ConvertRegistryPassTest::testProcess()   C
last analyzed

Complexity

Conditions 12
Paths 2

Size

Total Lines 78
Code Lines 58

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 78
rs 5.1746
c 0
b 0
f 0
cc 12
eloc 58
nc 2
nop 0

How to fix   Long Method    Complexity   

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
/*
4
 * This file is part of the Lug package.
5
 *
6
 * (c) Eric GELOEN <[email protected]>
7
 *
8
 * For the full copyright and license information, please read the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Lug\Bundle\RegistryBundle\Tests\DependencyInjection\Compiler;
13
14
use Lug\Bundle\RegistryBundle\DependencyInjection\Compiler\ConvertRegistryPass;
15
use Lug\Bundle\RegistryBundle\Model\LazyRegistry;
16
use Lug\Component\Registry\Model\Registry;
17
use Symfony\Component\DependencyInjection\ContainerBuilder;
18
use Symfony\Component\DependencyInjection\Definition;
19
use Symfony\Component\DependencyInjection\Reference;
20
21
/**
22
 * @author GeLo <[email protected]>
23
 */
24
class ConvertRegistryPassTest extends \PHPUnit_Framework_TestCase
25
{
26
    /**
27
     * @var ConvertRegistryPass
28
     */
29
    private $compiler;
30
31
    /**
32
     * @var ContainerBuilder|\PHPUnit_Framework_MockObject_MockObject
33
     */
34
    private $container;
35
36
    /**
37
     * {@inheritdoc}
38
     */
39
    protected function setUp()
40
    {
41
        $this->container = $this->createContainerMock();
42
        $this->compiler = new ConvertRegistryPass();
43
    }
44
45
    public function testProcess()
46
    {
47
        $this->container
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Symfony\Component\Depend...ection\ContainerBuilder.

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...
48
            ->expects($this->once())
49
            ->method('findTaggedServiceIds')
50
            ->with($this->identicalTo($tag = 'lug.registry'))
51
            ->will($this->returnValue([$service = 'my.registry' => []]));
52
53
        $this->container
54
            ->expects($this->once())
55
            ->method('getDefinition')
56
            ->with($this->identicalTo($service))
57
            ->will($this->returnValue($definition = $this->createDefinitionMock()));
58
59
        $definition
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Symfony\Component\DependencyInjection\Definition.

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...
60
            ->expects($this->once())
61
            ->method('getClass')
62
            ->will($this->returnValue(Registry::class));
63
64
        $definition
65
            ->expects($this->once())
66
            ->method('clearTag')
67
            ->with($this->identicalTo($tag))
68
            ->will($this->returnSelf());
69
70
        $types = [
71
            ['type1', new Reference('my.id1')],
72
            ['type2', new Reference('my.id2')],
73
        ];
74
75
        $map = [];
76
        foreach ($types as $type) {
77
            $map[] = ['offsetSet', $type];
78
        }
79
80
        $definition
81
            ->expects($this->once())
82
            ->method('getMethodCalls')
83
            ->will($this->returnValue($map));
84
85
        $definition
86
            ->expects($this->exactly(3))
87
            ->method('hasMethodCall')
88
            ->with($this->identicalTo('offsetSet'))
89
            ->willReturnOnConsecutiveCalls(true, true, false);
90
91
        $definition
92
            ->expects($this->exactly(2))
93
            ->method('removeMethodCall')
94
            ->with('offsetSet');
95
96
        $this->container
97
            ->expects($this->exactly(2))
98
            ->method('setDefinition')
99
            ->withConsecutive(
100
                [$service.'.internal', $definition],
101
                [$service, $this->callback(function ($definition) use ($service, $types) {
102
                    $result = $definition instanceof Definition
103
                        && $definition->getClass() === LazyRegistry::class
104
                        && count($definition->getArguments()) === 2
105
                        && $definition->getArgument(0) instanceof Reference
106
                        && (string) $definition->getArgument(0) === 'service_container'
107
                        && $definition->getArgument(1) instanceof Reference
108
                        && (string) $definition->getArgument(1) === $service.'.internal';
109
110
                    $result = $result && count($methodCalls = $definition->getMethodCalls()) === count($types);
111
112
                    foreach ($types as $type => $value) {
113
                        $value[1] = (string) $value[1];
114
                        $result = $result && isset($methodCalls[$type]) && $methodCalls[$type] === ['setLazy', $value];
115
                    }
116
117
                    return $result;
118
                })]
119
            );
120
121
        $this->compiler->process($this->container);
122
    }
123
124
    public function testProcessWithLazyRegistry()
125
    {
126
        $this->container
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Symfony\Component\Depend...ection\ContainerBuilder.

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...
127
            ->expects($this->once())
128
            ->method('findTaggedServiceIds')
129
            ->with($this->identicalTo($tag = 'lug.registry'))
130
            ->will($this->returnValue([$service = 'my.registry' => []]));
131
132
        $this->container
133
            ->expects($this->once())
134
            ->method('getDefinition')
135
            ->with($this->identicalTo($service))
136
            ->will($this->returnValue($definition = $this->createDefinitionMock()));
137
138
        $definition
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Symfony\Component\DependencyInjection\Definition.

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...
139
            ->expects($this->once())
140
            ->method('getClass')
141
            ->will($this->returnValue(LazyRegistry::class));
142
143
        $definition
144
            ->expects($this->never())
145
            ->method('clearTag');
146
147
        $definition
148
            ->expects($this->never())
149
            ->method('removeMethodCall')
150
            ->with('offsetSet');
151
152
        $this->container
153
            ->expects($this->never())
154
            ->method('setDefinition');
155
156
        $this->compiler->process($this->container);
157
    }
158
159
    /**
160
     * @return ContainerBuilder|\PHPUnit_Framework_MockObject_MockObject
161
     */
162
    private function createContainerMock()
163
    {
164
        return $this->getMockBuilder(ContainerBuilder::class)
165
            ->setMethods(['findTaggedServiceIds', 'getDefinition', 'setDefinition'])
166
            ->getMock();
167
    }
168
169
    /**
170
     * @return Definition|\PHPUnit_Framework_MockObject_MockObject
171
     */
172
    private function createDefinitionMock()
173
    {
174
        return $this->createMock(Definition::class);
175
    }
176
}
177