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'); });