This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
Checks whether a method/function call has too many arguments.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | declare(strict_types=1); |
||
3 | |||
4 | namespace Moka\Strategy; |
||
5 | |||
6 | use Moka\Exception\InvalidArgumentException; |
||
7 | use Moka\Exception\MissingDependencyException; |
||
8 | use Moka\Exception\MockNotCreatedException; |
||
9 | use Moka\Exception\NotImplementedException; |
||
10 | use function Moka\Factory\buildStubs; |
||
11 | use Moka\Factory\StubFactory; |
||
12 | use Moka\Stub\MethodStub; |
||
13 | use Moka\Stub\PropertyStub; |
||
14 | use Moka\Stub\StubInterface; |
||
15 | use Moka\Stub\StubSet; |
||
16 | |||
17 | /** |
||
18 | * Class AbstractMockingStrategy |
||
19 | * @package Moka\Strategy |
||
20 | */ |
||
21 | abstract class AbstractMockingStrategy implements MockingStrategyInterface |
||
22 | { |
||
23 | /** |
||
24 | * @var string |
||
25 | */ |
||
26 | private $mockType; |
||
27 | |||
28 | /** |
||
29 | * @param string $dependencyClassName |
||
30 | * @param string $dependencyPackageName |
||
31 | * |
||
32 | * @throws MissingDependencyException |
||
33 | */ |
||
34 | 10 | final protected static function checkDependencies(string $dependencyClassName, string $dependencyPackageName) |
|
35 | { |
||
36 | 10 | if (!class_exists($dependencyClassName)) { |
|
37 | 1 | throw new MissingDependencyException( |
|
38 | 1 | sprintf( |
|
39 | 1 | 'Class "%s" does not exist, please install package "%s"', |
|
40 | $dependencyClassName, |
||
41 | $dependencyPackageName |
||
42 | ) |
||
43 | ); |
||
44 | } |
||
45 | } |
||
46 | |||
47 | /** |
||
48 | * @param string $fqcn |
||
49 | * @return object |
||
50 | * |
||
51 | * @throws MockNotCreatedException |
||
52 | */ |
||
53 | 89 | public function build(string $fqcn) |
|
54 | { |
||
55 | try { |
||
56 | 89 | return $this->doBuild($fqcn); |
|
57 | 1 | } catch (\Throwable $exception) { |
|
58 | 1 | throw new MockNotCreatedException( |
|
59 | 1 | sprintf( |
|
60 | 1 | 'Cannot create mock object for FQCN "%s": %s', |
|
61 | $fqcn, |
||
62 | 1 | $exception->getMessage() |
|
63 | ) |
||
64 | ); |
||
65 | } |
||
66 | } |
||
67 | |||
68 | /** |
||
69 | * @param object $mock |
||
70 | * @param StubInterface[] $stubs |
||
71 | * @return void |
||
72 | * |
||
73 | * @throws InvalidArgumentException |
||
74 | * @throws NotImplementedException |
||
75 | * @throws \LogicException |
||
76 | */ |
||
77 | 80 | public function decorate($mock, array $stubs): void |
|
78 | { |
||
79 | 80 | $this->checkMockType($mock); |
|
80 | |||
81 | 80 | $stubs = buildStubs($stubs); |
|
82 | |||
83 | 80 | foreach ($stubs as $stub) { |
|
84 | 80 | if ($stub instanceof PropertyStub) { |
|
85 | 80 | $this->doDecorateWithProperty($mock, $stub); |
|
86 | } |
||
87 | |||
88 | 80 | if ($stub instanceof MethodStub) { |
|
89 | 80 | $this->doDecorateWithMethod($mock, $stub); |
|
90 | } |
||
91 | } |
||
92 | } |
||
93 | |||
94 | /** |
||
95 | * @param object $mock |
||
96 | * @return object |
||
97 | * |
||
98 | * @throws NotImplementedException |
||
99 | * @throws InvalidArgumentException |
||
100 | */ |
||
101 | 72 | public function get($mock) |
|
102 | { |
||
103 | 72 | $this->checkMockType($mock); |
|
104 | |||
105 | 68 | return $this->doGet($mock); |
|
106 | } |
||
107 | |||
108 | /** |
||
109 | * @param object $mock |
||
110 | * @param string $methodName |
||
111 | * @return mixed |
||
112 | * |
||
113 | * @throws NotImplementedException |
||
114 | * @throws InvalidArgumentException |
||
115 | * @throws \Error |
||
116 | */ |
||
117 | 3 | public function call($mock, string $methodName) |
|
118 | { |
||
119 | 3 | $this->checkMockType($mock); |
|
120 | |||
121 | 3 | return $this->doCall($mock, $methodName); |
|
122 | } |
||
123 | |||
124 | /** |
||
125 | * @return string |
||
126 | * |
||
127 | * @throws NotImplementedException |
||
128 | */ |
||
129 | 25 | public function getMockType(): string |
|
130 | { |
||
131 | 25 | $this->verifyMockType(); |
|
132 | |||
133 | 24 | return $this->mockType; |
|
134 | } |
||
135 | |||
136 | /** |
||
137 | * @param string $fqcn |
||
138 | */ |
||
139 | 11 | final protected function setMockType(string $fqcn) |
|
140 | { |
||
141 | 11 | $this->mockType = $fqcn; |
|
142 | } |
||
143 | |||
144 | /** |
||
145 | * @param object $mock |
||
146 | * |
||
147 | * @throws NotImplementedException |
||
148 | * @throws InvalidArgumentException |
||
149 | */ |
||
150 | 89 | final protected function checkMockType($mock) |
|
151 | { |
||
152 | 89 | $this->verifyMockType(); |
|
153 | |||
154 | 89 | if (!is_a($mock, $this->mockType)) { |
|
155 | 8 | throw new InvalidArgumentException( |
|
156 | 8 | sprintf( |
|
157 | 8 | 'Mock object must be an instance of "%s", "%s" given', |
|
158 | 8 | $this->mockType, |
|
159 | 8 | \gettype($mock) |
|
160 | ) |
||
161 | ); |
||
162 | } |
||
163 | } |
||
164 | |||
165 | /** |
||
166 | * @return void |
||
167 | * |
||
168 | * @throws NotImplementedException |
||
169 | */ |
||
170 | 90 | private function verifyMockType(): void |
|
171 | { |
||
172 | 90 | if (!$this->mockType) { |
|
173 | 1 | throw new NotImplementedException('Mock type was not defined'); |
|
174 | } |
||
175 | } |
||
176 | |||
177 | /** |
||
178 | * @param string $fqcn |
||
179 | * @return object |
||
180 | */ |
||
181 | abstract protected function doBuild(string $fqcn); |
||
182 | |||
183 | /** |
||
184 | * @param object $mock |
||
185 | * @param PropertyStub $stub |
||
186 | * @return void |
||
187 | */ |
||
188 | 80 | protected function doDecorateWithProperty($mock, PropertyStub $stub): void |
|
189 | { |
||
190 | 80 | $mock->{$stub->getName()} = $stub->getValue(); |
|
191 | } |
||
192 | |||
193 | /** |
||
194 | * @param object $mock |
||
195 | * @param MethodStub $stub |
||
196 | * @return void |
||
197 | */ |
||
198 | abstract protected function doDecorateWithMethod($mock, MethodStub $stub): void; |
||
199 | |||
200 | /** |
||
201 | * @param object $mock |
||
202 | * @return object |
||
203 | */ |
||
204 | abstract protected function doGet($mock); |
||
205 | |||
206 | /** |
||
207 | * @param object $mock |
||
208 | * @param string $methodName |
||
209 | * @return mixed |
||
210 | * @throws \Error |
||
211 | */ |
||
212 | 1 | protected function doCall($mock, string $methodName) |
|
213 | { |
||
214 | 1 | throw new \Error( |
|
215 | 1 | sprintf( |
|
0 ignored issues
–
show
|
|||
216 | 1 | 'Undefined property: %s::$%s', |
|
217 | 1 | \get_class($this), |
|
218 | $methodName |
||
219 | ) |
||
220 | ); |
||
221 | } |
||
222 | } |
||
223 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.