Skip to content

Commit

Permalink
feat(Core): Add contract for sleep service with no sleep implementati…
Browse files Browse the repository at this point in the history
…on in tests

- When running in tests, SleepService is switched with NoSleepService
- Use NoSleepService in your unit tests
  • Loading branch information
pionl committed Oct 12, 2023
1 parent 61f6781 commit e20cea1
Show file tree
Hide file tree
Showing 10 changed files with 151 additions and 9 deletions.
12 changes: 12 additions & 0 deletions src/Core/Contracts/SleepServiceContract.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace LaraStrict\Core\Contracts;

interface SleepServiceContract
{
public function sleep(int $milliSeconds): void;

public function sleepRandom(int $fromMilliSeconds, int $toMilliSeconds): void;
}
3 changes: 3 additions & 0 deletions src/Core/LaraStrictServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
use LaraStrict\Context\ContextServiceProvider;
use LaraStrict\Contracts\RunAppServiceProviderPipesActionContract;
use LaraStrict\Core\Actions\CreateCoreAppServiceProviderAction;
use LaraStrict\Core\Contracts\SleepServiceContract;
use LaraStrict\Core\Services\ImplementsService;
use LaraStrict\Core\Services\SleepService;
use LaraStrict\Database\DatabaseServiceProvider;
use LaraStrict\Docker\DockerServiceProvider;
use LaraStrict\Log\LogServiceProvider;
Expand All @@ -26,6 +28,7 @@ class LaraStrictServiceProvider extends AbstractBaseServiceProvider
public function register(): void
{
// Add ability to "switch" the implementation - it is important to run it now.
$this->app->singleton(SleepServiceContract::class, SleepService::class);
$this->app->singleton(ScheduleServiceContract::class, ScheduleServiceContract::class);
$this->app->alias(ScheduleService::class, ScheduleServiceContract::class);

Expand Down
4 changes: 3 additions & 1 deletion src/Core/Services/SleepService.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
8 changes: 4 additions & 4 deletions src/Providers/Actions/RunAppServiceProviderPipesAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 () {
});
Expand Down
18 changes: 18 additions & 0 deletions src/Testing/Core/Services/NoSleepService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace LaraStrict\Testing\Core\Services;

use LaraStrict\Core\Contracts\SleepServiceContract;

final class NoSleepService implements SleepServiceContract
{
public function sleep(int $milliSeconds): void
{
}

public function sleepRandom(int $fromMilliSeconds, int $toMilliSeconds): void
{
}
}
6 changes: 6 additions & 0 deletions src/Testing/TestServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@

use Illuminate\Support\ServiceProvider;
use LaraStrict\Config\Contracts\AppConfigContract;
use LaraStrict\Core\Contracts\SleepServiceContract;
use LaraStrict\Enums\EnvironmentType;
use LaraStrict\Testing\Actions\GetBasePathForStubsAction;
use LaraStrict\Testing\Actions\GetNamespaceForStubsAction;
use LaraStrict\Testing\Commands\MakeExpectationCommand;
use LaraStrict\Testing\Contracts\GetBasePathForStubsActionContract;
use LaraStrict\Testing\Contracts\GetNamespaceForStubsActionContract;
use LaraStrict\Testing\Core\Services\NoSleepService;

class TestServiceProvider extends ServiceProvider
{
Expand All @@ -37,5 +39,9 @@ public function register(): void
}

$this->commands([MakeExpectationCommand::class]);

if ($this->app->runningUnitTests()) {
$this->app->singleton(SleepServiceContract::class, NoSleepService::class);
}
}
}
43 changes: 43 additions & 0 deletions tests/Feature/Core/Services/SleepServiceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace Tests\LaraStrict\Feature\Core\Services;

use Closure;
use LaraStrict\Core\Contracts\SleepServiceContract;
use LaraStrict\Core\Services\SleepService;
use PHPUnit\Framework\TestCase;

final class SleepServiceTest extends TestCase
{
private const MinMilliseconds = 100;

public function testSleep(): void
{
$this->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);
}
}
2 changes: 2 additions & 0 deletions tests/Feature/Providers/LaraStrictServiceProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -73,6 +74,7 @@ public function testSingletons(): void
GetBasePathForStubsActionContract::class => GetBasePathForStubsAction::class,
GetNamespaceForStubsActionContract::class => GetNamespaceForStubsAction::class,
ImplementsService::class => ImplementsService::class,
SleepServiceContract::class => SleepServiceContract::class,
]
);
}
Expand Down
22 changes: 22 additions & 0 deletions tests/Feature/Testing/Core/Services/NoSleepServiceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Tests\LaraStrict\Feature\Testing\Core\Services;

use LaraStrict\Testing\Core\Services\NoSleepService;
use PHPUnit\Framework\TestCase;

class NoSleepServiceTest extends TestCase
{
public function testSleepDoesNothing(): void
{
$time = microtime(true);
$noSleep = new NoSleepService();

$noSleep->sleep(10000);
$noSleep->sleepRandom(10000, 20000);

$this->assertTrue(microtime(true) - $time < 0.08);
}
}
42 changes: 38 additions & 4 deletions tests/Feature/Testing/TestServiceProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand All @@ -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);
}
}

0 comments on commit e20cea1

Please sign in to comment.