Completed
Push — master ( 8c5203...c6433c )
by Gerrit
23:20
created

ArgumentCompilerTest::setUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
c 0
b 0
f 0
rs 10
cc 1
nc 1
nop 0
1
<?php
2
/**
3
 * Copyright (C) 2017  Gerrit Addiks.
4
 * This package (including this file) was released under the terms of the GPL-3.0.
5
 * You should have received a copy of the GNU General Public License along with this program.
6
 * If not, see <http://www.gnu.org/licenses/> or send me a mail so i can send you a copy.
7
 * @license GPL-3.0
8
 * @author Gerrit Addiks <[email protected]>
9
 */
10
11
namespace Addiks\SymfonyGenerics\Tests\Unit\Services;
12
13
use PHPUnit\Framework\TestCase;
14
use Addiks\SymfonyGenerics\Services\ArgumentCompiler;
15
use Psr\Container\ContainerInterface;
16
use Addiks\SymfonyGenerics\Services\EntityRepositoryInterface;
17
use ReflectionMethod;
18
use Symfony\Component\HttpFoundation\Request;
19
use ReflectionParameter;
20
use ReflectionType;
21
use stdClass;
22
use InvalidArgumentException;
23
use Serializable;
24
25
final class ArgumentCompilerTest extends TestCase
26
{
27
28
    /**
29
     * @var ArgumentCompiler
30
     */
31
    private $argumentCompiler;
32
33
    /**
34
     * @var ContainerInterface
35
     */
36
    private $container;
37
38
    /**
39
     * @var EntityRepositoryInterface
40
     */
41
    private $entityRepository;
42
43
    public function setUp()
44
    {
45
        $this->container = $this->createMock(ContainerInterface::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(\Psr\C...tainerInterface::class) of type object<PHPUnit\Framework\MockObject\MockObject> is incompatible with the declared type object<Psr\Container\ContainerInterface> of property $container.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
46
        $this->entityRepository = $this->createMock(EntityRepositoryInterface::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createMock(\Addik...sitoryInterface::class) of type object<PHPUnit\Framework\MockObject\MockObject> is incompatible with the declared type object<Addiks\SymfonyGen...ityRepositoryInterface> of property $entityRepository.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
47
48
        $this->argumentCompiler = new ArgumentCompiler($this->container, $this->entityRepository);
0 ignored issues
show
Documentation introduced by
$this->container is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Psr\Container\ContainerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation introduced by
$this->entityRepository is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Addiks\SymfonyGen...ityRepositoryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
49
    }
50
51
    /**
52
     * @test
53
     */
54
    public function shouldBuildRouteArguments()
55
    {
56
        /** @var Request $request */
57
        $request = $this->createMock(Request::class);
58
        $request->method('get')->will($this->returnValueMap([
0 ignored issues
show
Bug introduced by
The method method() does not exist on Symfony\Component\HttpFoundation\Request. Did you maybe mean enableHttpMethodParameterOverride()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
59
            ['reqFoo', null, 'ipsum'],
60
        ]));
61
62
        $someObject = new stdClass();
63
64
        /** @var Serializable $someService */
65
        $someService = $this->createMock(Serializable::class);
66
        $someService->method('serialize')->willReturn($someObject);
67
68
        $this->container->method('get')->will($this->returnValueMap([
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Psr\Container\ContainerInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
69
            ['some.service', $someService],
70
        ]));
71
72
        /** @var array<string, mixed> $expectedRouteArguments */
73
        $expectedRouteArguments = array(
74
            'foo' => 'ipsum',
75
            'bar' => $someObject
76
        );
77
78
        /** @var array<string, mixed> $actualRouteArguments */
79
        $actualRouteArguments = $this->argumentCompiler->buildRouteArguments([
80
            'foo' => '$reqFoo',
81
            'bar' => '@some.service::serialize',
82
        ], $request);
83
84
        $this->assertEquals($expectedRouteArguments, $actualRouteArguments);
85
    }
86
87
    /**
88
     * @test
89
     */
90
    public function shouldBuildCallArguments()
91
    {
92
        /** @var ReflectionMethod $methodReflection */
93
        $methodReflection = $this->createMock(ReflectionMethod::class);
94
95
        /** @var ReflectionParameter $parameterFooReflection */
96
        $parameterFooReflection = $this->createMock(ReflectionParameter::class);
97
        $parameterFooReflection->method('getName')->willReturn("foo");
98
99
        /** @var ReflectionParameter $parameterBarReflection */
100
        $parameterBarReflection = $this->createMock(ReflectionParameter::class);
101
        $parameterBarReflection->method('getName')->willReturn("bar");
102
103
        /** @var ReflectionParameter $parameterBazReflection */
104
        $parameterBazReflection = $this->createMock(ReflectionParameter::class);
105
        $parameterBazReflection->method('getName')->willReturn("baz");
106
107
        /** @var ReflectionType $parameterType */
108
        $parameterType = $this->createMock(ReflectionType::class);
109
        $parameterType->method('__toString')->willReturn(stdClass::class);
110
111
        /** @var ReflectionParameter $parameterBazReflection */
112
        $parameterFazReflection = $this->createMock(ReflectionParameter::class);
113
        $parameterFazReflection->method('getName')->willReturn("faz");
114
        $parameterFazReflection->method('hasType')->willReturn(true);
115
        $parameterFazReflection->method('getType')->willReturn($parameterType);
116
117
        $methodReflection->method("getParameters")->willReturn([
118
            $parameterFooReflection,
119
            $parameterBarReflection,
120
            $parameterBazReflection,
121
            $parameterFazReflection
122
        ]);
123
124
        /** @var Request $request */
125
        $request = $this->createMock(Request::class);
126
        $request->method('get')->will($this->returnValueMap([
0 ignored issues
show
Bug introduced by
The method method() does not exist on Symfony\Component\HttpFoundation\Request. Did you maybe mean enableHttpMethodParameterOverride()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
127
            ['lorem', null, 'ipsum'],
128
            ['bar', null, 'blah'],
129
        ]));
130
131
        /** @var array<string, mixed> $argumentsConfiguration */
132
        $argumentsConfiguration = array(
133
            "foo" => '$lorem',
134
            "baz" => '@some.service',
135
            "faz" => '$lorem'
136
        );
137
138
        /** @var object $someService */
139
        $someService = new stdClass();
140
141
        $this->container->method('get')->will($this->returnValueMap([
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Psr\Container\ContainerInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
142
            ['some.service', $someService],
143
        ]));
144
145
        $this->entityRepository->expects($this->once())->method('findEntity')->with(
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Addiks\SymfonyGen...ityRepositoryInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
146
            $this->equalTo(stdClass::class),
147
            $this->equalTo('ipsum')
148
        )->willReturn($someService);
149
150
        /** @var array<int, mixed> $expectedCallArguments */
151
        $expectedCallArguments = array(
152
            'ipsum',
153
            'blah',
154
            $someService,
155
            $someService
156
        );
157
158
        /** @var array<int, mixed> $actualCallArguments */
159
        $actualCallArguments = $this->argumentCompiler->buildCallArguments(
160
            $methodReflection,
161
            $argumentsConfiguration,
162
            $request
163
        );
164
165
        $this->assertEquals($expectedCallArguments, $actualCallArguments);
166
    }
167
168
    /**
169
     * @test
170
     */
171
    public function shouldRejectInvalidArgumentConfiguration()
172
    {
173
        $this->expectException(InvalidArgumentException::class);
174
175
        /** @var array $argumentsConfiguration */
176
        $argumentsConfiguration = array(
177
            'foo' => false
178
        );
179
180
        /** @var ReflectionParameter $parameterFooReflection */
181
        $parameterFooReflection = $this->createMock(ReflectionParameter::class);
182
        $parameterFooReflection->method('getName')->willReturn("foo");
183
184
        /** @var ReflectionMethod $methodReflection */
185
        $methodReflection = $this->createMock(ReflectionMethod::class);
186
187
        $methodReflection->method("getParameters")->willReturn([
188
            $parameterFooReflection,
189
        ]);
190
191
        /** @var Request $request */
192
        $request = $this->createMock(Request::class);
193
194
        $this->argumentCompiler->buildCallArguments(
195
            $methodReflection,
196
            $argumentsConfiguration,
197
            $request
198
        );
199
200
    }
201
202
    /**
203
     * @test
204
     */
205
    public function shouldRejectNonExistingFactoryMethod()
206
    {
207
        $this->expectException(InvalidArgumentException::class);
208
209
        /** @var Request $request */
210
        $request = $this->createMock(Request::class);
211
212
        /** @var Serializable $someService */
213
        $someService = $this->createMock(Serializable::class);
214
215
        $this->container->method('get')->will($this->returnValueMap([
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<Psr\Container\ContainerInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
216
            ['some.service', $someService],
217
        ]));
218
219
        $this->argumentCompiler->buildRouteArguments([
220
            'foo' => '$reqFoo',
221
            'bar' => '@some.service::doesNotExist',
222
        ], $request);
223
    }
224
225
}
226