Completed
Pull Request — 6.0 (#2058)
by nhzex
05:48
created

ContainerTest::testResolving()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 8
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 15
rs 10
1
<?php
2
0 ignored issues
show
Coding Style introduced by
Missing file doc comment
Loading history...
3
namespace think\tests;
4
5
use PHPUnit\Framework\TestCase;
6
use ReflectionMethod;
7
use stdClass;
8
use think\Container;
9
use think\exception\ClassNotFoundException;
10
use think\exception\FuncNotFoundException;
11
12
class Taylor
13
{
14
    public $name;
15
16
    public function __construct($name)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function __construct()
Loading history...
17
    {
18
        $this->name = $name;
19
    }
20
21
    public function some(Container $container)
0 ignored issues
show
Unused Code introduced by
The parameter $container is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

21
    public function some(/** @scrutinizer ignore-unused */ Container $container)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Coding Style introduced by
Missing doc comment for function some()
Loading history...
22
    {
23
    }
24
25
    protected function protectionFun()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function protectionFun()
Loading history...
26
    {
27
        return true;
28
    }
29
30
    public static function test(Container $container)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function test()
Loading history...
31
    {
32
        return $container;
33
    }
34
35
    public static function __make()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function __make()
Loading history...
36
    {
37
        return new self('Taylor');
38
    }
39
}
40
41
class SomeClass
42
{
43
    public $container;
44
45
    public $count = 0;
46
47
    public function __construct(Container $container)
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function __construct()
Loading history...
48
    {
49
        $this->container = $container;
50
    }
51
}
52
53
class ContainerTest extends TestCase
54
{
55
    protected function tearDown(): void
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function tearDown()
Loading history...
56
    {
57
        Container::setInstance(null);
58
    }
59
60
    public function testClosureResolution()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function testClosureResolution()
Loading history...
61
    {
62
        $container = new Container;
63
64
        Container::setInstance($container);
65
66
        $container->bind('name', function () {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
67
            return 'Taylor';
68
        });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
69
70
        $this->assertEquals('Taylor', $container->make('name'));
71
72
        $this->assertEquals('Taylor', Container::pull('name'));
73
    }
74
75
    public function testGet()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function testGet()
Loading history...
76
    {
77
        $container = new Container;
78
79
        $this->expectException(ClassNotFoundException::class);
80
        $this->expectExceptionMessage('class not exists: name');
81
        $container->get('name');
82
83
        $container->bind('name', function () {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
84
            return 'Taylor';
85
        });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
86
87
        $this->assertSame('Taylor', $container->get('name'));
88
    }
89
90
    public function testExist()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function testExist()
Loading history...
91
    {
92
        $container = new Container;
93
94
        $container->bind('name', function () {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
95
            return 'Taylor';
96
        });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
97
98
        $this->assertFalse($container->exists("name"));
99
100
        $container->make('name');
101
102
        $this->assertTrue($container->exists('name'));
103
    }
104
105
    public function testInstance()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function testInstance()
Loading history...
106
    {
107
        $container = new Container;
108
109
        $container->bind('name', function () {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
110
            return 'Taylor';
111
        });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
112
113
        $this->assertEquals('Taylor', $container->get('name'));
114
115
        $container->bind('name2', Taylor::class);
116
117
        $object = new stdClass();
118
119
        $this->assertFalse($container->exists('name2'));
120
121
        $container->instance('name2', $object);
122
123
        $this->assertTrue($container->exists('name2'));
124
125
        $this->assertTrue($container->exists(Taylor::class));
126
127
        $this->assertEquals($object, $container->make(Taylor::class));
128
129
        unset($container->name1);
0 ignored issues
show
Bug Best Practice introduced by
The property name1 does not exist on think\Container. Since you implemented __get, consider adding a @property annotation.
Loading history...
130
131
        $this->assertFalse($container->exists('name1'));
132
133
        $container->delete('name2');
134
135
        $this->assertFalse($container->exists('name2'));
136
137
        foreach ($container as $class => $instance) {
138
139
        }
140
    }
141
142
    public function testBind()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function testBind()
Loading history...
143
    {
144
        $container = new Container;
145
146
        $object = new stdClass();
147
148
        $container->bind(['name' => Taylor::class]);
149
150
        $container->bind('name2', $object);
151
152
        $container->bind('name3', Taylor::class);
153
154
        $container->name4 = $object;
0 ignored issues
show
Bug Best Practice introduced by
The property name4 does not exist on think\Container. Since you implemented __set, consider adding a @property annotation.
Loading history...
155
156
        $container['name5'] = $object;
157
158
        $this->assertTrue(isset($container->name4));
0 ignored issues
show
Bug Best Practice introduced by
The property name4 does not exist on think\Container. Since you implemented __get, consider adding a @property annotation.
Loading history...
159
160
        $this->assertTrue(isset($container['name5']));
161
162
        $this->assertInstanceOf(Taylor::class, $container->get('name'));
163
164
        $this->assertSame($object, $container->get('name2'));
165
166
        $this->assertSame($object, $container->name4);
167
168
        $this->assertSame($object, $container['name5']);
169
170
        $this->assertInstanceOf(Taylor::class, $container->get('name3'));
171
172
        unset($container['name']);
173
174
        $this->assertFalse(isset($container['name']));
175
176
        unset($container->name3);
0 ignored issues
show
Bug Best Practice introduced by
The property name3 does not exist on think\Container. Since you implemented __get, consider adding a @property annotation.
Loading history...
177
178
        $this->assertFalse(isset($container->name3));
179
    }
180
181
    public function testAutoConcreteResolution()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function testAutoConcreteResolution()
Loading history...
182
    {
183
        $container = new Container;
184
185
        $taylor = $container->make(Taylor::class);
186
187
        $this->assertInstanceOf(Taylor::class, $taylor);
188
        $this->assertAttributeSame('Taylor', 'name', $taylor);
0 ignored issues
show
Deprecated Code introduced by
The function PHPUnit\Framework\Assert::assertAttributeSame() has been deprecated: https://github.com/sebastianbergmann/phpunit/issues/3338 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

188
        /** @scrutinizer ignore-deprecated */ $this->assertAttributeSame('Taylor', 'name', $taylor);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
189
    }
190
191
    public function testGetAndSetInstance()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function testGetAndSetInstance()
Loading history...
192
    {
193
        $this->assertInstanceOf(Container::class, Container::getInstance());
194
195
        $object = new stdClass();
196
197
        Container::setInstance($object);
198
199
        $this->assertSame($object, Container::getInstance());
200
201
        Container::setInstance(function () {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
202
            return $this;
203
        });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
204
205
        $this->assertSame($this, Container::getInstance());
206
    }
207
208
    public function testResolving()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function testResolving()
Loading history...
209
    {
210
        $container = new Container();
211
        $container->bind(Container::class, $container);
212
213
        $container->resolving(function (SomeClass $taylor, Container $container) {
0 ignored issues
show
Unused Code introduced by
The parameter $container is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

213
        $container->resolving(function (SomeClass $taylor, /** @scrutinizer ignore-unused */ Container $container) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
214
            $taylor->count++;
215
        });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
216
        $container->resolving(SomeClass::class, function (SomeClass $taylor, Container $container) {
0 ignored issues
show
Unused Code introduced by
The parameter $container is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

216
        $container->resolving(SomeClass::class, function (SomeClass $taylor, /** @scrutinizer ignore-unused */ Container $container) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
217
            $taylor->count++;
218
        });
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
219
220
        /** @var SomeClass $someClass */
0 ignored issues
show
Coding Style introduced by
The open comment tag must be the only content on the line
Loading history...
Coding Style introduced by
Missing short description in doc comment
Loading history...
Coding Style introduced by
The close comment tag must be the only content on the line
Loading history...
221
        $someClass = $container->invokeClass(SomeClass::class);
222
        $this->assertEquals(2, $someClass->count);
223
    }
224
225
    public function testInvokeFunctionWithoutMethodThrowsException()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function testInvokeFunctionWithoutMethodThrowsException()
Loading history...
226
    {
227
        $this->expectException(FuncNotFoundException::class);
228
        $this->expectExceptionMessage('function not exists: ContainerTestCallStub()');
229
        $container = new Container();
230
        $container->invokeFunction('ContainerTestCallStub', []);
231
    }
232
233
    public function testInvokeProtectionMethod()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function testInvokeProtectionMethod()
Loading history...
234
    {
235
        $container = new Container();
236
        $this->assertTrue($container->invokeMethod([Taylor::class, 'protectionFun'], [], true));
237
    }
238
239
    public function testInvoke()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function testInvoke()
Loading history...
240
    {
241
        $container = new Container();
242
243
        Container::setInstance($container);
244
245
        $container->bind(Container::class, $container);
246
247
        $stub = $this->createMock(Taylor::class);
248
249
        $stub->expects($this->once())->method('some')->with($container)->will($this->returnSelf());
250
251
        $container->invokeMethod([$stub, 'some']);
252
253
        $this->assertEquals('48', $container->invoke('ord', ['0']));
254
255
        $this->assertSame($container, $container->invoke(Taylor::class . '::test', []));
256
257
        $this->assertSame($container, $container->invokeMethod(Taylor::class . '::test'));
258
259
        $reflect = new ReflectionMethod($container, 'exists');
260
261
        $this->assertTrue($container->invokeReflectMethod($container, $reflect, [Container::class]));
262
263
        $this->assertSame($container, $container->invoke(function (Container $container) {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
264
            return $container;
265
        }));
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
266
267
        $this->assertSame($container, $container->invoke(Taylor::class . '::test'));
268
269
        $object = $container->invokeClass(SomeClass::class);
270
        $this->assertInstanceOf(SomeClass::class, $object);
271
        $this->assertSame($container, $object->container);
272
273
        $stdClass = new stdClass();
274
275
        $container->invoke(function (Container $container, stdClass $stdObject, $key1, $lowKey, $key2 = 'default') use ($stdClass) {
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
276
            $this->assertEquals('value1', $key1);
277
            $this->assertEquals('default', $key2);
278
            $this->assertEquals('value2', $lowKey);
279
            $this->assertSame($stdClass, $stdObject);
280
            return $container;
281
        }, ['some' => $stdClass, 'key1' => 'value1', 'low_key' => 'value2']);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
282
    }
283
284
    public function testInvokeMethodNotExists()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function testInvokeMethodNotExists()
Loading history...
285
    {
286
        $container = $this->resolveContainer();
287
        $this->expectException(FuncNotFoundException::class);
288
289
        $container->invokeMethod([SomeClass::class, 'any']);
290
    }
291
292
    public function testInvokeClassNotExists()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function testInvokeClassNotExists()
Loading history...
293
    {
294
        $container = new Container();
295
296
        Container::setInstance($container);
297
298
        $container->bind(Container::class, $container);
299
300
        $this->expectExceptionObject(new ClassNotFoundException('class not exists: SomeClass'));
301
302
        $container->invokeClass('SomeClass');
303
    }
304
305
    protected function resolveContainer()
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function resolveContainer()
Loading history...
306
    {
307
        $container = new Container();
308
309
        Container::setInstance($container);
310
        return $container;
311
    }
312
313
}
314