testPrependResolver()   B
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 87
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 87
rs 8.6296
cc 1
eloc 49
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @link    https://github.com/nnx-framework/entry-name-resolver
4
 * @author  Malofeykin Andrey  <[email protected]>
5
 */
6
namespace Nnx\EntryNameResolver\PhpUnit\Test;
7
8
use Nnx\EntryNameResolver\PhpUnit\TestData\TestPaths;
9
use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;
10
use Nnx\EntryNameResolver\EntryNameResolverManagerInterface;
11
use Nnx\EntryNameResolver\EntryNameResolverChain;
12
use Nnx\EntryNameResolver\Exception\RuntimeException;
13
use Nnx\EntryNameResolver\EntryNameResolverInterface;
14
use Nnx\EntryNameResolver\EntryNameResolverManager;
15
use PHPUnit_Framework_MockObject_MockObject;
16
17
/**
18
 * Class EntryNameResolverIntegrationTest
19
 *
20
 * @package Nnx\EntryNameResolver\PhpUnit\Test
21
 */
22
class EntryNameResolverChainFunctionalTest extends AbstractHttpControllerTestCase
23
{
24
    /**
25
     * Проверка получения резолвера с некорректным конфигом.
26
     *
27
     *
28
     * @throws \Zend\Stdlib\Exception\LogicException
29
     * @throws \Zend\ServiceManager\Exception\ServiceNotFoundException
30
     * @throws \Interop\Container\Exception\NotFoundException
31
     * @throws \Interop\Container\Exception\ContainerException
32
     */
33 View Code Duplication
    public function testInvalidEntryNameResolverChainConfig()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
34
    {
35
        /** @noinspection PhpIncludeInspection */
36
        $this->setApplicationConfig(
37
            include TestPaths::getPathToDefaultAppConfig()
38
        );
39
40
        /** @var EntryNameResolverManagerInterface $entryNameResolverManager */
41
        $entryNameResolverManager = $this->getApplicationServiceLocator()->get(EntryNameResolverManagerInterface::class);
42
43
        $e = null;
44
        try {
45
            $entryNameResolverManager->get(EntryNameResolverChain::class, [
46
                'resolvers' => [
47
                    'invalidEntryNameResolver'
48
                ]
49
            ]);
50
        } catch (\Exception $ex) {
51
            $e = $ex;
52
        }
53
54
        static::assertInstanceOf(\Exception::class, $e);
55
        $prevException = $e->getPrevious();
56
        static::assertInstanceOf(RuntimeException::class, $prevException);
57
        static::assertEquals('Entry name resolver config is not array', $prevException->getMessage());
58
    }
59
60
    /**
61
     * Проверка получения резолвера с конфигом, в котором в описание вложенного резолвера не указано имя.
62
     *
63
     *
64
     * @throws \Zend\Stdlib\Exception\LogicException
65
     * @throws \Zend\ServiceManager\Exception\ServiceNotFoundException
66
     * @throws \Interop\Container\Exception\NotFoundException
67
     * @throws \Interop\Container\Exception\ContainerException
68
     */
69 View Code Duplication
    public function testNestedResolverInvalidName()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
70
    {
71
        /** @noinspection PhpIncludeInspection */
72
        $this->setApplicationConfig(
73
            include TestPaths::getPathToDefaultAppConfig()
74
        );
75
76
        /** @var EntryNameResolverManagerInterface $entryNameResolverManager */
77
        $entryNameResolverManager = $this->getApplicationServiceLocator()->get(EntryNameResolverManagerInterface::class);
78
79
        $e = null;
80
        try {
81
            $entryNameResolverManager->get(EntryNameResolverChain::class, [
82
                'resolvers' => [
83
                    [
84
85
                    ]
86
                ]
87
            ]);
88
        } catch (\Exception $ex) {
89
            $e = $ex;
90
        }
91
92
        static::assertInstanceOf(\Exception::class, $e);
93
        $prevException = $e->getPrevious();
94
        static::assertInstanceOf(RuntimeException::class, $prevException);
95
        static::assertEquals('Resolver entry name not found', $prevException->getMessage());
96
    }
97
98
    /**
99
     * Проверка получения резолвера с конфигом, в котором в опции вложенного резолвера описаны не строкой
100
     *
101
     *
102
     * @throws \Zend\Stdlib\Exception\LogicException
103
     * @throws \Zend\ServiceManager\Exception\ServiceNotFoundException
104
     * @throws \Interop\Container\Exception\NotFoundException
105
     * @throws \Interop\Container\Exception\ContainerException
106
     */
107
    public function testNestedResolverInvalidOptions()
108
    {
109
        /** @noinspection PhpIncludeInspection */
110
        $this->setApplicationConfig(
111
            include TestPaths::getPathToDefaultAppConfig()
112
        );
113
114
        /** @var EntryNameResolverManagerInterface $entryNameResolverManager */
115
        $entryNameResolverManager = $this->getApplicationServiceLocator()->get(EntryNameResolverManagerInterface::class);
116
117
        $e = null;
118
        try {
119
            $entryNameResolverManager->get(EntryNameResolverChain::class, [
120
                'resolvers' => [
121
                    [
122
                        'name' => 'test',
123
                        'options' => 'notArray'
124
                    ]
125
                ]
126
            ]);
127
        } catch (\Exception $ex) {
128
            $e = $ex;
129
        }
130
131
        static::assertInstanceOf(\Exception::class, $e);
132
        $prevException = $e->getPrevious();
133
        static::assertInstanceOf(RuntimeException::class, $prevException);
134
        static::assertEquals('Resolver options is not array', $prevException->getMessage());
135
    }
136
137
    /**
138
     * Проверка работы фабрики по созданию цепочки резолверов
139
     *
140
     *
141
     * @throws \Zend\Stdlib\Exception\LogicException
142
     * @throws \Zend\ServiceManager\Exception\ServiceNotFoundException
143
     * @throws \PHPUnit_Framework_Exception
144
     * @throws \Zend\ServiceManager\Exception\InvalidServiceNameException
145
     */
146
    public function testInsertResolverChain()
147
    {
148
        /** @noinspection PhpIncludeInspection */
149
        $this->setApplicationConfig(
150
            include TestPaths::getPathToDefaultAppConfig()
151
        );
152
153
        $entryName = 'testEntryName';
154
        $context = $this;
155
156
157
158
        /** @var EntryNameResolverManager $entryNameResolverManager */
159
        $entryNameResolverManager = $this->getApplicationServiceLocator()->get(EntryNameResolverManagerInterface::class);
160
161
        $expectedSequence = [3, 2, 1, 4];
162
163
        $actualSequence = [];
164
165
        $mockResolver1 = $this->getMock(EntryNameResolverInterface::class);
166
        $mockResolver1->expects(static::once())
167
            ->method('resolveEntryNameByContext')
168
            ->with(static::equalTo($entryName), static::equalTo($context))
169
            ->will(static::returnCallback(function () use (&$actualSequence) {
170
                $actualSequence[] = 1;
171
            }));
172
        $mockResolverName1 = spl_object_hash($mockResolver1);
173
        $entryNameResolverManager->setService($mockResolverName1, $mockResolver1);
174
175
        $mockResolver2 = $this->getMock(EntryNameResolverInterface::class);
176
        $mockResolver2->expects(static::once())
177
            ->method('resolveEntryNameByContext')
178
            ->with(static::equalTo($entryName), static::equalTo($context))
179
            ->will(static::returnCallback(function () use (&$actualSequence) {
180
                $actualSequence[] = 2;
181
            }));
182
        $mockResolverName2 = spl_object_hash($mockResolver2);
183
        $entryNameResolverManager->setService($mockResolverName2, $mockResolver2);
184
185
        $mockResolver3 = $this->getMock(EntryNameResolverInterface::class);
186
        $mockResolver3->expects(static::once())
187
            ->method('resolveEntryNameByContext')
188
            ->with(static::equalTo($entryName), static::equalTo($context))
189
            ->will(static::returnCallback(function () use (&$actualSequence) {
190
                $actualSequence[] = 3;
191
            }));
192
        $mockResolverName3 = spl_object_hash($mockResolver3);
193
        $entryNameResolverManager->setService($mockResolverName3, $mockResolver3);
194
195
196
        $mockResolver4 = $this->getMock(EntryNameResolverInterface::class);
197
        $mockResolver4->expects(static::once())
198
            ->method('resolveEntryNameByContext')
199
            ->with(static::equalTo($entryName), static::equalTo($context))
200
            ->will(static::returnCallback(function () use (&$actualSequence) {
201
                $actualSequence[] = 4;
202
            }));
203
        $mockResolverName4 = spl_object_hash($mockResolver4);
204
        $entryNameResolverManager->setService($mockResolverName4, $mockResolver4);
205
206
207
208
        /** @var EntryNameResolverChain $entryNameResolverChain */
209
        $entryNameResolverChain = $entryNameResolverManager->get(EntryNameResolverChain::class, [
210
            'resolvers' => [
211
                [
212
                    'name' => $mockResolverName1,
213
                    'priority'  => 70
214
                ],
215
                [
216
                    'name' => $mockResolverName2,
217
                    'priority'  => 80
218
                ],
219
                [
220
                    'name' => $mockResolverName3,
221
                    'priority'  => 100
222
                ],
223
                [
224
                    'name' => $mockResolverName4
225
                ],
226
227
            ]
228
        ]);
229
230
        $entryNameResolverChain->resolveEntryNameByContext($entryName, $context);
231
232
233
        static::assertEquals($expectedSequence, $actualSequence);
234
    }
235
236
237
    /**
238
     * Проверка получения результатов из цепочки резолверов
239
     *
240
     *
241
     * @throws \Zend\Stdlib\Exception\LogicException
242
     * @throws \Zend\ServiceManager\Exception\ServiceNotFoundException
243
     * @throws \PHPUnit_Framework_Exception
244
     * @throws \Zend\ServiceManager\Exception\InvalidServiceNameException
245
     */
246
    public function testReturnResult()
247
    {
248
        /** @noinspection PhpIncludeInspection */
249
        $this->setApplicationConfig(
250
            include TestPaths::getPathToDefaultAppConfig()
251
        );
252
253
        $entryName = 'testEntryName';
254
        $context = $this;
255
256
        $expectedResolveEntryName = 'expectedResolveEntryName';
257
258
259
        /** @var EntryNameResolverManager $entryNameResolverManager */
260
        $entryNameResolverManager = $this->getApplicationServiceLocator()->get(EntryNameResolverManagerInterface::class);
261
262
        $mockResolver1 = $this->getMock(EntryNameResolverInterface::class);
263
        $mockResolver1->expects(static::once())
264
            ->method('resolveEntryNameByContext')
265
            ->with(static::equalTo($entryName), static::equalTo($context));
266
        $mockResolverName1 = spl_object_hash($mockResolver1);
267
        $entryNameResolverManager->setService($mockResolverName1, $mockResolver1);
268
269
        $mockResolver2 = $this->getMock(EntryNameResolverInterface::class);
270
        $mockResolver2->expects(static::once())
271
            ->method('resolveEntryNameByContext')
272
            ->with(static::equalTo($entryName), static::equalTo($context));
273
        $mockResolverName2 = spl_object_hash($mockResolver2);
274
        $entryNameResolverManager->setService($mockResolverName2, $mockResolver2);
275
276
        $mockResolver3 = $this->getMock(EntryNameResolverInterface::class);
277
        $mockResolver3->expects(static::once())
278
            ->method('resolveEntryNameByContext')
279
            ->with(static::equalTo($entryName), static::equalTo($context))
280
            ->will(static::returnValue($expectedResolveEntryName));
281
        $mockResolverName3 = spl_object_hash($mockResolver3);
282
        $entryNameResolverManager->setService($mockResolverName3, $mockResolver3);
283
284
285
        $mockResolver4 = $this->getMock(EntryNameResolverInterface::class);
286
        $mockResolver4->expects(static::never())
287
            ->method('resolveEntryNameByContext');
288
        $mockResolverName4 = spl_object_hash($mockResolver4);
289
        $entryNameResolverManager->setService($mockResolverName4, $mockResolver4);
290
291
292
293
        /** @var EntryNameResolverChain $entryNameResolverChain */
294
        $entryNameResolverChain = $entryNameResolverManager->get(EntryNameResolverChain::class, [
295
            'resolvers' => [
296
                [
297
                    'name' => $mockResolverName1,
298
                    'priority'  => 80
299
                ],
300
                [
301
                    'name' => $mockResolverName2,
302
                    'priority'  => 100
303
                ],
304
                [
305
                    'name' => $mockResolverName3,
306
                    'priority'  => 70
307
                ],
308
                [
309
                    'name' => $mockResolverName4
310
                ],
311
312
            ]
313
        ]);
314
315
        $actualResolveEntryName = $entryNameResolverChain->resolveEntryNameByContext($entryName, $context);
316
317
        static::assertEquals($expectedResolveEntryName, $actualResolveEntryName);
318
    }
319
320
321
    /**
322
     * Проверка получения результатов из цепочки резолверов
323
     *
324
     *
325
     * @throws \Zend\Stdlib\Exception\LogicException
326
     * @throws \Zend\ServiceManager\Exception\ServiceNotFoundException
327
     * @throws \PHPUnit_Framework_Exception
328
     * @throws \Zend\ServiceManager\Exception\InvalidServiceNameException
329
     */
330
    public function testPrependResolver()
331
    {
332
        /** @noinspection PhpIncludeInspection */
333
        $this->setApplicationConfig(
334
            include TestPaths::getPathToDefaultAppConfig()
335
        );
336
337
        $entryName = 'testEntryName';
338
        $context = $this;
339
340
341
342
        /** @var EntryNameResolverManager $entryNameResolverManager */
343
        $entryNameResolverManager = $this->getApplicationServiceLocator()->get(EntryNameResolverManagerInterface::class);
344
345
        $expectedSequence = [1, 3, 2, 4];
346
347
        $actualSequence = [];
348
349
        $mockResolver2 = $this->getMock(EntryNameResolverInterface::class);
350
        $mockResolver2->expects(static::once())
351
            ->method('resolveEntryNameByContext')
352
            ->with(static::equalTo($entryName), static::equalTo($context))
353
            ->will(static::returnCallback(function () use (&$actualSequence) {
354
                $actualSequence[] = 2;
355
            }));
356
        $mockResolverName2 = spl_object_hash($mockResolver2);
357
        $entryNameResolverManager->setService($mockResolverName2, $mockResolver2);
358
359
        $mockResolver3 = $this->getMock(EntryNameResolverInterface::class);
360
        $mockResolver3->expects(static::once())
361
            ->method('resolveEntryNameByContext')
362
            ->with(static::equalTo($entryName), static::equalTo($context))
363
            ->will(static::returnCallback(function () use (&$actualSequence) {
364
                $actualSequence[] = 3;
365
            }));
366
        $mockResolverName3 = spl_object_hash($mockResolver3);
367
        $entryNameResolverManager->setService($mockResolverName3, $mockResolver3);
368
369
370
        $mockResolver4 = $this->getMock(EntryNameResolverInterface::class);
371
        $mockResolver4->expects(static::once())
372
            ->method('resolveEntryNameByContext')
373
            ->with(static::equalTo($entryName), static::equalTo($context))
374
            ->will(static::returnCallback(function () use (&$actualSequence) {
375
                $actualSequence[] = 4;
376
            }));
377
        $mockResolverName4 = spl_object_hash($mockResolver4);
378
        $entryNameResolverManager->setService($mockResolverName4, $mockResolver4);
379
380
381
382
        /** @var EntryNameResolverChain $entryNameResolverChain */
383
        $entryNameResolverChain = $entryNameResolverManager->get(EntryNameResolverChain::class, [
384
            'resolvers' => [
385
                [
386
                    'name' => $mockResolverName2,
387
                    'priority'  => 80
388
                ],
389
                [
390
                    'name' => $mockResolverName3,
391
                    'priority'  => 100
392
                ],
393
                [
394
                    'name' => $mockResolverName4
395
                ],
396
397
            ]
398
        ]);
399
400
401
        /** @var PHPUnit_Framework_MockObject_MockObject|EntryNameResolverInterface $mockResolver1 */
402
        $mockResolver1 = $this->getMock(EntryNameResolverInterface::class);
403
        $mockResolver1->expects(static::once())
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Nnx\EntryNameResolver\EntryNameResolverInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
404
            ->method('resolveEntryNameByContext')
405
            ->with(static::equalTo($entryName), static::equalTo($context))
406
            ->will(static::returnCallback(function () use (&$actualSequence) {
407
                $actualSequence[] = 1;
408
            }));
409
        $entryNameResolverChain->prependResolver($mockResolver1);
410
411
        $entryNameResolverChain->resolveEntryNameByContext($entryName, $context);
412
413
414
        static::assertEquals($expectedSequence, $actualSequence);
415
        static::assertCount(4, $entryNameResolverChain);
416
    }
417
418
    /**
419
     * Проверка ситуации когда, при создание фабрики, указан некорректный класс резолвера
420
     *
421
     *
422
     * @throws \Zend\Stdlib\Exception\LogicException
423
     * @throws \Zend\ServiceManager\Exception\ServiceNotFoundException
424
     * @throws \Interop\Container\Exception\NotFoundException
425
     * @throws \Interop\Container\Exception\ContainerException
426
     */
427 View Code Duplication
    public function testInvalidEntryNameResolverChainClassName()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
428
    {
429
        /** @noinspection PhpIncludeInspection */
430
        $this->setApplicationConfig(
431
            include TestPaths::getPathToDefaultAppConfig()
432
        );
433
434
        /** @var EntryNameResolverManagerInterface $entryNameResolverManager */
435
        $entryNameResolverManager = $this->getApplicationServiceLocator()->get(EntryNameResolverManagerInterface::class);
436
437
        $e = null;
438
        try {
439
            $entryNameResolverManager->get(EntryNameResolverChain::class, [
440
                'className' => \stdClass::class
441
            ]);
442
        } catch (\Exception $ex) {
443
            $e = $ex;
444
        }
445
446
        static::assertInstanceOf(\Exception::class, $e);
447
        $prevException = $e->getPrevious();
448
        static::assertInstanceOf(RuntimeException::class, $prevException);
449
        static::assertEquals('EntryNameResolverChain not implements: Nnx\EntryNameResolver\EntryNameResolverChain', $prevException->getMessage());
450
    }
451
}
452