Skip to content

Commit

Permalink
Merge pull request #1772 from hydephp/refactor-console-kernel-bootstr…
Browse files Browse the repository at this point in the history
…apper-loading

Refactor console kernel bootstrapper loading
  • Loading branch information
caendesilva authored Jul 1, 2024
2 parents f8f60cd + d9080cc commit 034b151
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 30 deletions.
27 changes: 12 additions & 15 deletions packages/framework/src/Foundation/ConsoleKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,6 @@
namespace Hyde\Foundation;

use LaravelZero\Framework\Kernel;
use Hyde\Foundation\Internal\LoadYamlConfiguration;

use function array_combine;
use function array_splice;
use function array_values;
use function tap;

class ConsoleKernel extends Kernel
{
Expand All @@ -19,17 +13,20 @@ class ConsoleKernel extends Kernel
*/
protected function bootstrappers(): array
{
$bootstrappers = $this->bootstrappers;

// Insert our bootstrapper between load configuration and register provider bootstrappers.
array_splice($bootstrappers, 5, 0, LoadYamlConfiguration::class);

// Since we store our application config in `app/config.php`, we need to replace
// the default LoadConfiguration bootstrapper class with our implementation.
// We do this by swapping out the LoadConfiguration class with our own.

return array_values((array) tap(array_combine($bootstrappers, $bootstrappers), function (array &$array): void {
$array[\LaravelZero\Framework\Bootstrap\LoadConfiguration::class] = \Hyde\Foundation\Internal\LoadConfiguration::class;
}));
// We also inject our Yaml configuration loading bootstrapper.

return [
\LaravelZero\Framework\Bootstrap\CoreBindings::class,
\LaravelZero\Framework\Bootstrap\LoadEnvironmentVariables::class,
\Hyde\Foundation\Internal\LoadConfiguration::class,
\Illuminate\Foundation\Bootstrap\HandleExceptions::class,
\LaravelZero\Framework\Bootstrap\RegisterFacades::class,
\Hyde\Foundation\Internal\LoadYamlConfiguration::class,
\LaravelZero\Framework\Bootstrap\RegisterProviders::class,
\Illuminate\Foundation\Bootstrap\BootProviders::class,
];
}
}
49 changes: 34 additions & 15 deletions packages/framework/tests/Feature/ConsoleKernelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@

namespace Hyde\Framework\Testing\Feature;

use LaravelZero\Framework\Kernel as LaravelZeroKernel;
use Hyde\Foundation\Internal\LoadYamlConfiguration;
use Illuminate\Contracts\Console\Kernel;
use Hyde\Foundation\ConsoleKernel;
use Hyde\Testing\TestCase;
use ReflectionMethod;

/**
* This test covers our custom console kernel, which is responsible for registering our custom bootstrappers.
*
* @covers \Hyde\Foundation\ConsoleKernel
*
* Our custom bootstrapping system depends on code from Laravel Zero which is marked as internal.
* Sadly, there is no way around working with this private API. Since they may change the API
* at any time, we have tests here to detect if their code changes, so we can catch it early.
*/
class ConsoleKernelTest extends TestCase
{
Expand All @@ -25,28 +32,40 @@ public function testClassImplementsKernelInterface()
$this->assertInstanceOf(Kernel::class, app(ConsoleKernel::class));
}

public function testBootstrappers()
public function testLaravelZeroBootstrappersHaveNotChanged()
{
$kernel = app(ConsoleKernel::class);
$this->assertSame([
\LaravelZero\Framework\Bootstrap\CoreBindings::class,
\LaravelZero\Framework\Bootstrap\LoadEnvironmentVariables::class,
\LaravelZero\Framework\Bootstrap\LoadConfiguration::class,
\Illuminate\Foundation\Bootstrap\HandleExceptions::class,
\LaravelZero\Framework\Bootstrap\RegisterFacades::class,
\LaravelZero\Framework\Bootstrap\RegisterProviders::class,
\Illuminate\Foundation\Bootstrap\BootProviders::class,
], $this->getBootstrappersFromKernel(app(LaravelZeroKernel::class)));
}

// Normally, protected code does not need to be unit tested, but since this array is so vital, we want to inspect it.
$bootstrappers = (new ReflectionMethod($kernel, 'bootstrappers'))->invoke($kernel);
public function testHydeBootstrapperInjections()
{
$bootstrappers = $this->getBootstrappersFromKernel(app(ConsoleKernel::class));

$this->assertIsArray($bootstrappers);
$this->assertContains(LoadYamlConfiguration::class, $bootstrappers);

// Another assertion that is usually a no-no, testing vendor code, especially those which are marked as internal.
// We do this here however, so we get a heads-up if the vendor code changes as that could break our code.

$this->assertSame([
0 => 'LaravelZero\Framework\Bootstrap\CoreBindings',
1 => 'LaravelZero\Framework\Bootstrap\LoadEnvironmentVariables',
2 => 'Hyde\Foundation\Internal\LoadConfiguration',
3 => 'Illuminate\Foundation\Bootstrap\HandleExceptions',
4 => 'LaravelZero\Framework\Bootstrap\RegisterFacades',
5 => 'Hyde\Foundation\Internal\LoadYamlConfiguration',
6 => 'LaravelZero\Framework\Bootstrap\RegisterProviders',
7 => 'Illuminate\Foundation\Bootstrap\BootProviders',
\LaravelZero\Framework\Bootstrap\CoreBindings::class,
\LaravelZero\Framework\Bootstrap\LoadEnvironmentVariables::class,
\Hyde\Foundation\Internal\LoadConfiguration::class,
\Illuminate\Foundation\Bootstrap\HandleExceptions::class,
\LaravelZero\Framework\Bootstrap\RegisterFacades::class,
\Hyde\Foundation\Internal\LoadYamlConfiguration::class,
\LaravelZero\Framework\Bootstrap\RegisterProviders::class,
\Illuminate\Foundation\Bootstrap\BootProviders::class,
], $bootstrappers);
}

protected function getBootstrappersFromKernel(\Illuminate\Foundation\Console\Kernel $kernel): array
{
return (new ReflectionMethod($kernel, 'bootstrappers'))->invoke($kernel);
}
}

0 comments on commit 034b151

Please sign in to comment.