Skip to content

Commit

Permalink
Merge pull request #39 from gacela-project/feature/adding-unit-tests
Browse files Browse the repository at this point in the history
Adding unit tests to Container and Locator
  • Loading branch information
Chemaclass authored Jul 9, 2021
2 parents 61560d0 + 11d970d commit 6d98afe
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 4 deletions.
13 changes: 9 additions & 4 deletions src/Framework/Container/Locator.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ final class Locator
private static ?Locator $instance = null;

/** @var array<string, mixed> */
private static array $instanceCache = [];
private array $instanceCache = [];

public static function getInstance(): self
{
Expand All @@ -22,6 +22,11 @@ public static function getInstance(): self
return self::$instance;
}

public static function resetInstance(): void
{
self::$instance = null;
}

private function __construct()
{
}
Expand All @@ -40,14 +45,14 @@ public function get(string $className)
{
$concreteClass = $this->getConcreteClass($className);

if (isset(self::$instanceCache[$concreteClass])) {
return self::$instanceCache[$concreteClass];
if (isset($this->instanceCache[$concreteClass])) {
return $this->instanceCache[$concreteClass];
}

/** @var mixed $newInstance */
$newInstance = $this->newInstance($concreteClass);
/** @psalm-suppress MixedAssignment */
self::$instanceCache[$concreteClass] = $newInstance;
$this->instanceCache[$concreteClass] = $newInstance;

return $newInstance;
}
Expand Down
20 changes: 20 additions & 0 deletions tests/Fixtures/StringValue.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace GacelaTest\Fixtures;

final class StringValue implements StringValueInterface
{
private string $value = '';

public function setValue(string $value): void
{
$this->value = $value;
}

public function value(): string
{
return $this->value;
}
}
10 changes: 10 additions & 0 deletions tests/Fixtures/StringValueInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace GacelaTest\Fixtures;

interface StringValueInterface
{
public function value(): string;
}
80 changes: 80 additions & 0 deletions tests/Unit/Framework/Container/ContainerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types=1);

namespace GacelaTest\Unit\Framework\Container;

use Gacela\Framework\Container\Container;
use Gacela\Framework\Container\Exception\ContainerKeyNotFoundException;
use PHPUnit\Framework\TestCase;

final class ContainerTest extends TestCase
{
private Container $container;

protected function setUp(): void
{
$this->container = new Container();
}

public function test_get_non_existing_service(): void
{
$this->expectException(ContainerKeyNotFoundException::class);
$this->container->get('unknown-service_name');
}

public function test_has_service(): void
{
$this->container->set('service_name', 'value');

self::assertTrue($this->container->has('service_name'));
self::assertFalse($this->container->has('unknown-service_name'));
}

public function test_remove_existing_service(): void
{
$this->container->set('service_name', 'value');
$this->container->remove('service_name');

$this->expectException(ContainerKeyNotFoundException::class);
$this->container->get('service_name');
}

public function test_resolve_service_as_raw_string(): void
{
$this->container->set('service_name', 'value');

$resolvedService = $this->container->get('service_name');
self::assertSame('value', $resolvedService);

$cachedResolvedService = $this->container->get('service_name');
self::assertSame('value', $cachedResolvedService);
}

public function test_resolve_service_as_function(): void
{
$this->container->set('service_name', static fn (): string => 'value');

$resolvedService = $this->container->get('service_name');
self::assertSame('value', $resolvedService);

$cachedResolvedService = $this->container->get('service_name');
self::assertSame('value', $cachedResolvedService);
}

public function test_resolve_service_as_callable_class(): void
{
$this->container->set('service_name', new class() {
public function __invoke(): string
{
return 'value';
}
});

$resolvedService = $this->container->get('service_name');
self::assertSame('value', $resolvedService);

$cachedResolvedService = $this->container->get('service_name');
self::assertSame('value', $cachedResolvedService);
}
}
59 changes: 59 additions & 0 deletions tests/Unit/Framework/Container/LocatorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

namespace GacelaTest\Unit\Framework\Container;

use Gacela\Framework\Container\Locator;
use GacelaTest\Fixtures\StringValue;
use GacelaTest\Fixtures\StringValueInterface;
use PHPUnit\Framework\TestCase;

final class LocatorTest extends TestCase
{
private Locator $locator;

public function setUp(): void
{
Locator::resetInstance();
$this->locator = Locator::getInstance();
}

public function tearDown(): void
{
Locator::resetInstance();
}

public function test_get_singleton_from_concrete_class(): void
{
/** @var StringValue $stringValue */
$stringValue = $this->locator->get(StringValue::class);
self::assertInstanceOf(StringValue::class, $stringValue);
self::assertSame('', $stringValue->value());
$stringValue->setValue('updated value');

/** @var StringValue $stringValue2 */
$stringValue2 = $this->locator->get(StringValue::class);
self::assertSame('updated value', $stringValue2->value());
}

public function test_get_singleton_from_interface(): void
{
/** @var StringValue $stringValue */
$stringValue = $this->locator->get(StringValueInterface::class);
self::assertInstanceOf(StringValue::class, $stringValue);
self::assertSame('', $stringValue->value());
$stringValue->setValue('updated value');

/** @var StringValue $stringValue2 */
$stringValue2 = $this->locator->get(StringValueInterface::class);
self::assertSame('updated value', $stringValue2->value());
}

public function test_get_singleton_from_string(): void
{
/** @var string $stringValue */
$stringValue = $this->locator->get('NonExistingClass');
self::assertSame('NonExistingClass', $stringValue);
}
}

0 comments on commit 6d98afe

Please sign in to comment.