123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- <?php
- namespace think\tests;
- use Exception;
- use PHPUnit\Framework\TestCase;
- use ReflectionMethod;
- use stdClass;
- use think\Container;
- use think\exception\ClassNotFoundException;
- class Taylor
- {
- public $name;
- public function __construct($name)
- {
- $this->name = $name;
- }
- public function some(Container $container)
- {
- }
- public static function test(Container $container)
- {
- return $container;
- }
- public static function __make()
- {
- return new self('Taylor');
- }
- }
- class SomeClass
- {
- public $container;
- public function __construct(Container $container)
- {
- $this->container = $container;
- }
- }
- class ContainerTest extends TestCase
- {
- protected function tearDown(): void
- {
- Container::setInstance(null);
- }
- public function testClosureResolution()
- {
- $container = new Container;
- Container::setInstance($container);
- $container->bind('name', function () {
- return 'Taylor';
- });
- $this->assertEquals('Taylor', $container->make('name'));
- $this->assertEquals('Taylor', Container::pull('name'));
- }
- public function testGet()
- {
- $container = new Container;
- $this->expectException(ClassNotFoundException::class);
- $this->expectExceptionMessage('class not exists: name');
- $container->get('name');
- $container->bind('name', function () {
- return 'Taylor';
- });
- $this->assertSame('Taylor', $container->get('name'));
- }
- public function testExist()
- {
- $container = new Container;
- $container->bind('name', function () {
- return 'Taylor';
- });
- $this->assertFalse($container->exists("name"));
- $container->make('name');
- $this->assertTrue($container->exists('name'));
- }
- public function testInstance()
- {
- $container = new Container;
- $container->bind('name', function () {
- return 'Taylor';
- });
- $this->assertEquals('Taylor', $container->get('name'));
- $container->bind('name2', Taylor::class);
- $object = new stdClass();
- $this->assertFalse($container->exists('name2'));
- $container->instance('name2', $object);
- $this->assertTrue($container->exists('name2'));
- $this->assertTrue($container->exists(Taylor::class));
- $this->assertEquals($object, $container->make(Taylor::class));
- unset($container->name1);
- $this->assertFalse($container->exists('name1'));
- $container->delete('name2');
- $this->assertFalse($container->exists('name2'));
- foreach ($container as $class => $instance) {
- }
- }
- public function testBind()
- {
- $container = new Container;
- $object = new stdClass();
- $container->bind(['name' => Taylor::class]);
- $container->bind('name2', $object);
- $container->bind('name3', Taylor::class);
- $container->name4 = $object;
- $container['name5'] = $object;
- $this->assertTrue(isset($container->name4));
- $this->assertTrue(isset($container['name5']));
- $this->assertInstanceOf(Taylor::class, $container->get('name'));
- $this->assertSame($object, $container->get('name2'));
- $this->assertSame($object, $container->name4);
- $this->assertSame($object, $container['name5']);
- $this->assertInstanceOf(Taylor::class, $container->get('name3'));
- unset($container['name']);
- $this->assertFalse(isset($container['name']));
- unset($container->name3);
- $this->assertFalse(isset($container->name3));
- }
- public function testAutoConcreteResolution()
- {
- $container = new Container;
- $taylor = $container->make(Taylor::class);
- $this->assertInstanceOf(Taylor::class, $taylor);
- $this->assertAttributeSame('Taylor', 'name', $taylor);
- }
- public function testGetAndSetInstance()
- {
- $this->assertInstanceOf(Container::class, Container::getInstance());
- $object = new stdClass();
- Container::setInstance($object);
- $this->assertSame($object, Container::getInstance());
- Container::setInstance(function () {
- return $this;
- });
- $this->assertSame($this, Container::getInstance());
- }
- public function testInvokeFunctionWithoutMethodThrowsException()
- {
- $this->expectException(Exception::class);
- $this->expectExceptionMessage('function not exists: ContainerTestCallStub()');
- $container = new Container;
- $container->invokeFunction('ContainerTestCallStub', []);
- }
- public function testInvokeClosureFunctionWithoutMethodThrowsException()
- {
- $this->expectException(Exception::class);
- $this->expectExceptionMessageRegExp('/function not exists: {Closure}@.+#L\d+-\d+/');
- $container = new Container;
- $container->invokeFunction(function () {
- throw new \ReflectionException('test exception');
- });
- }
- public function testInvoke()
- {
- $container = new Container();
- Container::setInstance($container);
- $container->bind(Container::class, $container);
- $stub = $this->createMock(Taylor::class);
- $stub->expects($this->once())->method('some')->with($container)->will($this->returnSelf());
- $container->invokeMethod([$stub, 'some']);
- $this->assertSame($container, $container->invokeMethod(Taylor::class . '::test'));
- $reflect = new ReflectionMethod($container, 'exists');
- $this->assertTrue($container->invokeReflectMethod($container, $reflect, [Container::class]));
- $this->assertSame($container, $container->invoke(function (Container $container) {
- return $container;
- }));
- $this->assertSame($container, $container->invoke(Taylor::class . '::test'));
- $object = $container->invokeClass(SomeClass::class);
- $this->assertInstanceOf(SomeClass::class, $object);
- $this->assertSame($container, $object->container);
- $stdClass = new stdClass();
- $container->invoke(function (Container $container, stdClass $stdObject, $key1, $lowKey, $key2 = 'default') use ($stdClass) {
- $this->assertEquals('value1', $key1);
- $this->assertEquals('default', $key2);
- $this->assertEquals('value2', $lowKey);
- $this->assertSame($stdClass, $stdObject);
- return $container;
- }, ['some' => $stdClass, 'key1' => 'value1', 'low_key' => 'value2']);
- }
- public function testInvokeMethodNotExists()
- {
- $container = $this->resolveContainer();
- $this->expectException(Exception::class);
- $container->invokeMethod([SomeClass::class, 'any']);
- }
- public function testInvokeClassNotExists()
- {
- $container = new Container();
- Container::setInstance($container);
- $container->bind(Container::class, $container);
- $this->expectExceptionObject(new ClassNotFoundException('class not exists: SomeClass'));
- $container->invokeClass('SomeClass');
- }
- protected function resolveContainer()
- {
- $container = new Container();
- Container::setInstance($container);
- return $container;
- }
- }
|