Mercurial > hg > isophonics-drupal-site
comparison core/lib/Drupal/Component/Assertion/Inspector.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 1fec387a4317 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Component\Assertion; | |
4 | |
5 use Traversable; | |
6 | |
7 /** | |
8 * Generic inspections for the assert() statement. | |
9 * | |
10 * This is a static function collection for inspecting variable contents. All | |
11 * functions in this collection check a variable against an assertion about its | |
12 * structure. | |
13 * | |
14 * Example call: | |
15 * @code | |
16 * assert('Drupal\\Component\\Assertion\\Inspector::assertAllStrings($array)'); | |
17 * @endcode | |
18 * | |
19 * @ingroup php_assert | |
20 */ | |
21 class Inspector { | |
22 | |
23 /** | |
24 * Asserts argument can be traversed with foreach. | |
25 * | |
26 * @param mixed $traversable | |
27 * Variable to be examined. | |
28 * | |
29 * @return bool | |
30 * TRUE if $traversable can be traversed with foreach. | |
31 */ | |
32 public static function assertTraversable($traversable) { | |
33 return is_array($traversable) || $traversable instanceof Traversable; | |
34 } | |
35 | |
36 /** | |
37 * Asserts callback returns TRUE for each member of a traversable. | |
38 * | |
39 * This is less memory intensive than using array_filter() to build a second | |
40 * array and then comparing the arrays. Many of the other functions in this | |
41 * collection alias this function passing a specific callback to make the | |
42 * code more readable. | |
43 * | |
44 * @param callable $callable | |
45 * Callback function. | |
46 * @param mixed $traversable | |
47 * Variable to be examined. | |
48 * | |
49 * @return bool | |
50 * TRUE if $traversable can be traversed and $callable returns TRUE on | |
51 * all members. | |
52 * | |
53 * @see http://php.net/manual/language.types.callable.php | |
54 */ | |
55 public static function assertAll(callable $callable, $traversable) { | |
56 if (static::assertTraversable($traversable)) { | |
57 foreach ($traversable as $member) { | |
58 if (!$callable($member)) { | |
59 return FALSE; | |
60 } | |
61 } | |
62 return TRUE; | |
63 } | |
64 return FALSE; | |
65 } | |
66 | |
67 /** | |
68 * Asserts that all members are strings. | |
69 * | |
70 * Use this only if it is vital that the members not be objects, otherwise | |
71 * test with ::assertAllStringable(). | |
72 * | |
73 * @param mixed $traversable | |
74 * Variable to be examined. | |
75 * | |
76 * @return bool | |
77 * TRUE if $traversable can be traversed and all members are strings. | |
78 */ | |
79 public static function assertAllStrings($traversable) { | |
80 return static::assertAll('is_string', $traversable); | |
81 } | |
82 | |
83 /** | |
84 * Asserts all members are strings or objects with magic __toString() method. | |
85 * | |
86 * @param mixed $traversable | |
87 * Variable to be examined. | |
88 * | |
89 * @return bool | |
90 * TRUE if $traversable can be traversed and all members are strings or | |
91 * objects with __toString(). | |
92 */ | |
93 public static function assertAllStringable($traversable) { | |
94 if (static::assertTraversable($traversable)) { | |
95 foreach ($traversable as $member) { | |
96 if (!static::assertStringable($member)) { | |
97 return FALSE; | |
98 } | |
99 } | |
100 return TRUE; | |
101 } | |
102 return FALSE; | |
103 } | |
104 | |
105 /** | |
106 * Asserts argument is a string or an object castable to a string. | |
107 * | |
108 * Use this instead of is_string() alone unless the argument being an object | |
109 * in any way will cause a problem. | |
110 * | |
111 * @param mixed $string | |
112 * Variable to be examined | |
113 * | |
114 * @return bool | |
115 * TRUE if $string is a string or an object castable to a string. | |
116 */ | |
117 public static function assertStringable($string) { | |
118 return is_string($string) || (is_object($string) && method_exists($string, '__toString')); | |
119 } | |
120 | |
121 /** | |
122 * Asserts that all members are arrays. | |
123 * | |
124 * @param mixed $traversable | |
125 * Variable to be examined. | |
126 * | |
127 * @return bool | |
128 * TRUE if $traversable can be traversed and all members are arrays. | |
129 */ | |
130 public static function assertAllArrays($traversable) { | |
131 return static::assertAll('is_array', $traversable); | |
132 } | |
133 | |
134 /** | |
135 * Asserts that the array is strict. | |
136 * | |
137 * What PHP calls arrays are more formally called maps in most other | |
138 * programming languages. A map is a datatype that associates values to keys. | |
139 * The term 'strict array' here refers to a 0-indexed array in the classic | |
140 * sense found in programming languages other than PHP. | |
141 * | |
142 * @param mixed $array | |
143 * Variable to be examined. | |
144 * | |
145 * @return bool | |
146 * TRUE if $traversable is a 0-indexed array. | |
147 * | |
148 * @see http://php.net/manual/language.types.array.php | |
149 */ | |
150 public static function assertStrictArray($array) { | |
151 if (!is_array($array)) { | |
152 return FALSE; | |
153 } | |
154 $i = 0; | |
155 | |
156 foreach (array_keys($array) as $key) { | |
157 if ($i !== $key) { | |
158 return FALSE; | |
159 } | |
160 $i++; | |
161 } | |
162 return TRUE; | |
163 } | |
164 | |
165 /** | |
166 * Asserts all members are strict arrays. | |
167 * | |
168 * @param mixed $traversable | |
169 * Variable to be examined. | |
170 * | |
171 * @return bool | |
172 * TRUE if $traversable can be traversed and all members are strict arrays. | |
173 * | |
174 * @see ::assertStrictArray | |
175 */ | |
176 public static function assertAllStrictArrays($traversable) { | |
177 return static::assertAll([__CLASS__, 'assertStrictArray'], $traversable); | |
178 } | |
179 | |
180 /** | |
181 * Asserts all given keys exist in every member array. | |
182 * | |
183 * Drupal has several data structure arrays that require certain keys be set. | |
184 * You can overload this function to specify a list of required keys. All | |
185 * of the keys must be set for this method to return TRUE. | |
186 * | |
187 * As an example, this assertion tests for the keys of a theme registry. | |
188 * | |
189 * @code | |
190 * assert('Drupal\\Component\\Assertion\\Inspector::assertAllHaveKey( | |
191 * $arrayToTest, "type", "theme path", "function", "template", "variables", "render element", "preprocess functions")'); | |
192 * @endcode | |
193 * | |
194 * Note: If a method requires certain keys to be present it will usually be | |
195 * specific about the data types for the values of those keys. Therefore it | |
196 * will be best to write a specific test for it. Such tests are either bound | |
197 * to the object that uses them, or are collected into one assertion set for | |
198 * the package. | |
199 * | |
200 * @param mixed $traversable | |
201 * Variable to be examined. | |
202 * @param string ... | |
203 * Keys to be searched for. | |
204 * | |
205 * @return bool | |
206 * TRUE if $traversable can be traversed and all members have all keys. | |
207 */ | |
208 public static function assertAllHaveKey($traversable) { | |
209 $args = func_get_args(); | |
210 unset($args[0]); | |
211 | |
212 if (static::assertTraversable($traversable)) { | |
213 foreach ($traversable as $member) { | |
214 foreach ($args as $key) { | |
215 if (!array_key_exists($key, $member)) { | |
216 return FALSE; | |
217 } | |
218 } | |
219 } | |
220 return TRUE; | |
221 } | |
222 return FALSE; | |
223 } | |
224 | |
225 /** | |
226 * Asserts that all members are integer values. | |
227 * | |
228 * @param mixed $traversable | |
229 * Variable to be examined. | |
230 * | |
231 * @return bool | |
232 * TRUE if $traversable can be traversed and all members are integers. | |
233 */ | |
234 public static function assertAllIntegers($traversable) { | |
235 return static::assertAll('is_int', $traversable); | |
236 } | |
237 | |
238 /** | |
239 * Asserts that all members are float values. | |
240 * | |
241 * @param mixed $traversable | |
242 * Variable to be examined. | |
243 * | |
244 * @return bool | |
245 * TRUE if $traversable can be traversed and all members are floating point | |
246 * numbers. | |
247 */ | |
248 public static function assertAllFloat($traversable) { | |
249 return static::assertAll('is_float', $traversable); | |
250 } | |
251 | |
252 /** | |
253 * Asserts that all members are callable. | |
254 * | |
255 * @param mixed $traversable | |
256 * Variable to be examined. | |
257 * | |
258 * @return bool | |
259 * TRUE if $traversable can be traversed and all members are callable. | |
260 */ | |
261 public static function assertAllCallable($traversable) { | |
262 return static::assertAll('is_callable', $traversable); | |
263 } | |
264 | |
265 /** | |
266 * Asserts that all members are not empty. | |
267 * | |
268 * @param mixed $traversable | |
269 * Variable to be examined. | |
270 * | |
271 * @return bool | |
272 * TRUE if $traversable can be traversed and all members not empty. | |
273 */ | |
274 public static function assertAllNotEmpty($traversable) { | |
275 if (static::assertTraversable($traversable)) { | |
276 foreach ($traversable as $member) { | |
277 if (empty($member)) { | |
278 return FALSE; | |
279 } | |
280 } | |
281 return TRUE; | |
282 } | |
283 return FALSE; | |
284 } | |
285 | |
286 /** | |
287 * Asserts all members are numeric data types or strings castable to such. | |
288 * | |
289 * @param mixed $traversable | |
290 * Variable to be examined. | |
291 * | |
292 * @return bool | |
293 * TRUE if $traversable can be traversed and all members are numeric. | |
294 */ | |
295 public static function assertAllNumeric($traversable) { | |
296 return static::assertAll('is_numeric', $traversable); | |
297 } | |
298 | |
299 /** | |
300 * Asserts that all members are strings that contain the specified string. | |
301 * | |
302 * This runs faster than the regular expression equivalent. | |
303 * | |
304 * @param string $pattern | |
305 * The needle to find. | |
306 * @param mixed $traversable | |
307 * Variable to examine. | |
308 * @param bool $case_sensitive | |
309 * TRUE to use strstr(), FALSE to use stristr() which is case insensitive. | |
310 * | |
311 * @return bool | |
312 * TRUE if $traversable can be traversed and all members are strings | |
313 * containing $pattern. | |
314 */ | |
315 public static function assertAllMatch($pattern, $traversable, $case_sensitive = FALSE) { | |
316 if (static::assertTraversable($traversable)) { | |
317 if ($case_sensitive) { | |
318 foreach ($traversable as $member) { | |
319 if (!(is_string($member) && strstr($member, $pattern))) { | |
320 return FALSE; | |
321 } | |
322 } | |
323 } | |
324 else { | |
325 foreach ($traversable as $member) { | |
326 if (!(is_string($member) && stristr($member, $pattern))) { | |
327 return FALSE; | |
328 } | |
329 } | |
330 } | |
331 return TRUE; | |
332 } | |
333 return FALSE; | |
334 } | |
335 | |
336 | |
337 /** | |
338 * Asserts that all members are strings matching a regular expression. | |
339 * | |
340 * @param string $pattern | |
341 * Regular expression string to find. | |
342 * @param mixed $traversable | |
343 * Variable to be examined. | |
344 * | |
345 * @return bool | |
346 * TRUE if $traversable can be traversed and all members are strings | |
347 * matching $pattern. | |
348 */ | |
349 public static function assertAllRegularExpressionMatch($pattern, $traversable) { | |
350 if (static::assertTraversable($traversable)) { | |
351 foreach ($traversable as $member) { | |
352 if (!is_string($member)) { | |
353 return FALSE; | |
354 } | |
355 | |
356 if (!preg_match($pattern, $member)) { | |
357 return FALSE; | |
358 } | |
359 } | |
360 return TRUE; | |
361 } | |
362 return FALSE; | |
363 } | |
364 | |
365 /** | |
366 * Asserts that all members are objects. | |
367 * | |
368 * When testing if a collection is composed of objects those objects should | |
369 * be given a common interface to implement and the test should be written to | |
370 * search for just that interface. While this method will allow tests for | |
371 * just object status or for multiple classes and interfaces this was done to | |
372 * allow tests to be written for existing code without altering it. Only use | |
373 * this method in that manner when testing code from third party vendors. | |
374 * | |
375 * Here are some examples: | |
376 * @code | |
377 * // Just test all are objects, like a cache. | |
378 * assert('Drupal\\Component\\Assertion\\Inspector::assertAllObjects( | |
379 * $collection'); | |
380 * | |
381 * // Test if traversable objects (arrays won't pass this) | |
382 * assert('Drupal\\Component\\Assertion\\Inspector::assertAllObjects( | |
383 * $collection', \'\\Traversable\'); | |
384 * | |
385 * // Test for the Foo class or Bar\None interface | |
386 * assert('Drupal\\Component\\Assertion\\Inspector::assertAllObjects( | |
387 * $collection', \'\\Foo\', \'\\Bar\\None\''); | |
388 * @endcode | |
389 * | |
390 * @param mixed $traversable | |
391 * Variable to be examined. | |
392 * @param string ... | |
393 * Classes and interfaces to test objects against. | |
394 * | |
395 * @return bool | |
396 * TRUE if $traversable can be traversed and all members are objects with | |
397 * at least one of the listed classes or interfaces. | |
398 */ | |
399 public static function assertAllObjects($traversable) { | |
400 $args = func_get_args(); | |
401 unset($args[0]); | |
402 | |
403 if (static::assertTraversable($traversable)) { | |
404 foreach ($traversable as $member) { | |
405 if (count($args) > 0) { | |
406 foreach ($args as $instance) { | |
407 if ($member instanceof $instance) { | |
408 // We're continuing to the next member on the outer loop. | |
409 // @see http://php.net/continue | |
410 continue 2; | |
411 } | |
412 } | |
413 return FALSE; | |
414 } | |
415 elseif (!is_object($member)) { | |
416 return FALSE; | |
417 } | |
418 } | |
419 return TRUE; | |
420 } | |
421 return FALSE; | |
422 } | |
423 | |
424 } |