3 namespace Drupal\Component\Assertion;
8 * Generic inspections for the assert() statement.
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
16 * assert('Drupal\\Component\\Assertion\\Inspector::assertAllStrings($array)');
24 * Asserts argument can be traversed with foreach.
26 * @param mixed $traversable
27 * Variable to be examined.
30 * TRUE if $traversable can be traversed with foreach.
32 public static function assertTraversable($traversable) {
33 return is_array($traversable) || $traversable instanceof Traversable;
37 * Asserts callback returns TRUE for each member of a traversable.
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
44 * @param callable $callable
46 * @param mixed $traversable
47 * Variable to be examined.
50 * TRUE if $traversable can be traversed and $callable returns TRUE on
53 * @see http://php.net/manual/language.types.callable.php
55 public static function assertAll(callable $callable, $traversable) {
56 if (static::assertTraversable($traversable)) {
57 foreach ($traversable as $member) {
58 if (!$callable($member)) {
68 * Asserts that all members are strings.
70 * Use this only if it is vital that the members not be objects, otherwise
71 * test with ::assertAllStringable().
73 * @param mixed $traversable
74 * Variable to be examined.
77 * TRUE if $traversable can be traversed and all members are strings.
79 public static function assertAllStrings($traversable) {
80 return static::assertAll('is_string', $traversable);
84 * Asserts all members are strings or objects with magic __toString() method.
86 * @param mixed $traversable
87 * Variable to be examined.
90 * TRUE if $traversable can be traversed and all members are strings or
91 * objects with __toString().
93 public static function assertAllStringable($traversable) {
94 if (static::assertTraversable($traversable)) {
95 foreach ($traversable as $member) {
96 if (!static::assertStringable($member)) {
106 * Asserts argument is a string or an object castable to a string.
108 * Use this instead of is_string() alone unless the argument being an object
109 * in any way will cause a problem.
111 * @param mixed $string
112 * Variable to be examined
115 * TRUE if $string is a string or an object castable to a string.
117 public static function assertStringable($string) {
118 return is_string($string) || (is_object($string) && method_exists($string, '__toString'));
122 * Asserts that all members are arrays.
124 * @param mixed $traversable
125 * Variable to be examined.
128 * TRUE if $traversable can be traversed and all members are arrays.
130 public static function assertAllArrays($traversable) {
131 return static::assertAll('is_array', $traversable);
135 * Asserts that the array is strict.
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.
142 * @param mixed $array
143 * Variable to be examined.
146 * TRUE if $traversable is a 0-indexed array.
148 * @see http://php.net/manual/language.types.array.php
150 public static function assertStrictArray($array) {
151 if (!is_array($array)) {
156 foreach (array_keys($array) as $key) {
166 * Asserts all members are strict arrays.
168 * @param mixed $traversable
169 * Variable to be examined.
172 * TRUE if $traversable can be traversed and all members are strict arrays.
174 * @see ::assertStrictArray
176 public static function assertAllStrictArrays($traversable) {
177 return static::assertAll([__CLASS__, 'assertStrictArray'], $traversable);
181 * Asserts all given keys exist in every member array.
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.
187 * As an example, this assertion tests for the keys of a theme registry.
190 * assert('Drupal\\Component\\Assertion\\Inspector::assertAllHaveKey(
191 * $arrayToTest, "type", "theme path", "function", "template", "variables", "render element", "preprocess functions")');
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
200 * @param mixed $traversable
201 * Variable to be examined.
203 * Keys to be searched for.
206 * TRUE if $traversable can be traversed and all members have all keys.
208 public static function assertAllHaveKey() {
209 $args = func_get_args();
210 $traversable = array_shift($args);
212 if (static::assertTraversable($traversable)) {
213 foreach ($traversable as $member) {
214 foreach ($args as $key) {
215 if (!array_key_exists($key, $member)) {
226 * Asserts that all members are integer values.
228 * @param mixed $traversable
229 * Variable to be examined.
232 * TRUE if $traversable can be traversed and all members are integers.
234 public static function assertAllIntegers($traversable) {
235 return static::assertAll('is_int', $traversable);
239 * Asserts that all members are float values.
241 * @param mixed $traversable
242 * Variable to be examined.
245 * TRUE if $traversable can be traversed and all members are floating point
248 public static function assertAllFloat($traversable) {
249 return static::assertAll('is_float', $traversable);
253 * Asserts that all members are callable.
255 * @param mixed $traversable
256 * Variable to be examined.
259 * TRUE if $traversable can be traversed and all members are callable.
261 public static function assertAllCallable($traversable) {
262 return static::assertAll('is_callable', $traversable);
266 * Asserts that all members are not empty.
268 * @param mixed $traversable
269 * Variable to be examined.
272 * TRUE if $traversable can be traversed and all members not empty.
274 public static function assertAllNotEmpty($traversable) {
275 if (static::assertTraversable($traversable)) {
276 foreach ($traversable as $member) {
277 if (empty($member)) {
287 * Asserts all members are numeric data types or strings castable to such.
289 * @param mixed $traversable
290 * Variable to be examined.
293 * TRUE if $traversable can be traversed and all members are numeric.
295 public static function assertAllNumeric($traversable) {
296 return static::assertAll('is_numeric', $traversable);
300 * Asserts that all members are strings that contain the specified string.
302 * This runs faster than the regular expression equivalent.
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.
312 * TRUE if $traversable can be traversed and all members are strings
313 * containing $pattern.
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))) {
325 foreach ($traversable as $member) {
326 if (!(is_string($member) && stristr($member, $pattern))) {
338 * Asserts that all members are strings matching a regular expression.
340 * @param string $pattern
341 * Regular expression string to find.
342 * @param mixed $traversable
343 * Variable to be examined.
346 * TRUE if $traversable can be traversed and all members are strings
349 public static function assertAllRegularExpressionMatch($pattern, $traversable) {
350 if (static::assertTraversable($traversable)) {
351 foreach ($traversable as $member) {
352 if (!is_string($member)) {
356 if (!preg_match($pattern, $member)) {
366 * Asserts that all members are objects.
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.
375 * Here are some examples:
377 * // Just test all are objects, like a cache.
378 * assert('Drupal\\Component\\Assertion\\Inspector::assertAllObjects(
381 * // Test if traversable objects (arrays won't pass this)
382 * assert('Drupal\\Component\\Assertion\\Inspector::assertAllObjects(
383 * $collection', \'\\Traversable\');
385 * // Test for the Foo class or Bar\None interface
386 * assert('Drupal\\Component\\Assertion\\Inspector::assertAllObjects(
387 * $collection', \'\\Foo\', \'\\Bar\\None\'');
390 * @param mixed $traversable
391 * Variable to be examined.
393 * Classes and interfaces to test objects against.
396 * TRUE if $traversable can be traversed and all members are objects with
397 * at least one of the listed classes or interfaces.
399 public static function assertAllObjects() {
400 $args = func_get_args();
401 $traversable = array_shift($args);
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
415 elseif (!is_object($member)) {