Mercurial > hg > isophonics-drupal-site
comparison vendor/phpunit/phpunit-mock-objects/src/Invocation/StaticInvocation.php @ 14:1fec387a4317
Update Drupal core to 8.5.2 via Composer
author | Chris Cannam |
---|---|
date | Mon, 23 Apr 2018 09:46:53 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
13:5fb285c0d0e3 | 14:1fec387a4317 |
---|---|
1 <?php | |
2 /* | |
3 * This file is part of the phpunit-mock-objects package. | |
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\Invocation; | |
11 | |
12 use PHPUnit\Framework\MockObject\Generator; | |
13 use PHPUnit\Framework\MockObject\Invocation; | |
14 use PHPUnit\Framework\SelfDescribing; | |
15 use ReflectionObject; | |
16 use SebastianBergmann\Exporter\Exporter; | |
17 | |
18 /** | |
19 * Represents a static invocation. | |
20 */ | |
21 class StaticInvocation implements Invocation, SelfDescribing | |
22 { | |
23 /** | |
24 * @var array | |
25 */ | |
26 private static $uncloneableExtensions = [ | |
27 'mysqli' => true, | |
28 'SQLite' => true, | |
29 'sqlite3' => true, | |
30 'tidy' => true, | |
31 'xmlwriter' => true, | |
32 'xsl' => true | |
33 ]; | |
34 | |
35 /** | |
36 * @var array | |
37 */ | |
38 private static $uncloneableClasses = [ | |
39 'Closure', | |
40 'COMPersistHelper', | |
41 'IteratorIterator', | |
42 'RecursiveIteratorIterator', | |
43 'SplFileObject', | |
44 'PDORow', | |
45 'ZipArchive' | |
46 ]; | |
47 | |
48 /** | |
49 * @var string | |
50 */ | |
51 private $className; | |
52 | |
53 /** | |
54 * @var string | |
55 */ | |
56 private $methodName; | |
57 | |
58 /** | |
59 * @var array | |
60 */ | |
61 private $parameters; | |
62 | |
63 /** | |
64 * @var string | |
65 */ | |
66 private $returnType; | |
67 | |
68 /** | |
69 * @var bool | |
70 */ | |
71 private $isReturnTypeNullable = false; | |
72 | |
73 /** | |
74 * @param string $className | |
75 * @param string $methodName | |
76 * @param array $parameters | |
77 * @param string $returnType | |
78 * @param bool $cloneObjects | |
79 */ | |
80 public function __construct($className, $methodName, array $parameters, $returnType, $cloneObjects = false) | |
81 { | |
82 $this->className = $className; | |
83 $this->methodName = $methodName; | |
84 $this->parameters = $parameters; | |
85 | |
86 if (\strpos($returnType, '?') === 0) { | |
87 $returnType = \substr($returnType, 1); | |
88 $this->isReturnTypeNullable = true; | |
89 } | |
90 | |
91 $this->returnType = $returnType; | |
92 | |
93 if (!$cloneObjects) { | |
94 return; | |
95 } | |
96 | |
97 foreach ($this->parameters as $key => $value) { | |
98 if (\is_object($value)) { | |
99 $this->parameters[$key] = $this->cloneObject($value); | |
100 } | |
101 } | |
102 } | |
103 | |
104 public function getClassName(): string | |
105 { | |
106 return $this->className; | |
107 } | |
108 | |
109 public function getMethodName(): string | |
110 { | |
111 return $this->methodName; | |
112 } | |
113 | |
114 public function getParameters(): array | |
115 { | |
116 return $this->parameters; | |
117 } | |
118 | |
119 public function getReturnType(): string | |
120 { | |
121 return $this->returnType; | |
122 } | |
123 | |
124 public function isReturnTypeNullable(): bool | |
125 { | |
126 return $this->isReturnTypeNullable; | |
127 } | |
128 | |
129 /** | |
130 * @return mixed Mocked return value | |
131 * | |
132 * @throws \ReflectionException | |
133 * @throws \PHPUnit\Framework\MockObject\RuntimeException | |
134 * @throws \PHPUnit\Framework\Exception | |
135 */ | |
136 public function generateReturnValue() | |
137 { | |
138 if ($this->isReturnTypeNullable) { | |
139 return; | |
140 } | |
141 | |
142 switch (\strtolower($this->returnType)) { | |
143 case '': | |
144 case 'void': | |
145 return; | |
146 | |
147 case 'string': | |
148 return ''; | |
149 | |
150 case 'float': | |
151 return 0.0; | |
152 | |
153 case 'int': | |
154 return 0; | |
155 | |
156 case 'bool': | |
157 return false; | |
158 | |
159 case 'array': | |
160 return []; | |
161 | |
162 case 'object': | |
163 return new \stdClass; | |
164 | |
165 case 'callable': | |
166 case 'closure': | |
167 return function () { | |
168 }; | |
169 | |
170 case 'traversable': | |
171 case 'generator': | |
172 case 'iterable': | |
173 $generator = function () { | |
174 yield; | |
175 }; | |
176 | |
177 return $generator(); | |
178 | |
179 default: | |
180 $generator = new Generator; | |
181 | |
182 return $generator->getMock($this->returnType, [], [], '', false); | |
183 } | |
184 } | |
185 | |
186 public function toString(): string | |
187 { | |
188 $exporter = new Exporter; | |
189 | |
190 return \sprintf( | |
191 '%s::%s(%s)%s', | |
192 $this->className, | |
193 $this->methodName, | |
194 \implode( | |
195 ', ', | |
196 \array_map( | |
197 [$exporter, 'shortenedExport'], | |
198 $this->parameters | |
199 ) | |
200 ), | |
201 $this->returnType ? \sprintf(': %s', $this->returnType) : '' | |
202 ); | |
203 } | |
204 | |
205 /** | |
206 * @param object $original | |
207 * | |
208 * @return object | |
209 */ | |
210 private function cloneObject($original) | |
211 { | |
212 $cloneable = null; | |
213 $object = new ReflectionObject($original); | |
214 | |
215 // Check the blacklist before asking PHP reflection to work around | |
216 // https://bugs.php.net/bug.php?id=53967 | |
217 if ($object->isInternal() && | |
218 isset(self::$uncloneableExtensions[$object->getExtensionName()])) { | |
219 $cloneable = false; | |
220 } | |
221 | |
222 if ($cloneable === null) { | |
223 foreach (self::$uncloneableClasses as $class) { | |
224 if ($original instanceof $class) { | |
225 $cloneable = false; | |
226 | |
227 break; | |
228 } | |
229 } | |
230 } | |
231 | |
232 if ($cloneable === null) { | |
233 $cloneable = $object->isCloneable(); | |
234 } | |
235 | |
236 if ($cloneable === null && $object->hasMethod('__clone')) { | |
237 $method = $object->getMethod('__clone'); | |
238 $cloneable = $method->isPublic(); | |
239 } | |
240 | |
241 if ($cloneable === null) { | |
242 $cloneable = true; | |
243 } | |
244 | |
245 if ($cloneable) { | |
246 try { | |
247 return clone $original; | |
248 } catch (\Exception $e) { | |
249 return $original; | |
250 } | |
251 } else { | |
252 return $original; | |
253 } | |
254 } | |
255 } |