f0387eadb28e59024506d9e2c3dabbeda224e89a
[yaffs-website] / web / core / modules / views / src / Tests / ViewResultAssertionTrait.php
1 <?php
2
3 namespace Drupal\views\Tests;
4
5 use Drupal\views\Plugin\views\field\EntityField;
6
7 /**
8  * Provides a class for assertions to check for the expected result of a View.
9  */
10 trait ViewResultAssertionTrait {
11
12   /**
13    * Verifies that a result set returned by a View matches expected values.
14    *
15    * The comparison is done on the string representation of the columns of the
16    * column map, taking the order of the rows into account, but not the order
17    * of the columns.
18    *
19    * @param \Drupal\views\ViewExecutable $view
20    *   An executed View.
21    * @param array $expected_result
22    *   An expected result set.
23    * @param array $column_map
24    *   (optional) An associative array mapping the columns of the result set
25    *   from the view (as keys) and the expected result set (as values).
26    * @param string $message
27    *   (optional) A custom message to display with the assertion. Defaults to
28    *   'Identical result set.'
29    *
30    * @return bool
31    *   TRUE if the assertion succeeded, or FALSE otherwise.
32    */
33   protected function assertIdenticalResultset($view, $expected_result, $column_map = [], $message = NULL) {
34     return $this->assertIdenticalResultsetHelper($view, $expected_result, $column_map, 'assertIdentical', $message);
35   }
36
37   /**
38    * Verifies that a result set returned by a View differs from certain values.
39    *
40    * Inverse of ViewsTestCase::assertIdenticalResultset().
41    *
42    * @param \Drupal\views\ViewExecutable $view
43    *   An executed View.
44    * @param array $expected_result
45    *   An expected result set.
46    * @param array $column_map
47    *   (optional) An associative array mapping the columns of the result set
48    *   from the view (as keys) and the expected result set (as values).
49    * @param string $message
50    *   (optional) A custom message to display with the assertion. Defaults to
51    *   'Non-identical result set.'
52    *
53    * @return bool
54    *   TRUE if the assertion succeeded, or FALSE otherwise.
55    */
56   protected function assertNotIdenticalResultset($view, $expected_result, $column_map = [], $message = NULL) {
57     return $this->assertIdenticalResultsetHelper($view, $expected_result, $column_map, 'assertNotIdentical', $message);
58   }
59
60   /**
61    * Performs View result assertions.
62    *
63    * This is a helper method for ViewTestBase::assertIdenticalResultset() and
64    * ViewTestBase::assertNotIdenticalResultset().
65    *
66    * @param \Drupal\views\ViewExecutable $view
67    *   An executed View.
68    * @param array $expected_result
69    *   An expected result set.
70    * @param array $column_map
71    *   An associative array mapping the columns of the result set
72    *   from the view (as keys) and the expected result set (as values).
73    * @param string $assert_method
74    *   The TestBase assertion method to use (either 'assertIdentical' or
75    *   'assertNotIdentical').
76    * @param string $message
77    *   (optional) The message to display with the assertion.
78    *
79    * @return bool
80    *   TRUE if the assertion succeeded, or FALSE otherwise.
81    */
82   protected function assertIdenticalResultsetHelper($view, $expected_result, $column_map, $assert_method, $message = NULL) {
83     // Convert $view->result to an array of arrays.
84     $result = [];
85     foreach ($view->result as $key => $value) {
86       $row = [];
87       foreach ($column_map as $view_column => $expected_column) {
88         if (property_exists($value, $view_column)) {
89           $row[$expected_column] = (string) $value->$view_column;
90         }
91         // For entity fields we don't have the raw value. Let's try to fetch it
92         // using the entity itself.
93         elseif (empty($value->$view_column) && isset($view->field[$expected_column]) && ($field = $view->field[$expected_column]) && $field instanceof EntityField) {
94           $column = NULL;
95           if (count(explode(':', $view_column)) == 2) {
96             $column = explode(':', $view_column)[1];
97           }
98           // The comparison will be done on the string representation of the
99           // value.
100           $field_value = $field->getValue($value, $column);
101           $row[$expected_column] = is_array($field_value) ? array_map('strval', $field_value) : (string) $field_value;
102         }
103       }
104       $result[$key] = $row;
105     }
106
107     // Remove the columns we don't need from the expected result.
108     foreach ($expected_result as $key => $value) {
109       $row = [];
110       foreach ($column_map as $expected_column) {
111         // The comparison will be done on the string representation of the value.
112         if (is_object($value)) {
113           $row[$expected_column] = (string) $value->$expected_column;
114         }
115         // This case is about fields with multiple values.
116         elseif (is_array($value[$expected_column])) {
117           foreach (array_keys($value[$expected_column]) as $delta) {
118             $row[$expected_column][$delta] = (string) $value[$expected_column][$delta];
119           }
120         }
121         else {
122           $row[$expected_column] = (string) $value[$expected_column];
123         }
124       }
125       $expected_result[$key] = $row;
126     }
127
128     $this->verbose('<pre style="white-space: pre-wrap;">'
129       . "\n\nQuery:\n" . $view->build_info['query']
130       . "\n\nQuery arguments:\n" . var_export($view->build_info['query']->getArguments(), TRUE)
131       . "\n\nActual result:\n" . var_export($result, TRUE)
132       . "\n\nExpected result:\n" . var_export($expected_result, TRUE));
133
134     // Reset the numbering of the arrays.
135     $result = array_values($result);
136     $expected_result = array_values($expected_result);
137
138     // Do the actual comparison.
139     if (!isset($message)) {
140       $not = (strpos($assert_method, 'Not') ? 'not' : '');
141       $message = format_string("Actual result <pre>\n@actual\n</pre> is $not identical to expected <pre>\n@expected\n</pre>", [
142         '@actual' => var_export($result, TRUE),
143         '@expected' => var_export($expected_result, TRUE),
144       ]);
145     }
146     return $this->$assert_method($result, $expected_result, $message);
147   }
148
149 }