Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
162
tests/Unit/Framework/DI/ContainerTest.php
Normal file
162
tests/Unit/Framework/DI/ContainerTest.php
Normal file
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Unit\Framework\DI;
|
||||
|
||||
use App\Framework\DI\DefaultContainer;
|
||||
|
||||
class TestService
|
||||
{
|
||||
public function __construct(public string $message = 'Hello World')
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class DependentService
|
||||
{
|
||||
public function __construct(public TestService $service)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
interface TestInterface
|
||||
{
|
||||
public function getMessage(): string;
|
||||
}
|
||||
|
||||
class TestImplementation implements TestInterface
|
||||
{
|
||||
public function getMessage(): string
|
||||
{
|
||||
return 'Implementation';
|
||||
}
|
||||
}
|
||||
|
||||
test('container can create simple class without dependencies', function () {
|
||||
$container = new DefaultContainer();
|
||||
|
||||
$service = $container->get(TestService::class);
|
||||
|
||||
expect($service)->toBeInstanceOf(TestService::class);
|
||||
expect($service->message)->toBe('Hello World');
|
||||
});
|
||||
|
||||
test('container resolves dependencies automatically', function () {
|
||||
$container = new DefaultContainer();
|
||||
|
||||
$service = $container->get(DependentService::class);
|
||||
|
||||
expect($service)->toBeInstanceOf(DependentService::class);
|
||||
expect($service->service)->toBeInstanceOf(TestService::class);
|
||||
expect($service->service->message)->toBe('Hello World');
|
||||
});
|
||||
|
||||
test('container can bind interfaces to implementations', function () {
|
||||
$container = new DefaultContainer();
|
||||
|
||||
$container->bind(TestInterface::class, TestImplementation::class);
|
||||
|
||||
$service = $container->get(TestInterface::class);
|
||||
|
||||
expect($service)->toBeInstanceOf(TestImplementation::class);
|
||||
expect($service->getMessage())->toBe('Implementation');
|
||||
});
|
||||
|
||||
test('container can bind with closures', function () {
|
||||
$container = new DefaultContainer();
|
||||
|
||||
$container->bind(TestService::class, function () {
|
||||
return new TestService('Custom Message');
|
||||
});
|
||||
|
||||
$service = $container->get(TestService::class);
|
||||
|
||||
expect($service->message)->toBe('Custom Message');
|
||||
});
|
||||
|
||||
test('container can register singletons', function () {
|
||||
$container = new DefaultContainer();
|
||||
|
||||
$container->singleton(TestService::class, TestService::class);
|
||||
|
||||
$service1 = $container->get(TestService::class);
|
||||
$service2 = $container->get(TestService::class);
|
||||
|
||||
expect($service1)->toBe($service2); // Same instance
|
||||
});
|
||||
|
||||
test('container can store instances directly', function () {
|
||||
$container = new DefaultContainer();
|
||||
|
||||
$instance = new TestService('Direct Instance');
|
||||
$container->instance(TestService::class, $instance);
|
||||
|
||||
$retrieved = $container->get(TestService::class);
|
||||
|
||||
expect($retrieved)->toBe($instance);
|
||||
expect($retrieved->message)->toBe('Direct Instance');
|
||||
});
|
||||
|
||||
test('container has method works correctly', function () {
|
||||
$container = new DefaultContainer();
|
||||
|
||||
expect($container->has(TestService::class))->toBeTrue(); // Can be auto-wired
|
||||
expect($container->has('NonExistentClass'))->toBeFalse();
|
||||
|
||||
$container->bind('bound-service', TestService::class);
|
||||
expect($container->has('bound-service'))->toBeTrue();
|
||||
});
|
||||
|
||||
test('container forget removes bindings', function () {
|
||||
$container = new DefaultContainer();
|
||||
|
||||
$container->bind('test-binding', TestService::class);
|
||||
expect($container->has('test-binding'))->toBeTrue();
|
||||
|
||||
$container->forget('test-binding');
|
||||
expect($container->has('test-binding'))->toBeFalse();
|
||||
});
|
||||
|
||||
test('container can get service ids', function () {
|
||||
$container = new DefaultContainer();
|
||||
|
||||
$container->bind('service-1', TestService::class);
|
||||
$container->instance('service-2', new TestService());
|
||||
|
||||
$serviceIds = $container->getServiceIds();
|
||||
|
||||
expect($serviceIds)->toContain('service-1');
|
||||
expect($serviceIds)->toContain('service-2');
|
||||
expect($serviceIds)->toContain(DefaultContainer::class); // Self-registered
|
||||
});
|
||||
|
||||
test('container can flush all bindings', function () {
|
||||
$container = new DefaultContainer();
|
||||
|
||||
$container->bind('test-1', TestService::class);
|
||||
$container->instance('test-2', new TestService());
|
||||
|
||||
$container->flush();
|
||||
|
||||
// Should still contain self-registration
|
||||
$serviceIds = $container->getServiceIds();
|
||||
expect($serviceIds)->toContain(DefaultContainer::class);
|
||||
expect($serviceIds)->not->toContain('test-1');
|
||||
expect($serviceIds)->not->toContain('test-2');
|
||||
});
|
||||
|
||||
test('container method invoker works', function () {
|
||||
$container = new DefaultContainer();
|
||||
|
||||
$service = new class () {
|
||||
public function method(TestService $service): string
|
||||
{
|
||||
return $service->message;
|
||||
}
|
||||
};
|
||||
|
||||
$result = $container->invoker->call($service, 'method');
|
||||
|
||||
expect($result)->toBe('Hello World');
|
||||
});
|
||||
Reference in New Issue
Block a user