From e20cea1b6107d325b7ca703cd7d98b28959e5a0f Mon Sep 17 00:00:00 2001 From: Martin Kluska Date: Thu, 12 Oct 2023 16:09:24 +0200 Subject: [PATCH] feat(Core): Add contract for sleep service with no sleep implementation in tests - When running in tests, SleepService is switched with NoSleepService - Use NoSleepService in your unit tests --- src/Core/Contracts/SleepServiceContract.php | 12 ++++++ src/Core/LaraStrictServiceProvider.php | 3 ++ src/Core/Services/SleepService.php | 4 +- .../RunAppServiceProviderPipesAction.php | 8 ++-- src/Testing/Core/Services/NoSleepService.php | 18 ++++++++ src/Testing/TestServiceProvider.php | 6 +++ .../Core/Services/SleepServiceTest.php | 43 +++++++++++++++++++ .../LaraStrictServiceProviderTest.php | 2 + .../Core/Services/NoSleepServiceTest.php | 22 ++++++++++ .../Testing/TestServiceProviderTest.php | 42 ++++++++++++++++-- 10 files changed, 151 insertions(+), 9 deletions(-) create mode 100644 src/Core/Contracts/SleepServiceContract.php create mode 100644 src/Testing/Core/Services/NoSleepService.php create mode 100644 tests/Feature/Core/Services/SleepServiceTest.php create mode 100644 tests/Feature/Testing/Core/Services/NoSleepServiceTest.php diff --git a/src/Core/Contracts/SleepServiceContract.php b/src/Core/Contracts/SleepServiceContract.php new file mode 100644 index 00000000..aa77cb9d --- /dev/null +++ b/src/Core/Contracts/SleepServiceContract.php @@ -0,0 +1,12 @@ +app->singleton(SleepServiceContract::class, SleepService::class); $this->app->singleton(ScheduleServiceContract::class, ScheduleServiceContract::class); $this->app->alias(ScheduleService::class, ScheduleServiceContract::class); diff --git a/src/Core/Services/SleepService.php b/src/Core/Services/SleepService.php index 2a1d48c8..5cef4e4a 100644 --- a/src/Core/Services/SleepService.php +++ b/src/Core/Services/SleepService.php @@ -4,7 +4,9 @@ namespace LaraStrict\Core\Services; -class SleepService +use LaraStrict\Core\Contracts\SleepServiceContract; + +final class SleepService implements SleepServiceContract { public function sleep(int $milliSeconds): void { diff --git a/src/Providers/Actions/RunAppServiceProviderPipesAction.php b/src/Providers/Actions/RunAppServiceProviderPipesAction.php index 962502e3..630e8b03 100644 --- a/src/Providers/Actions/RunAppServiceProviderPipesAction.php +++ b/src/Providers/Actions/RunAppServiceProviderPipesAction.php @@ -9,20 +9,20 @@ use LaraStrict\Contracts\RunAppServiceProviderPipesActionContract; use LaraStrict\Providers\Entities\AppServiceProviderEntity; -class RunAppServiceProviderPipesAction implements RunAppServiceProviderPipesActionContract +final class RunAppServiceProviderPipesAction implements RunAppServiceProviderPipesActionContract { public function __construct( private readonly Container $container ) { } - public function execute(AppServiceProviderEntity $app, array $pipes): void + public function execute(AppServiceProviderEntity $appServiceProvider, array $pipes): void { - /** @var Pipeline $pipeline */ $pipeline = $this->container->make(Pipeline::class); + assert($pipeline instanceof Pipeline); $pipeline - ->send($app) + ->send($appServiceProvider) ->through($pipes) ->then(static function () { }); diff --git a/src/Testing/Core/Services/NoSleepService.php b/src/Testing/Core/Services/NoSleepService.php new file mode 100644 index 00000000..8df2d108 --- /dev/null +++ b/src/Testing/Core/Services/NoSleepService.php @@ -0,0 +1,18 @@ +commands([MakeExpectationCommand::class]); + + if ($this->app->runningUnitTests()) { + $this->app->singleton(SleepServiceContract::class, NoSleepService::class); + } } } diff --git a/tests/Feature/Core/Services/SleepServiceTest.php b/tests/Feature/Core/Services/SleepServiceTest.php new file mode 100644 index 00000000..ab6c4c62 --- /dev/null +++ b/tests/Feature/Core/Services/SleepServiceTest.php @@ -0,0 +1,43 @@ +assertIsInRange( + static fn (SleepServiceContract $service) => $service->sleep(milliSeconds: self::MinMilliseconds) + ); + } + + public function testSleepRandom(): void + { + $this->assertIsInRange( + static fn (SleepServiceContract $service) => $service->sleepRandom( + fromMilliSeconds: self::MinMilliseconds, + toMilliSeconds: self::MinMilliseconds + 10 + ) + ); + } + + protected function assertIsInRange(Closure $run): void + { + $time = microtime(true); + + $service = new SleepService(); + $run($service); + + $diff = microtime(true) - $time; + $this->assertTrue($diff > 0.08); + } +} diff --git a/tests/Feature/Providers/LaraStrictServiceProviderTest.php b/tests/Feature/Providers/LaraStrictServiceProviderTest.php index 663f7475..3ac9e377 100644 --- a/tests/Feature/Providers/LaraStrictServiceProviderTest.php +++ b/tests/Feature/Providers/LaraStrictServiceProviderTest.php @@ -6,6 +6,7 @@ use LaraStrict\Console\Contracts\ScheduleServiceContract; use LaraStrict\Console\Services\ScheduleService; +use LaraStrict\Core\Contracts\SleepServiceContract; use LaraStrict\Core\LaraStrictServiceProvider; use LaraStrict\Core\Services\ImplementsService; use LaraStrict\Database\Actions\RunInTransactionAction; @@ -73,6 +74,7 @@ public function testSingletons(): void GetBasePathForStubsActionContract::class => GetBasePathForStubsAction::class, GetNamespaceForStubsActionContract::class => GetNamespaceForStubsAction::class, ImplementsService::class => ImplementsService::class, + SleepServiceContract::class => SleepServiceContract::class, ] ); } diff --git a/tests/Feature/Testing/Core/Services/NoSleepServiceTest.php b/tests/Feature/Testing/Core/Services/NoSleepServiceTest.php new file mode 100644 index 00000000..d5ed138b --- /dev/null +++ b/tests/Feature/Testing/Core/Services/NoSleepServiceTest.php @@ -0,0 +1,22 @@ +sleep(10000); + $noSleep->sleepRandom(10000, 20000); + + $this->assertTrue(microtime(true) - $time < 0.08); + } +} diff --git a/tests/Feature/Testing/TestServiceProviderTest.php b/tests/Feature/Testing/TestServiceProviderTest.php index 900e9c41..971b767a 100644 --- a/tests/Feature/Testing/TestServiceProviderTest.php +++ b/tests/Feature/Testing/TestServiceProviderTest.php @@ -6,8 +6,11 @@ use Illuminate\Contracts\Config\Repository; use Illuminate\Contracts\Console\Kernel; +use LaraStrict\Core\Contracts\SleepServiceContract; use LaraStrict\Core\LaraStrictServiceProvider; +use LaraStrict\Core\Services\SleepService; use LaraStrict\Enums\EnvironmentType; +use LaraStrict\Testing\Core\Services\NoSleepService; use Tests\LaraStrict\Feature\TestCase; class TestServiceProviderTest extends TestCase @@ -32,10 +35,7 @@ public function makeExpectationCommandData(): array */ public function testMakeExpectationCommand(string|EnvironmentType $environment, bool $has): void { - $config = $this->app() - ->get(Repository::class); - assert($config instanceof Repository); - $config->set('app.env', $environment); + $this->setEnv($environment); $this->app() ->register(LaraStrictServiceProvider::class); @@ -47,8 +47,42 @@ public function testMakeExpectationCommand(string|EnvironmentType $environment, $this->assertEquals($has, array_key_exists('make:expectation', $kernel->all())); } + public function testSleepServiceInTests(): void + { + $this->app() + ->register(LaraStrictServiceProvider::class); + + $this->assertInstanceOf( + expected: NoSleepService::class, + actual: $this->app() + ->make(SleepServiceContract::class) + ); + } + + public function testSleepServiceInProduction(): void + { + $this->setEnv(environment: EnvironmentType::Production); + + $this->app() + ->register(LaraStrictServiceProvider::class); + + $this->assertInstanceOf( + expected: SleepService::class, + actual: $this->app() + ->make(SleepServiceContract::class) + ); + } + protected function getPackageProviders($app) { return []; } + + protected function setEnv(string|EnvironmentType $environment): void + { + $config = $this->app() + ->get(Repository::class); + assert($config instanceof Repository); + $config->set('app.env', $environment); + } }