index/tests/DependenciesTest.php

135 lines
5.7 KiB
PHP

<?php
// DependenciesTest.php
// Created: 2025-01-21
// Updated: 2025-03-21
declare(strict_types=1);
namespace {
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\{CoversClass,UsesClass};
use Index\Dependencies;
#[CoversClass(Dependencies::class)]
final class DependenciesTest extends TestCase {
public function testDependencyCall(): void {
$deps = new Dependencies;
$deps->register(\Index\Db\DbResultIterator::class, construct: fn($result) => null);
$deps->register(\Index\Db\NullDb\NullDbResult::class);
$func = function(
\Index\Db\DbResult $result,
string $soup,
?\Index\Db\DbConnection $conn,
string $named = '',
?\Index\Db\NullDb\NullDbTransaction $transaction = null
) {
return $result instanceof \Index\Db\NullDb\NullDbResult
&& $soup === 'beans'
&& $conn === null
&& $named === 'bowl'
&& $transaction === null;
};
$this->assertTrue($deps->call($func, 'beans', named: 'bowl'));
$outOfOrder = function(
string $soup,
\Index\Db\DbResult $result,
string $named = '',
?\Index\Db\DbResultIterator $iterator = null
) {
return $result instanceof \Index\Db\NullDb\NullDbResult
&& $soup === 'beans'
&& $named === 'bowl'
&& $iterator instanceof \Index\Db\DbResultIterator;
};
$this->assertTrue($deps->call($outOfOrder, 'beans', named: 'bowl'));
}
public function testDependencyResolver(): void {
$deps = new Dependencies;
$deps->register(\Index\Db\DbResultIterator::class, construct: fn($result) => null);
$deps->register(\Index\Db\NullDb\NullDbResult::class);
$iterator = $deps->resolve(\Index\Db\DbResultIterator::class);
$this->assertInstanceOf(\Index\Db\DbResultIterator::class, $iterator);
$this->assertFalse($iterator->valid());
$result = $deps->resolve(\Index\Db\NullDb\NullDbResult::class);
$this->assertInstanceOf(\Index\Db\DbResult::class, $result);
}
public function testRequiredDependency(): void {
$this->expectException(TypeError::class);
$deps = new Dependencies;
$deps->register(DependenciesTest\RequiredParamTestClass::class);
$deps->resolve(DependenciesTest\RequiredParamTestClass::class);
$instance = $deps->resolve(DependenciesTest\RequiredParamTestClass::class);
$this->assertInstanceOf(DependenciesTest\RequiredParamTestClass::class, $instance);
// this is the one that actually triggers the exception because of lazy instantiation
$this->assertInstanceOf(DependenciesTest\RequiredParamTestClass::class, $instance->test);
}
public function testNullableDependency(): void {
$deps = new Dependencies;
$deps->register(DependenciesTest\NullableParamTestClass::class);
$instance = $deps->resolve(DependenciesTest\NullableParamTestClass::class);
$this->assertInstanceOf(DependenciesTest\NullableParamTestClass::class, $instance);
$this->assertNull($instance->test);
}
public function testFetchAllDependencies(): void {
$deps = new Dependencies;
$deps->register(\Index\Db\NullDb\NullDbResult::class);
$deps->register(DependenciesTest\NullableParamTestClass::class);
$deps->register(DependenciesTest\Routes1::class);
$deps->register(new DependenciesTest\Routes2);
$deps->register(DependenciesTest\RequiredParamTestClass::class);
$deps->register(DependenciesTest\Routes3::class);
$deps->register(\Index\Db\DbResultIterator::class, construct: fn($result) => null);
$routes3 = $deps->resolve(\Index\Http\Routing\RouteHandler::class, fn($object) => $object instanceof DependenciesTest\Routes3);
$this->assertInstanceOf(DependenciesTest\Routes3::class, $routes3);
$routes2 = $deps->resolve(DependenciesTest\Routes2::class);
$this->assertInstanceOf(DependenciesTest\Routes2::class, $routes2);
$all = $deps->all(\Index\Http\Routing\RouteHandler::class);
$this->assertEquals(3, count($all));
$this->assertInstanceOf(DependenciesTest\Routes1::class, $all[0]);
$this->assertInstanceOf(DependenciesTest\Routes2::class, $all[1]);
$this->assertInstanceOf(DependenciesTest\Routes3::class, $all[2]);
$some = $deps->all(\Index\Http\Routing\RouteHandler::class, fn($object) => !($object instanceof DependenciesTest\Routes2));
$this->assertEquals(2, count($some));
$this->assertInstanceOf(DependenciesTest\Routes1::class, $some[0]);
$this->assertInstanceOf(DependenciesTest\Routes3::class, $some[1]);
}
}
}
namespace DependenciesTest {
interface DependencyTestInterface {}
class RequiredParamTestClass {
public function __construct(public DependencyTestInterface $test) {}
}
class NullableParamTestClass {
public function __construct(public ?DependencyTestInterface $test) {}
}
class Routes1 implements \Index\Http\Routing\RouteHandler {
use \Index\Http\Routing\RouteHandlerCommon;
}
class Routes2 implements \Index\Http\Routing\RouteHandler {
use \Index\Http\Routing\RouteHandlerCommon;
}
class Routes3 implements \Index\Http\Routing\RouteHandler {
use \Index\Http\Routing\RouteHandlerCommon;
}
}