Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 148 | Details | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php declare(strict_types=1);
2
/*
3
 * This file is part of PHPUnit.
4
 *
5
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace PHPUnit\Framework\MockObject\Builder;
11
 
12
use function array_map;
13
use function array_merge;
14
use function count;
15
use function in_array;
16
use function is_string;
17
use function strtolower;
18
use PHPUnit\Framework\Constraint\Constraint;
19
use PHPUnit\Framework\MockObject\ConfigurableMethod;
20
use PHPUnit\Framework\MockObject\IncompatibleReturnValueException;
21
use PHPUnit\Framework\MockObject\InvocationHandler;
22
use PHPUnit\Framework\MockObject\Matcher;
23
use PHPUnit\Framework\MockObject\MatcherAlreadyRegisteredException;
24
use PHPUnit\Framework\MockObject\MethodCannotBeConfiguredException;
25
use PHPUnit\Framework\MockObject\MethodNameAlreadyConfiguredException;
26
use PHPUnit\Framework\MockObject\MethodNameNotConfiguredException;
27
use PHPUnit\Framework\MockObject\MethodParametersAlreadyConfiguredException;
28
use PHPUnit\Framework\MockObject\Rule;
29
use PHPUnit\Framework\MockObject\Stub\ConsecutiveCalls;
30
use PHPUnit\Framework\MockObject\Stub\Exception;
31
use PHPUnit\Framework\MockObject\Stub\ReturnArgument;
32
use PHPUnit\Framework\MockObject\Stub\ReturnCallback;
33
use PHPUnit\Framework\MockObject\Stub\ReturnReference;
34
use PHPUnit\Framework\MockObject\Stub\ReturnSelf;
35
use PHPUnit\Framework\MockObject\Stub\ReturnStub;
36
use PHPUnit\Framework\MockObject\Stub\ReturnValueMap;
37
use PHPUnit\Framework\MockObject\Stub\Stub;
38
use Throwable;
39
 
40
/**
41
 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
42
 */
43
final class InvocationMocker implements InvocationStubber, MethodNameMatch
44
{
45
    /**
46
     * @var InvocationHandler
47
     */
48
    private $invocationHandler;
49
 
50
    /**
51
     * @var Matcher
52
     */
53
    private $matcher;
54
 
55
    /**
56
     * @var ConfigurableMethod[]
57
     */
58
    private $configurableMethods;
59
 
60
    public function __construct(InvocationHandler $handler, Matcher $matcher, ConfigurableMethod ...$configurableMethods)
61
    {
62
        $this->invocationHandler   = $handler;
63
        $this->matcher             = $matcher;
64
        $this->configurableMethods = $configurableMethods;
65
    }
66
 
67
    /**
68
     * @throws MatcherAlreadyRegisteredException
69
     *
70
     * @return $this
71
     */
72
    public function id($id): self
73
    {
74
        $this->invocationHandler->registerMatcher($id, $this->matcher);
75
 
76
        return $this;
77
    }
78
 
79
    /**
80
     * @return $this
81
     */
82
    public function will(Stub $stub): Identity
83
    {
84
        $this->matcher->setStub($stub);
85
 
86
        return $this;
87
    }
88
 
89
    /**
90
     * @param mixed   $value
91
     * @param mixed[] $nextValues
92
     *
93
     * @throws IncompatibleReturnValueException
94
     */
95
    public function willReturn($value, ...$nextValues): self
96
    {
97
        if (count($nextValues) === 0) {
98
            $this->ensureTypeOfReturnValues([$value]);
99
 
100
            $stub = $value instanceof Stub ? $value : new ReturnStub($value);
101
        } else {
102
            $values = array_merge([$value], $nextValues);
103
 
104
            $this->ensureTypeOfReturnValues($values);
105
 
106
            $stub = new ConsecutiveCalls($values);
107
        }
108
 
109
        return $this->will($stub);
110
    }
111
 
112
    public function willReturnReference(&$reference): self
113
    {
114
        $stub = new ReturnReference($reference);
115
 
116
        return $this->will($stub);
117
    }
118
 
119
    public function willReturnMap(array $valueMap): self
120
    {
121
        $stub = new ReturnValueMap($valueMap);
122
 
123
        return $this->will($stub);
124
    }
125
 
126
    public function willReturnArgument($argumentIndex): self
127
    {
128
        $stub = new ReturnArgument($argumentIndex);
129
 
130
        return $this->will($stub);
131
    }
132
 
133
    public function willReturnCallback($callback): self
134
    {
135
        $stub = new ReturnCallback($callback);
136
 
137
        return $this->will($stub);
138
    }
139
 
140
    public function willReturnSelf(): self
141
    {
142
        $stub = new ReturnSelf;
143
 
144
        return $this->will($stub);
145
    }
146
 
147
    public function willReturnOnConsecutiveCalls(...$values): self
148
    {
149
        $stub = new ConsecutiveCalls($values);
150
 
151
        return $this->will($stub);
152
    }
153
 
154
    public function willThrowException(Throwable $exception): self
155
    {
156
        $stub = new Exception($exception);
157
 
158
        return $this->will($stub);
159
    }
160
 
161
    /**
162
     * @return $this
163
     */
164
    public function after($id): self
165
    {
166
        $this->matcher->setAfterMatchBuilderId($id);
167
 
168
        return $this;
169
    }
170
 
171
    /**
172
     * @param mixed[] $arguments
173
     *
174
     * @throws \PHPUnit\Framework\Exception
175
     * @throws MethodNameNotConfiguredException
176
     * @throws MethodParametersAlreadyConfiguredException
177
     *
178
     * @return $this
179
     */
180
    public function with(...$arguments): self
181
    {
182
        $this->ensureParametersCanBeConfigured();
183
 
184
        $this->matcher->setParametersRule(new Rule\Parameters($arguments));
185
 
186
        return $this;
187
    }
188
 
189
    /**
190
     * @param array ...$arguments
191
     *
192
     * @throws \PHPUnit\Framework\Exception
193
     * @throws MethodNameNotConfiguredException
194
     * @throws MethodParametersAlreadyConfiguredException
195
     *
196
     * @return $this
621 lars 197
     *
198
     * @deprecated
148 lars 199
     */
200
    public function withConsecutive(...$arguments): self
201
    {
202
        $this->ensureParametersCanBeConfigured();
203
 
204
        $this->matcher->setParametersRule(new Rule\ConsecutiveParameters($arguments));
205
 
206
        return $this;
207
    }
208
 
209
    /**
210
     * @throws MethodNameNotConfiguredException
211
     * @throws MethodParametersAlreadyConfiguredException
212
     *
213
     * @return $this
214
     */
215
    public function withAnyParameters(): self
216
    {
217
        $this->ensureParametersCanBeConfigured();
218
 
219
        $this->matcher->setParametersRule(new Rule\AnyParameters);
220
 
221
        return $this;
222
    }
223
 
224
    /**
225
     * @param Constraint|string $constraint
226
     *
227
     * @throws \PHPUnit\Framework\InvalidArgumentException
228
     * @throws MethodCannotBeConfiguredException
229
     * @throws MethodNameAlreadyConfiguredException
230
     *
231
     * @return $this
232
     */
233
    public function method($constraint): self
234
    {
235
        if ($this->matcher->hasMethodNameRule()) {
236
            throw new MethodNameAlreadyConfiguredException;
237
        }
238
 
239
        $configurableMethodNames = array_map(
240
            static function (ConfigurableMethod $configurable)
241
            {
242
                return strtolower($configurable->getName());
243
            },
244
            $this->configurableMethods
245
        );
246
 
247
        if (is_string($constraint) && !in_array(strtolower($constraint), $configurableMethodNames, true)) {
248
            throw new MethodCannotBeConfiguredException($constraint);
249
        }
250
 
251
        $this->matcher->setMethodNameRule(new Rule\MethodName($constraint));
252
 
253
        return $this;
254
    }
255
 
256
    /**
257
     * @throws MethodNameNotConfiguredException
258
     * @throws MethodParametersAlreadyConfiguredException
259
     */
260
    private function ensureParametersCanBeConfigured(): void
261
    {
262
        if (!$this->matcher->hasMethodNameRule()) {
263
            throw new MethodNameNotConfiguredException;
264
        }
265
 
266
        if ($this->matcher->hasParametersRule()) {
267
            throw new MethodParametersAlreadyConfiguredException;
268
        }
269
    }
270
 
271
    private function getConfiguredMethod(): ?ConfigurableMethod
272
    {
273
        $configuredMethod = null;
274
 
275
        foreach ($this->configurableMethods as $configurableMethod) {
276
            if ($this->matcher->getMethodNameRule()->matchesName($configurableMethod->getName())) {
277
                if ($configuredMethod !== null) {
278
                    return null;
279
                }
280
 
281
                $configuredMethod = $configurableMethod;
282
            }
283
        }
284
 
285
        return $configuredMethod;
286
    }
287
 
288
    /**
289
     * @throws IncompatibleReturnValueException
290
     */
291
    private function ensureTypeOfReturnValues(array $values): void
292
    {
293
        $configuredMethod = $this->getConfiguredMethod();
294
 
295
        if ($configuredMethod === null) {
296
            return;
297
        }
298
 
299
        foreach ($values as $value) {
300
            if (!$configuredMethod->mayReturn($value)) {
301
                throw new IncompatibleReturnValueException(
302
                    $configuredMethod,
303
                    $value
304
                );
305
            }
306
        }
307
    }
308
}