Skip to content

Commit

Permalink
Changes behavior for loading system bootloaders. Now system bootloade…
Browse files Browse the repository at this point in the history
…rs init only after Environment is bound to the container
  • Loading branch information
butschster committed Aug 10, 2023
1 parent e2b43f3 commit 0682428
Show file tree
Hide file tree
Showing 14 changed files with 137 additions and 43 deletions.
7 changes: 3 additions & 4 deletions src/Boot/src/AbstractKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ protected function __construct(

$this->finalizer = new Finalizer();
$container->bindSingleton(FinalizerInterface::class, $this->finalizer);

$this->bootloader->bootload($this->defineSystemBootloaders());
}

/**
Expand Down Expand Up @@ -162,13 +160,14 @@ public function run(?EnvironmentInterface $environment = null): ?self
$environment ??= new Environment();
$this->container->bindSingleton(EnvironmentInterface::class, $environment);

$this->fireCallbacks($this->runningCallbacks);

try {
// will protect any against env overwrite action
$this->container->runScope(
[EnvironmentInterface::class => $environment],
function (): void {
$this->bootloader->bootload($this->defineSystemBootloaders());
$this->fireCallbacks($this->runningCallbacks);

$this->bootload();
$this->bootstrap();

Expand Down
9 changes: 6 additions & 3 deletions src/Framework/Bootloader/Attributes/AttributesBootloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Spiral\Attributes\Psr16CachedReader;
use Spiral\Attributes\ReaderInterface;
use Spiral\Boot\Bootloader\Bootloader;
use Spiral\Boot\EnvironmentInterface;
use Spiral\Config\ConfiguratorInterface;

class AttributesBootloader extends Bootloader
Expand All @@ -32,13 +33,13 @@ public function __construct(
) {
}

public function init(): void
public function init(EnvironmentInterface $env): void
{
$this->config->setDefaults(
AttributesConfig::CONFIG,
[
'annotations' => [
'support' => true,
'support' => $env->get('SUPPORT_ANNOTATIONS', true),
],
],
);
Expand Down Expand Up @@ -68,7 +69,9 @@ private function initReader(
$reader = new Psr16CachedReader($reader, $cache);
}

if ($config->isAnnotationsReaderEnabled()) {
$supportAnnotations = $config->isAnnotationsReaderEnabled();

if ($supportAnnotations) {
if (!\interface_exists(DoctrineReaderInterface::class)) {
throw new InitializationException(
'Doctrine annotations reader is not available, please install "doctrine/annotations" package',
Expand Down
15 changes: 10 additions & 5 deletions src/Tokenizer/src/Bootloader/TokenizerBootloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Spiral\Boot\Bootloader\Bootloader;
use Spiral\Boot\DirectoriesInterface;
use Spiral\Boot\EnvironmentInterface;
use Spiral\Config\ConfiguratorInterface;
use Spiral\Config\Patch\Append;
use Spiral\Core\BinderInterface;
Expand Down Expand Up @@ -47,7 +48,7 @@ public function __construct(
) {
}

public function init(BinderInterface $binder, DirectoriesInterface $dirs): void
public function init(BinderInterface $binder, DirectoriesInterface $dirs, EnvironmentInterface $env): void
{
$binder->bindInjector(ClassLocator::class, ClassLocatorInjector::class);
$binder->bindInjector(EnumLocator::class, EnumLocatorInjector::class);
Expand All @@ -65,7 +66,11 @@ public function init(BinderInterface $binder, DirectoriesInterface $dirs): void
'tests',
'migrations',
],
]
'cache' => [
'directory' => $dirs->get('runtime') . 'cache/listeners',
'enabled' => \filter_var($env->get('TOKENIZER_CACHE_TARGETS', false), \FILTER_VALIDATE_BOOL),
],
],
);
}

Expand All @@ -76,7 +81,7 @@ public function addDirectory(string $directory): void
{
$this->config->modify(
TokenizerConfig::CONFIG,
new Append('directories', null, $directory)
new Append('directories', null, $directory),
);
}

Expand All @@ -88,13 +93,13 @@ public function addScopedDirectory(string $scope, string $directory): void
if (!isset($this->config->getConfig(TokenizerConfig::CONFIG)['scopes'][$scope])) {
$this->config->modify(
TokenizerConfig::CONFIG,
new Append('scopes', $scope, [])
new Append('scopes', $scope, []),
);
}

$this->config->modify(
TokenizerConfig::CONFIG,
new Append('scopes.' . $scope, null, $directory)
new Append('scopes.' . $scope, null, $directory),
);
}
}
7 changes: 2 additions & 5 deletions src/Tokenizer/src/Bootloader/TokenizerListenerBootloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,9 @@ private function makeCachedLoader(
// but not read from there.
return $factory->make($classLoader, [
'memory' => $factory->make(Memory::class, [
'directory' => $config->getCacheDirectory() ?? $dirs->get('runtime') . 'cache/listeners',
'directory' => $config->getCacheDirectory(),
]),
'readCache' => \filter_var(
$env->get('TOKENIZER_CACHE_TARGETS', $config->isCacheEnabled()),
\FILTER_VALIDATE_BOOL
),
'readCache' => $config->isCacheEnabled(),
]);
}

Expand Down
11 changes: 8 additions & 3 deletions src/Tokenizer/src/Config/TokenizerConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ public function getScope(string $scope): array
];
}

public function getScopes(): array
{
return $this->config['scopes'] ?? [];
}

/**
* Check if tokenizer listeners cache is enabled.
*/
Expand All @@ -102,16 +107,16 @@ public function getCacheDirectory(): ?string

public function isLoadClassesEnabled(): bool
{
return (bool) ($this->config['load']['classes'] ?? true);
return (bool)($this->config['load']['classes'] ?? true);
}

public function isLoadEnumsEnabled(): bool
{
return (bool) ($this->config['load']['enums'] ?? false);
return (bool)($this->config['load']['enums'] ?? false);
}

public function isLoadInterfacesEnabled(): bool
{
return (bool) ($this->config['load']['interfaces'] ?? false);
return (bool)($this->config['load']['interfaces'] ?? false);
}
}
19 changes: 18 additions & 1 deletion tests/Framework/BaseTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@

use Spiral\App\TestApp;
use Spiral\Core\Container;
use Spiral\Testing\Traits\InteractsWithCore;

abstract class BaseTestCase extends \Spiral\Testing\TestCase
{
use InteractsWithCore;

private array $disabledBootloaders = [];

public function rootDirectory(): string
{
return \realpath(__DIR__.'/../');
Expand All @@ -19,7 +24,19 @@ public function createAppInstance(Container $container = new Container()): TestA
return TestApp::create(
$this->defineDirectories($this->rootDirectory()),
false
);
)->disableBootloader(...$this->disabledBootloaders);
}

public function withDisabledBootloaders(string ... $bootloader): self
{
$this->disabledBootloaders = $bootloader;

return $this;
}

public function getTestEnvVariables(): array
{
return [...static::ENV, ...$this->getEnvVariablesFromConfig()];
}

protected function tearDown(): void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,39 @@
namespace Framework\Bootloader\Attributes;

use Spiral\Attributes\AttributeReader;
use Spiral\Attributes\Composite\SelectiveReader;
use Spiral\Attributes\Psr16CachedReader;
use Spiral\Attributes\ReaderInterface;
use Spiral\Bootloader\Attributes\AttributesConfig;
use Spiral\Bootloader\Attributes\Factory;
use Spiral\Config\ConfiguratorInterface;
use Spiral\Testing\Attribute\Env;
use Spiral\Tests\Framework\BaseTestCase;

final class AttributesWithoutAnnotationsBootloaderTest extends BaseTestCase
{
protected function setUp(): void
public const MAKE_APP_ON_STARTUP = false;

#[Env('SUPPORT_ANNOTATIONS', 'false')]
public function testReaderBindingWithoutCache(): void
{
$this->beforeInit(function (ConfiguratorInterface $configurator) {
$configurator->setDefaults(AttributesConfig::CONFIG, [
'annotations' => [
'support' => false,
],
]);
});

parent::setUp();
$this
->withDisabledBootloaders(\Spiral\Cache\Bootloader\CacheBootloader::class)
->initApp($this->getTestEnvVariables());

$this->assertContainerBoundAsSingleton(ReaderInterface::class, AttributeReader::class);
}

public function testReaderBinding(): void
#[Env('SUPPORT_ANNOTATIONS', 'false')]
public function testReaderBindingWithtCache(): void
{
$this->initApp($this->getTestEnvVariables());

$this->assertContainerBoundAsSingleton(ReaderInterface::class, AttributeReader::class);
$this->assertContainerBoundAsSingleton(ReaderInterface::class, Psr16CachedReader::class);
}

#[Env('SUPPORT_ANNOTATIONS', 'true')]
public function testSelectiveReaderBinding(): void
{
$this->initApp($this->getTestEnvVariables());

$this->assertContainerBoundAsSingleton(ReaderInterface::class, SelectiveReader::class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ public function testConfig(): void
'tests',
'migrations',
],
'cache' => [
'directory' => $this->getDirectoryByAlias('runtime') .'cache/listeners',
'enabled' => true
]
]
);
}
Expand Down
10 changes: 6 additions & 4 deletions tests/Framework/Dispatcher/ConsoleDispatcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ public function testException(): void
);
$result = $output->fetch();

$this->assertStringContainsString('undefined', $result);
$this->assertStringContainsString('This command is dead', $result);
$this->assertStringContainsString('DeadCommand.php', $result);
$this->assertStringNotContainsString('throw new \InvalidArgumentException(\'This command is dead\');', $result);
$this->assertNotEquals(0, $serveResult);
}

Expand All @@ -70,8 +71,9 @@ public function testExceptionVerbose(): void
);
$result = $output->fetch();

$this->assertStringContainsString('undefined', $result);
$this->assertStringContainsString('This command is dead', $result);
$this->assertStringContainsString('DeadCommand.php', $result);
$this->assertStringNotContainsString('throw new \InvalidArgumentException(\'This command is dead\');', $result);
$this->assertNotEquals(0, $serveResult);
}

Expand All @@ -90,9 +92,9 @@ public function testExceptionDebug(): void
);
$result = $output->fetch();

$this->assertStringContainsString('undefined', $result);
$this->assertStringContainsString('This command is dead', $result);
$this->assertStringContainsString('DeadCommand.php', $result);
$this->assertStringContainsString('$undefined', $result);
$this->assertStringContainsString('throw new \InvalidArgumentException(\'This command is dead\');', $result);
$this->assertNotEquals(0, $serveResult);
}
}
3 changes: 2 additions & 1 deletion tests/Framework/Http/ControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public function testPayloadActionBad(): void

public function test500(): void
{
$this->getHttp()->get('/error')->assertStatus(500);
$this->getHttp()->get('/error')
->assertStatus(500);
}
}
28 changes: 28 additions & 0 deletions tests/Framework/Tokenizer/Config/ConfigTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Framework\Tokenizer\Config;

use Spiral\Testing\Attribute\Env;
use Spiral\Tests\Framework\BaseTestCase;
use Spiral\Tokenizer\Config\TokenizerConfig;

final class ConfigTest extends BaseTestCase
{
#[Env('TOKENIZER_CACHE_TARGETS', 'false')]
public function testCacheFromEnvDisabled(): void
{
$config = $this->getContainer()->get(TokenizerConfig::class);

$this->assertFalse($config->isCacheEnabled());
}

#[Env('TOKENIZER_CACHE_TARGETS', 'true')]
public function testCacheFromEnvEnabled(): void
{
$config = $this->getContainer()->get(TokenizerConfig::class);

$this->assertTrue($config->isCacheEnabled());
}
}
4 changes: 3 additions & 1 deletion tests/app/src/Command/DeadCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@

namespace Spiral\App\Command;

use Spiral\Console\Attribute\AsCommand;
use Spiral\Console\Command;

#[AsCommand(name: 'dead')]
class DeadCommand extends Command
{
public const NAME = 'dead';

public function perform(): void
{
echo $undefined;
throw new \InvalidArgumentException('This command is dead');
}
}
2 changes: 1 addition & 1 deletion tests/app/src/Controller/TestController.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function input(InputScope $i)

public function error(): void
{
echo $undefined;
throw new \InvalidArgumentException('Invalid argument');
}

public function route(RouteInterface $route)
Expand Down
Loading

0 comments on commit 0682428

Please sign in to comment.