8dc101a4659e9754260b385e5e74b614fc011b92
[yaffs-website] / web / core / tests / Drupal / KernelTests / Core / Entity / ConfigEntityQueryTest.php
1 <?php
2
3 namespace Drupal\KernelTests\Core\Entity;
4
5 use Drupal\Core\Config\Entity\Query\QueryFactory;
6 use Drupal\config_test\Entity\ConfigQueryTest;
7 use Drupal\KernelTests\KernelTestBase;
8
9 /**
10  * Tests Config Entity Query functionality.
11  *
12  * @group Entity
13  * @see \Drupal\Core\Config\Entity\Query
14  */
15 class ConfigEntityQueryTest extends KernelTestBase {
16
17   /**
18    * Modules to enable.
19    *
20    * @var array
21    */
22   public static $modules = ['config_test'];
23
24   /**
25    * Stores the search results for alter comparison.
26    *
27    * @var array
28    */
29   protected $queryResults;
30
31   /**
32    * The query factory used to construct all queries in the test.
33    *
34    * @var \Drupal\Core\Entity\Query\QueryFactory
35    */
36   protected $factory;
37
38   /**
39    * Stores all config entities created for the test.
40    *
41    * @var array
42    */
43   protected $entities;
44
45   protected function setUp() {
46     parent::setUp();
47
48     $this->entities = [];
49     $this->factory = $this->container->get('entity.query');
50
51     // These two are here to make sure that matchArray needs to go over several
52     // non-matches on every levels.
53     $array['level1']['level2a'] = 9;
54     $array['level1a']['level2'] = 9;
55     // The tests match array.level1.level2.
56     $array['level1']['level2'] = 1;
57     $entity = ConfigQueryTest::create([
58       'label' => $this->randomMachineName(),
59       'id' => '1',
60       'number' => 31,
61       'array' => $array,
62     ]);
63     $this->entities[] = $entity;
64     $entity->enforceIsNew();
65     $entity->save();
66
67     $array['level1']['level2'] = 2;
68     $entity = ConfigQueryTest::create([
69       'label' => $this->randomMachineName(),
70       'id' => '2',
71       'number' => 41,
72       'array' => $array,
73     ]);
74     $this->entities[] = $entity;
75     $entity->enforceIsNew();
76     $entity->save();
77
78     $array['level1']['level2'] = 1;
79     $entity = ConfigQueryTest::create([
80       'label' => 'test_prefix_' . $this->randomMachineName(),
81       'id' => '3',
82       'number' => 59,
83       'array' => $array,
84     ]);
85     $this->entities[] = $entity;
86     $entity->enforceIsNew();
87     $entity->save();
88
89     $array['level1']['level2'] = 2;
90     $entity = ConfigQueryTest::create([
91       'label' => $this->randomMachineName() . '_test_suffix',
92       'id' => '4',
93       'number' => 26,
94       'array' => $array,
95     ]);
96     $this->entities[] = $entity;
97     $entity->enforceIsNew();
98     $entity->save();
99
100     $array['level1']['level2'] = 3;
101     $entity = ConfigQueryTest::create([
102       'label' => $this->randomMachineName() . '_TEST_contains_' . $this->randomMachineName(),
103       'id' => '5',
104       'number' => 53,
105       'array' => $array,
106     ]);
107     $this->entities[] = $entity;
108     $entity->enforceIsNew();
109     $entity->save();
110   }
111
112   /**
113    * Tests basic functionality.
114    */
115   public function testConfigEntityQuery() {
116     // Run a test without any condition.
117     $this->queryResults = $this->factory->get('config_query_test')
118       ->execute();
119     $this->assertResults(['1', '2', '3', '4', '5']);
120     // No conditions, OR.
121     $this->queryResults = $this->factory->get('config_query_test', 'OR')
122       ->execute();
123     $this->assertResults(['1', '2', '3', '4', '5']);
124
125     // Filter by ID with equality.
126     $this->queryResults = $this->factory->get('config_query_test')
127       ->condition('id', '3')
128       ->execute();
129     $this->assertResults(['3']);
130
131     // Filter by label with a known prefix.
132     $this->queryResults = $this->factory->get('config_query_test')
133       ->condition('label', 'test_prefix', 'STARTS_WITH')
134       ->execute();
135     $this->assertResults(['3']);
136
137     // Filter by label with a known suffix.
138     $this->queryResults = $this->factory->get('config_query_test')
139       ->condition('label', 'test_suffix', 'ENDS_WITH')
140       ->execute();
141     $this->assertResults(['4']);
142
143     // Filter by label with a known containing word.
144     $this->queryResults = $this->factory->get('config_query_test')
145       ->condition('label', 'test_contains', 'CONTAINS')
146       ->execute();
147     $this->assertResults(['5']);
148
149     // Filter by ID with the IN operator.
150     $this->queryResults = $this->factory->get('config_query_test')
151       ->condition('id', ['2', '3'], 'IN')
152       ->execute();
153     $this->assertResults(['2', '3']);
154
155     // Filter by ID with the implicit IN operator.
156     $this->queryResults = $this->factory->get('config_query_test')
157       ->condition('id', ['2', '3'])
158       ->execute();
159     $this->assertResults(['2', '3']);
160
161     // Filter by ID with the > operator.
162     $this->queryResults = $this->factory->get('config_query_test')
163       ->condition('id', '3', '>')
164       ->execute();
165     $this->assertResults(['4', '5']);
166
167     // Filter by ID with the >= operator.
168     $this->queryResults = $this->factory->get('config_query_test')
169       ->condition('id', '3', '>=')
170       ->execute();
171     $this->assertResults(['3', '4', '5']);
172
173     // Filter by ID with the <> operator.
174     $this->queryResults = $this->factory->get('config_query_test')
175       ->condition('id', '3', '<>')
176       ->execute();
177     $this->assertResults(['1', '2', '4', '5']);
178
179     // Filter by ID with the < operator.
180     $this->queryResults = $this->factory->get('config_query_test')
181       ->condition('id', '3', '<')
182       ->execute();
183     $this->assertResults(['1', '2']);
184
185     // Filter by ID with the <= operator.
186     $this->queryResults = $this->factory->get('config_query_test')
187       ->condition('id', '3', '<=')
188       ->execute();
189     $this->assertResults(['1', '2', '3']);
190
191     // Filter by two conditions on the same field.
192     $this->queryResults = $this->factory->get('config_query_test')
193       ->condition('label', 'test_pref', 'STARTS_WITH')
194       ->condition('label', 'test_prefix', 'STARTS_WITH')
195       ->execute();
196     $this->assertResults(['3']);
197
198     // Filter by two conditions on different fields. The first query matches for
199     // a different ID, so the result is empty.
200     $this->queryResults = $this->factory->get('config_query_test')
201       ->condition('label', 'test_prefix', 'STARTS_WITH')
202       ->condition('id', '5')
203       ->execute();
204     $this->assertResults([]);
205
206     // Filter by two different conditions on different fields. This time the
207     // first condition matches on one item, but the second one does as well.
208     $this->queryResults = $this->factory->get('config_query_test')
209       ->condition('label', 'test_prefix', 'STARTS_WITH')
210       ->condition('id', '3')
211       ->execute();
212     $this->assertResults(['3']);
213
214     // Filter by two different conditions, of which the first one matches for
215     // every entry, the second one as well, but just the third one filters so
216     // that just two are left.
217     $this->queryResults = $this->factory->get('config_query_test')
218       ->condition('id', '1', '>=')
219       ->condition('number', 10, '>=')
220       ->condition('number', 50, '>=')
221       ->execute();
222     $this->assertResults(['3', '5']);
223
224     // Filter with an OR condition group.
225     $this->queryResults = $this->factory->get('config_query_test', 'OR')
226       ->condition('id', 1)
227       ->condition('id', '2')
228       ->execute();
229     $this->assertResults(['1', '2']);
230
231     // Simplify it with IN.
232     $this->queryResults = $this->factory->get('config_query_test')
233       ->condition('id', ['1', '2'])
234       ->execute();
235     $this->assertResults(['1', '2']);
236     // Try explicit IN.
237     $this->queryResults = $this->factory->get('config_query_test')
238       ->condition('id', ['1', '2'], 'IN')
239       ->execute();
240     $this->assertResults(['1', '2']);
241     // Try not IN.
242     $this->queryResults = $this->factory->get('config_query_test')
243       ->condition('id', ['1', '2'], 'NOT IN')
244       ->execute();
245     $this->assertResults(['3', '4', '5']);
246
247     // Filter with an OR condition group on different fields.
248     $this->queryResults = $this->factory->get('config_query_test', 'OR')
249       ->condition('id', 1)
250       ->condition('number', 41)
251       ->execute();
252     $this->assertResults(['1', '2']);
253
254     // Filter with an OR condition group on different fields but matching on the
255     // same entity.
256     $this->queryResults = $this->factory->get('config_query_test', 'OR')
257       ->condition('id', 1)
258       ->condition('number', 31)
259       ->execute();
260     $this->assertResults(['1']);
261
262     // NO simple conditions, YES complex conditions, 'AND'.
263     $query = $this->factory->get('config_query_test', 'AND');
264     $and_condition_1 = $query->orConditionGroup()
265       ->condition('id', '2')
266       ->condition('label', $this->entities[0]->label);
267     $and_condition_2 = $query->orConditionGroup()
268       ->condition('id', 1)
269       ->condition('label', $this->entities[3]->label);
270     $this->queryResults = $query
271       ->condition($and_condition_1)
272       ->condition($and_condition_2)
273       ->execute();
274     $this->assertResults(['1']);
275
276     // NO simple conditions, YES complex conditions, 'OR'.
277     $query = $this->factory->get('config_query_test', 'OR');
278     $and_condition_1 = $query->andConditionGroup()
279       ->condition('id', 1)
280       ->condition('label', $this->entities[0]->label);
281     $and_condition_2 = $query->andConditionGroup()
282       ->condition('id', '2')
283       ->condition('label', $this->entities[1]->label);
284     $this->queryResults = $query
285       ->condition($and_condition_1)
286       ->condition($and_condition_2)
287       ->execute();
288     $this->assertResults(['1', '2']);
289
290     // YES simple conditions, YES complex conditions, 'AND'.
291     $query = $this->factory->get('config_query_test', 'AND');
292     $and_condition_1 = $query->orConditionGroup()
293       ->condition('id', '2')
294       ->condition('label', $this->entities[0]->label);
295     $and_condition_2 = $query->orConditionGroup()
296       ->condition('id', 1)
297       ->condition('label', $this->entities[3]->label);
298     $this->queryResults = $query
299       ->condition('number', 31)
300       ->condition($and_condition_1)
301       ->condition($and_condition_2)
302       ->execute();
303     $this->assertResults(['1']);
304
305     // YES simple conditions, YES complex conditions, 'OR'.
306     $query = $this->factory->get('config_query_test', 'OR');
307     $and_condition_1 = $query->orConditionGroup()
308       ->condition('id', '2')
309       ->condition('label', $this->entities[0]->label);
310     $and_condition_2 = $query->orConditionGroup()
311       ->condition('id', 1)
312       ->condition('label', $this->entities[3]->label);
313     $this->queryResults = $query
314       ->condition('number', 53)
315       ->condition($and_condition_1)
316       ->condition($and_condition_2)
317       ->execute();
318     $this->assertResults(['1', '2', '4', '5']);
319
320     // Test the exists and notExists conditions.
321     $this->queryResults = $this->factory->get('config_query_test')
322       ->exists('id')
323       ->execute();
324     $this->assertResults(['1', '2', '3', '4', '5']);
325
326     $this->queryResults = $this->factory->get('config_query_test')
327       ->exists('non-existent')
328       ->execute();
329     $this->assertResults([]);
330
331     $this->queryResults = $this->factory->get('config_query_test')
332       ->notExists('id')
333       ->execute();
334     $this->assertResults([]);
335
336     $this->queryResults = $this->factory->get('config_query_test')
337       ->notExists('non-existent')
338       ->execute();
339     $this->assertResults(['1', '2', '3', '4', '5']);
340   }
341
342   /**
343    * Tests ID conditions.
344    */
345   public function testStringIdConditions() {
346     // We need an entity with a non-numeric ID.
347     $entity = ConfigQueryTest::create([
348       'label' => $this->randomMachineName(),
349       'id' => 'foo.bar',
350     ]);
351     $this->entities[] = $entity;
352     $entity->enforceIsNew();
353     $entity->save();
354
355     // Test 'STARTS_WITH' condition.
356     $this->queryResults = $this->factory->get('config_query_test')
357       ->condition('id', 'foo.bar', 'STARTS_WITH')
358       ->execute();
359     $this->assertResults(['foo.bar']);
360     $this->queryResults = $this->factory->get('config_query_test')
361       ->condition('id', 'f', 'STARTS_WITH')
362       ->execute();
363     $this->assertResults(['foo.bar']);
364     $this->queryResults = $this->factory->get('config_query_test')
365       ->condition('id', 'miss', 'STARTS_WITH')
366       ->execute();
367     $this->assertResults([]);
368
369     // Test 'CONTAINS' condition.
370     $this->queryResults = $this->factory->get('config_query_test')
371       ->condition('id', 'foo.bar', 'CONTAINS')
372       ->execute();
373     $this->assertResults(['foo.bar']);
374     $this->queryResults = $this->factory->get('config_query_test')
375       ->condition('id', 'oo.ba', 'CONTAINS')
376       ->execute();
377     $this->assertResults(['foo.bar']);
378     $this->queryResults = $this->factory->get('config_query_test')
379       ->condition('id', 'miss', 'CONTAINS')
380       ->execute();
381     $this->assertResults([]);
382
383     // Test 'ENDS_WITH' condition.
384     $this->queryResults = $this->factory->get('config_query_test')
385       ->condition('id', 'foo.bar', 'ENDS_WITH')
386       ->execute();
387     $this->assertResults(['foo.bar']);
388     $this->queryResults = $this->factory->get('config_query_test')
389       ->condition('id', 'r', 'ENDS_WITH')
390       ->execute();
391     $this->assertResults(['foo.bar']);
392     $this->queryResults = $this->factory->get('config_query_test')
393       ->condition('id', 'miss', 'ENDS_WITH')
394       ->execute();
395     $this->assertResults([]);
396   }
397
398   /**
399    * Tests count query.
400    */
401   public function testCount() {
402     // Test count on no conditions.
403     $count = $this->factory->get('config_query_test')
404       ->count()
405       ->execute();
406     $this->assertIdentical($count, count($this->entities));
407
408     // Test count on a complex query.
409     $query = $this->factory->get('config_query_test', 'OR');
410     $and_condition_1 = $query->andConditionGroup()
411       ->condition('id', 1)
412       ->condition('label', $this->entities[0]->label);
413     $and_condition_2 = $query->andConditionGroup()
414       ->condition('id', '2')
415       ->condition('label', $this->entities[1]->label);
416     $count = $query
417       ->condition($and_condition_1)
418       ->condition($and_condition_2)
419       ->count()
420       ->execute();
421     $this->assertIdentical($count, 2);
422   }
423
424   /**
425    * Tests sorting and range on config entity queries.
426    */
427   public function testSortRange() {
428     // Sort by simple ascending/descending.
429     $this->queryResults = $this->factory->get('config_query_test')
430       ->sort('number', 'DESC')
431       ->execute();
432     $this->assertIdentical(array_values($this->queryResults), ['3', '5', '2', '1', '4']);
433
434     $this->queryResults = $this->factory->get('config_query_test')
435       ->sort('number', 'ASC')
436       ->execute();
437     $this->assertIdentical(array_values($this->queryResults), ['4', '1', '2', '5', '3']);
438
439     // Apply some filters and sort.
440     $this->queryResults = $this->factory->get('config_query_test')
441       ->condition('id', '3', '>')
442       ->sort('number', 'DESC')
443       ->execute();
444     $this->assertIdentical(array_values($this->queryResults), ['5', '4']);
445
446     $this->queryResults = $this->factory->get('config_query_test')
447       ->condition('id', '3', '>')
448       ->sort('number', 'ASC')
449       ->execute();
450     $this->assertIdentical(array_values($this->queryResults), ['4', '5']);
451
452     // Apply a pager and sort.
453     $this->queryResults = $this->factory->get('config_query_test')
454       ->sort('number', 'DESC')
455       ->range('2', '2')
456       ->execute();
457     $this->assertIdentical(array_values($this->queryResults), ['2', '1']);
458
459     $this->queryResults = $this->factory->get('config_query_test')
460       ->sort('number', 'ASC')
461       ->range('2', '2')
462       ->execute();
463     $this->assertIdentical(array_values($this->queryResults), ['2', '5']);
464
465     // Add a range to a query without a start parameter.
466     $this->queryResults = $this->factory->get('config_query_test')
467       ->range(0, '3')
468       ->sort('id', 'ASC')
469       ->execute();
470     $this->assertIdentical(array_values($this->queryResults), ['1', '2', '3']);
471
472     // Apply a pager with limit 4.
473     $this->queryResults = $this->factory->get('config_query_test')
474       ->pager('4', 0)
475       ->sort('id', 'ASC')
476       ->execute();
477     $this->assertIdentical(array_values($this->queryResults), ['1', '2', '3', '4']);
478   }
479
480   /**
481    * Tests sorting with tableSort on config entity queries.
482    */
483   public function testTableSort() {
484     $header = [
485       ['data' => t('ID'), 'specifier' => 'id'],
486       ['data' => t('Number'), 'specifier' => 'number'],
487     ];
488
489     // Sort key: id
490     // Sorting with 'DESC' upper case
491     $this->queryResults = $this->factory->get('config_query_test')
492       ->tableSort($header)
493       ->sort('id', 'DESC')
494       ->execute();
495     $this->assertIdentical(array_values($this->queryResults), ['5', '4', '3', '2', '1']);
496
497     // Sorting with 'ASC' upper case
498     $this->queryResults = $this->factory->get('config_query_test')
499       ->tableSort($header)
500       ->sort('id', 'ASC')
501       ->execute();
502     $this->assertIdentical(array_values($this->queryResults), ['1', '2', '3', '4', '5']);
503
504     // Sorting with 'desc' lower case
505     $this->queryResults = $this->factory->get('config_query_test')
506       ->tableSort($header)
507       ->sort('id', 'desc')
508       ->execute();
509     $this->assertIdentical(array_values($this->queryResults), ['5', '4', '3', '2', '1']);
510
511     // Sorting with 'asc' lower case
512     $this->queryResults = $this->factory->get('config_query_test')
513       ->tableSort($header)
514       ->sort('id', 'asc')
515       ->execute();
516     $this->assertIdentical(array_values($this->queryResults), ['1', '2', '3', '4', '5']);
517
518     // Sort key: number
519     // Sorting with 'DeSc' mixed upper and lower case
520     $this->queryResults = $this->factory->get('config_query_test')
521       ->tableSort($header)
522       ->sort('number', 'DeSc')
523       ->execute();
524     $this->assertIdentical(array_values($this->queryResults), ['3', '5', '2', '1', '4']);
525
526     // Sorting with 'AsC' mixed upper and lower case
527     $this->queryResults = $this->factory->get('config_query_test')
528       ->tableSort($header)
529       ->sort('number', 'AsC')
530       ->execute();
531     $this->assertIdentical(array_values($this->queryResults), ['4', '1', '2', '5', '3']);
532
533     // Sorting with 'dEsC' mixed upper and lower case
534     $this->queryResults = $this->factory->get('config_query_test')
535       ->tableSort($header)
536       ->sort('number', 'dEsC')
537       ->execute();
538     $this->assertIdentical(array_values($this->queryResults), ['3', '5', '2', '1', '4']);
539
540     // Sorting with 'aSc' mixed upper and lower case
541     $this->queryResults = $this->factory->get('config_query_test')
542       ->tableSort($header)
543       ->sort('number', 'aSc')
544       ->execute();
545     $this->assertIdentical(array_values($this->queryResults), ['4', '1', '2', '5', '3']);
546   }
547
548   /**
549    * Tests dotted path matching.
550    */
551   public function testDotted() {
552     $this->queryResults = $this->factory->get('config_query_test')
553       ->condition('array.level1.*', 1)
554       ->execute();
555     $this->assertResults(['1', '3']);
556     $this->queryResults = $this->factory->get('config_query_test')
557       ->condition('*.level1.level2', 2)
558       ->execute();
559     $this->assertResults(['2', '4']);
560     $this->queryResults = $this->factory->get('config_query_test')
561       ->condition('array.level1.*', 3)
562       ->execute();
563     $this->assertResults(['5']);
564     $this->queryResults = $this->factory->get('config_query_test')
565       ->condition('array.level1.level2', 3)
566       ->execute();
567     $this->assertResults(['5']);
568     // Make sure that values on the wildcard level do not match if there are
569     // sub-keys defined. This must not find anything even if entity 2 has a
570     // top-level key number with value 41.
571     $this->queryResults = $this->factory->get('config_query_test')
572       ->condition('*.level1.level2', 41)
573       ->execute();
574     $this->assertResults([]);
575     // Make sure that "IS NULL" and "IS NOT NULL" work correctly with
576     // array-valued fields/keys.
577     $all = ['1', '2', '3', '4', '5'];
578     $this->queryResults = $this->factory->get('config_query_test')
579       ->exists('array.level1.level2')
580       ->execute();
581     $this->assertResults($all);
582     $this->queryResults = $this->factory->get('config_query_test')
583       ->exists('array.level1')
584       ->execute();
585     $this->assertResults($all);
586     $this->queryResults = $this->factory->get('config_query_test')
587       ->exists('array')
588       ->execute();
589     $this->assertResults($all);
590     $this->queryResults = $this->factory->get('config_query_test')
591       ->notExists('array.level1.level2')
592       ->execute();
593     $this->assertResults([]);
594     $this->queryResults = $this->factory->get('config_query_test')
595       ->notExists('array.level1')
596       ->execute();
597     $this->assertResults([]);
598     $this->queryResults = $this->factory->get('config_query_test')
599       ->notExists('array')
600       ->execute();
601     $this->assertResults([]);
602   }
603
604   /**
605    * Tests case sensitivity.
606    */
607   public function testCaseSensitivity() {
608     // Filter by label with a known containing case-sensitive word.
609     $this->queryResults = $this->factory->get('config_query_test')
610       ->condition('label', 'TEST', 'CONTAINS')
611       ->execute();
612     $this->assertResults(['3', '4', '5']);
613
614     $this->queryResults = $this->factory->get('config_query_test')
615       ->condition('label', 'test', 'CONTAINS')
616       ->execute();
617     $this->assertResults(['3', '4', '5']);
618   }
619
620   /**
621    * Tests lookup keys are added to the key value store.
622    */
623   public function testLookupKeys() {
624     \Drupal::service('state')->set('config_test.lookup_keys', TRUE);
625     \Drupal::entityManager()->clearCachedDefinitions();
626     $key_value = $this->container->get('keyvalue')->get(QueryFactory::CONFIG_LOOKUP_PREFIX . 'config_test');
627
628     $test_entities = [];
629     $storage = \Drupal::entityTypeManager()->getStorage('config_test');
630     $entity = $storage->create([
631       'label' => $this->randomMachineName(),
632       'id' => '1',
633       'style' => 'test',
634     ]);
635     $test_entities[$entity->getConfigDependencyName()] = $entity;
636     $entity->enforceIsNew();
637     $entity->save();
638
639     $expected[] = $entity->getConfigDependencyName();
640     $this->assertEqual($expected, $key_value->get('style:test'));
641
642     $entity = $storage->create([
643       'label' => $this->randomMachineName(),
644       'id' => '2',
645       'style' => 'test',
646     ]);
647     $test_entities[$entity->getConfigDependencyName()] = $entity;
648     $entity->enforceIsNew();
649     $entity->save();
650     $expected[] = $entity->getConfigDependencyName();
651     $this->assertEqual($expected, $key_value->get('style:test'));
652
653     $entity = $storage->create([
654       'label' => $this->randomMachineName(),
655       'id' => '3',
656       'style' => 'blah',
657     ]);
658     $entity->enforceIsNew();
659     $entity->save();
660     // Do not add this entity to the list of expected result as it has a
661     // different value.
662     $this->assertEqual($expected, $key_value->get('style:test'));
663     $this->assertEqual([$entity->getConfigDependencyName()], $key_value->get('style:blah'));
664
665     // Ensure that a delete clears a key.
666     $entity->delete();
667     $this->assertEqual(NULL, $key_value->get('style:blah'));
668
669     // Ensure that delete only clears one key.
670     $entity_id = array_pop($expected);
671     $test_entities[$entity_id]->delete();
672     $this->assertEqual($expected, $key_value->get('style:test'));
673     $entity_id = array_pop($expected);
674     $test_entities[$entity_id]->delete();
675     $this->assertEqual(NULL, $key_value->get('style:test'));
676   }
677
678   /**
679    * Asserts the results as expected regardless of order.
680    *
681    * @param array $expected
682    *   Array of expected entity IDs.
683    */
684   protected function assertResults($expected) {
685     $this->assertIdentical(count($this->queryResults), count($expected));
686     foreach ($expected as $value) {
687       // This also tests whether $this->queryResults[$value] is even set at all.
688       $this->assertIdentical($this->queryResults[$value], $value);
689     }
690   }
691
692 }