Version 1
[yaffs-website] / web / core / modules / simpletest / tests / src / Unit / TestBaseTest.php
1 <?php
2
3 namespace Drupal\Tests\simpletest\Unit;
4
5 use Drupal\Tests\UnitTestCase;
6
7 /**
8  * @requires extension curl
9  * @coversDefaultClass \Drupal\simpletest\TestBase
10  * @group simpletest
11  */
12 class TestBaseTest extends UnitTestCase {
13
14   /**
15    * Helper method for constructing a mock TestBase object.
16    *
17    * TestBase is abstract, so we have to mock it. We'll also
18    * mock the storeAssertion() method so we don't need the database.
19    *
20    * @param string $test_id
21    *   An identifying name for the mocked test.
22    *
23    * @return object
24    *   Mock of Drupal\simpletest\TestBase.
25    */
26   public function getTestBaseForAssertionTests($test_id) {
27     $mock_test_base = $this->getMockBuilder('Drupal\simpletest\TestBase')
28       ->setConstructorArgs([$test_id])
29       ->setMethods(['storeAssertion'])
30       ->getMockForAbstractClass();
31     // Override storeAssertion() so we don't need a database.
32     $mock_test_base->expects($this->any())
33       ->method('storeAssertion')
34       ->will($this->returnValue(NULL));
35     return $mock_test_base;
36   }
37
38   /**
39    * Invoke methods that are protected or private.
40    *
41    * @param object $object
42    *   Object on which to invoke the method.
43    * @param string $method_name
44    *   Name of the method to invoke.
45    * @param array $arguments
46    *   Array of arguments to be passed to the method.
47    *
48    * @return mixed
49    *   Value returned by the invoked method.
50    */
51   public function invokeProtectedMethod($object, $method_name, array $arguments) {
52     $ref_method = new \ReflectionMethod($object, $method_name);
53     $ref_method->setAccessible(TRUE);
54     return $ref_method->invokeArgs($object, $arguments);
55   }
56
57   /**
58    * Provides data for the random string validation test.
59    *
60    * @return array
61    *   - The expected result of the validation.
62    *   - The string to validate.
63    */
64   public function providerRandomStringValidate() {
65     return [
66       [FALSE, ' curry paste'],
67       [FALSE, 'curry paste '],
68       [FALSE, 'curry  paste'],
69       [FALSE, 'curry   paste'],
70       [TRUE, 'curry paste'],
71       [TRUE, 'thai green curry paste'],
72       [TRUE, '@startswithat'],
73       [TRUE, 'contains@at'],
74     ];
75   }
76
77   /**
78    * @covers ::randomStringValidate
79    * @dataProvider providerRandomStringValidate
80    */
81   public function testRandomStringValidate($expected, $string) {
82     $mock_test_base = $this->getMockForAbstractClass('Drupal\simpletest\TestBase');
83     $actual = $mock_test_base->randomStringValidate($string);
84     $this->assertEquals($expected, $actual);
85   }
86
87   /**
88    * Provides data for testRandomString() and others.
89    *
90    * @return array
91    *   - The number of items (characters, object properties) we expect any of
92    *     the random functions to give us.
93    */
94   public function providerRandomItems() {
95     return [
96       [NULL],
97       [0],
98       [1],
99       [2],
100       [3],
101       [4],
102       [7],
103     ];
104   }
105
106   /**
107    * @covers ::randomString
108    * @dataProvider providerRandomItems
109    */
110   public function testRandomString($length) {
111     $mock_test_base = $this->getMockForAbstractClass('Drupal\simpletest\TestBase');
112     $string = $mock_test_base->randomString($length);
113     $this->assertEquals($length, strlen($string));
114     // randomString() should always include an ampersand ('&')  and a
115     // greater than ('>') if $length is greater than 3.
116     if ($length > 4) {
117       $this->assertContains('&', $string);
118       $this->assertContains('>', $string);
119     }
120   }
121
122   /**
123    * @covers ::randomObject
124    * @dataProvider providerRandomItems
125    */
126   public function testRandomObject($size) {
127     $test_base = $this->getTestBaseForAssertionTests('test_id');
128     // Note: count((array)object) works for now, maybe not later.
129     $this->assertEquals($size, count((array) $test_base->randomObject($size)));
130   }
131
132   /**
133    * @covers ::checkRequirements
134    */
135   public function testCheckRequirements() {
136     $test_base = $this->getTestBaseForAssertionTests('test_id');
137     $this->assertInternalType(
138         'array',
139         $this->invokeProtectedMethod($test_base, 'checkRequirements', [])
140     );
141   }
142
143   /**
144    * Data provider for testAssert().
145    *
146    * @return array
147    *   Standard dataProvider array of arrays:
148    *   - Expected result from assert().
149    *   - Expected status stored in TestBase->assertions.
150    *   - Status, passed to assert().
151    *   - Message, passed to assert().
152    *   - Group, passed to assert().
153    *   - Caller, passed to assert().
154    */
155   public function providerAssert() {
156     return [
157       [TRUE, 'pass', TRUE, 'Yay pass', 'test', []],
158       [FALSE, 'fail', FALSE, 'Boo fail', 'test', []],
159       [TRUE, 'pass', 'pass', 'Yay pass', 'test', []],
160       [FALSE, 'fail', 'fail', 'Boo fail', 'test', []],
161       [FALSE, 'exception', 'exception', 'Boo fail', 'test', []],
162       [FALSE, 'debug', 'debug', 'Boo fail', 'test', []],
163     ];
164   }
165
166   /**
167    * @covers ::assert
168    * @dataProvider providerAssert
169    */
170   public function testAssert($expected, $assertion_status, $status, $message, $group, $caller) {
171     $test_id = 'luke_i_am_your_' . $assertion_status;
172     $test_base = $this->getTestBaseForAssertionTests($test_id);
173
174     // Verify some startup values.
175     $this->assertAttributeEmpty('assertions', $test_base);
176     if (is_string($status)) {
177       $this->assertEquals(0, $test_base->results['#' . $status]);
178     }
179
180     // assert() is protected so we have to make it accessible.
181     $ref_assert = new \ReflectionMethod($test_base, 'assert');
182     $ref_assert->setAccessible(TRUE);
183
184     // Call assert() from within our hall of mirrors.
185     $this->assertEquals(
186         $expected,
187         $ref_assert->invokeArgs($test_base,
188           [$status, $message, $group, $caller]
189         )
190     );
191
192     // Check the side-effects of assert().
193     if (is_string($status)) {
194       $this->assertEquals(1, $test_base->results['#' . $status]);
195     }
196     $this->assertAttributeNotEmpty('assertions', $test_base);
197     // Make a ReflectionProperty for the assertions property,
198     // since it's protected.
199     $ref_assertions = new \ReflectionProperty($test_base, 'assertions');
200     $ref_assertions->setAccessible(TRUE);
201     $assertions = $ref_assertions->getValue($test_base);
202     $assertion = reset($assertions);
203     $this->assertEquals($assertion_status, $assertion['status']);
204     $this->assertEquals($test_id, $assertion['test_id']);
205     $this->assertEquals(get_class($test_base), $assertion['test_class']);
206     $this->assertEquals($message, $assertion['message']);
207     $this->assertEquals($group, $assertion['message_group']);
208   }
209
210   /**
211    * Data provider for assertTrue().
212    */
213   public function providerAssertTrue() {
214     return [
215       [TRUE, TRUE],
216       [FALSE, FALSE],
217     ];
218   }
219
220   /**
221    * @covers ::assertTrue
222    * @dataProvider providerAssertTrue
223    */
224   public function testAssertTrue($expected, $value) {
225     $test_base = $this->getTestBaseForAssertionTests('test_id');
226     $this->assertEquals(
227         $expected,
228         $this->invokeProtectedMethod($test_base, 'assertTrue', [$value])
229     );
230   }
231
232   /**
233    * @covers ::assertFalse
234    * @dataProvider providerAssertTrue
235    */
236   public function testAssertFalse($expected, $value) {
237     $test_base = $this->getTestBaseForAssertionTests('test_id');
238     $this->assertEquals(
239         (!$expected),
240         $this->invokeProtectedMethod($test_base, 'assertFalse', [$value])
241     );
242   }
243
244   /**
245    * Data provider for assertNull().
246    */
247   public function providerAssertNull() {
248     return [
249       [TRUE, NULL],
250       [FALSE, ''],
251     ];
252   }
253
254   /**
255    * @covers ::assertNull
256    * @dataProvider providerAssertNull
257    */
258   public function testAssertNull($expected, $value) {
259     $test_base = $this->getTestBaseForAssertionTests('test_id');
260     $this->assertEquals(
261         $expected,
262         $this->invokeProtectedMethod($test_base, 'assertNull', [$value])
263     );
264   }
265
266   /**
267    * @covers ::assertNotNull
268    * @dataProvider providerAssertNull
269    */
270   public function testAssertNotNull($expected, $value) {
271     $test_base = $this->getTestBaseForAssertionTests('test_id');
272     $this->assertEquals(
273         (!$expected),
274         $this->invokeProtectedMethod($test_base, 'assertNotNull', [$value])
275     );
276   }
277
278   /**
279    * Data provider for tests of equality assertions.
280    *
281    * Used by testAssertIdentical(), testAssertEqual(), testAssertNotIdentical(),
282    * and testAssertNotEqual().
283    *
284    * @return
285    *   Array of test data.
286    *   - Expected assertion value for identical comparison.
287    *   - Expected assertion value for equal comparison.
288    *   - First value to compare.
289    *   - Second value to compare.
290    */
291   public function providerEqualityAssertions() {
292     return [
293       // Integers and floats.
294       [TRUE, TRUE, 0, 0],
295       [FALSE, TRUE, 0, 0.0],
296       [FALSE, TRUE, '0', 0],
297       [FALSE, TRUE, '0.0', 0.0],
298       [FALSE, FALSE, 23, 77],
299       [TRUE, TRUE, 23.0, 23.0],
300       // Strings.
301       [FALSE, FALSE, 'foof', 'yay'],
302       [TRUE, TRUE, 'yay', 'yay'],
303       // Bools with type conversion.
304       [TRUE, TRUE, TRUE, TRUE],
305       [TRUE, TRUE, FALSE, FALSE],
306       [FALSE, TRUE, NULL, FALSE],
307       [FALSE, TRUE, 'TRUE', TRUE],
308       [FALSE, FALSE, 'FALSE', FALSE],
309       [FALSE, TRUE, 0, FALSE],
310       [FALSE, TRUE, 1, TRUE],
311       [FALSE, TRUE, -1, TRUE],
312       [FALSE, TRUE, '1', TRUE],
313       [FALSE, TRUE, '1.3', TRUE],
314       // Null.
315       [FALSE, FALSE, 'NULL', NULL],
316       [TRUE, TRUE, NULL, NULL],
317     ];
318   }
319
320   /**
321    * @covers ::assertIdentical
322    * @dataProvider providerEqualityAssertions
323    */
324   public function testAssertIdentical($expected_identical, $expected_equal, $first, $second) {
325     $test_base = $this->getTestBaseForAssertionTests('test_id');
326     $this->assertEquals(
327         $expected_identical,
328         $this->invokeProtectedMethod($test_base, 'assertIdentical', [$first, $second])
329     );
330   }
331
332   /**
333    * @covers ::assertNotIdentical
334    * @dataProvider providerEqualityAssertions
335    */
336   public function testAssertNotIdentical($expected_identical, $expected_equal, $first, $second) {
337     $test_base = $this->getTestBaseForAssertionTests('test_id');
338     $this->assertEquals(
339         (!$expected_identical),
340         $this->invokeProtectedMethod($test_base, 'assertNotIdentical', [$first, $second])
341     );
342   }
343
344   /**
345    * @covers ::assertEqual
346    * @dataProvider providerEqualityAssertions
347    */
348   public function testAssertEqual($expected_identical, $expected_equal, $first, $second) {
349     $test_base = $this->getTestBaseForAssertionTests('test_id');
350     $this->assertEquals(
351         $expected_equal,
352         $this->invokeProtectedMethod($test_base, 'assertEqual', [$first, $second])
353     );
354   }
355
356   /**
357    * @covers ::assertNotEqual
358    * @dataProvider providerEqualityAssertions
359    */
360   public function testAssertNotEqual($expected_identical, $expected_equal, $first, $second) {
361     $test_base = $this->getTestBaseForAssertionTests('test_id');
362     $this->assertEquals(
363         (!$expected_equal),
364         $this->invokeProtectedMethod($test_base, 'assertNotEqual', [$first, $second])
365     );
366   }
367
368   /**
369    * Data provider for testAssertIdenticalObject().
370    */
371   public function providerAssertIdenticalObject() {
372     $obj1 = new \stdClass();
373     $obj1->foof = 'yay';
374     $obj2 = $obj1;
375     $obj3 = clone $obj1;
376     $obj4 = new \stdClass();
377     return [
378       [TRUE, $obj1, $obj2],
379       [TRUE, $obj1, $obj3],
380       [FALSE, $obj1, $obj4],
381     ];
382   }
383
384   /**
385    * @covers ::assertIdenticalObject
386    * @dataProvider providerAssertIdenticalObject
387    */
388   public function testAssertIdenticalObject($expected, $first, $second) {
389     $test_base = $this->getTestBaseForAssertionTests('test_id');
390     $this->assertEquals(
391       $expected,
392       $this->invokeProtectedMethod($test_base, 'assertIdenticalObject', [$first, $second])
393     );
394   }
395
396   /**
397    * @covers ::pass
398    */
399   public function testPass() {
400     $test_base = $this->getTestBaseForAssertionTests('test_id');
401     $this->assertEquals(
402         TRUE,
403         $this->invokeProtectedMethod($test_base, 'pass', [])
404     );
405   }
406
407   /**
408    * @covers ::fail
409    */
410   public function testFail() {
411     $test_base = $this->getTestBaseForAssertionTests('test_id');
412     $this->assertEquals(
413         FALSE,
414         $this->invokeProtectedMethod($test_base, 'fail', [])
415     );
416   }
417
418   /**
419    * Data provider for testError().
420    *
421    * @return array
422    *   - Expected status for assertion.
423    *   - Group for use in assert().
424    */
425   public function providerError() {
426     return [
427       ['debug', 'User notice'],
428       ['exception', 'Not User notice'],
429     ];
430   }
431
432   /**
433    * @covers ::error
434    * @dataProvider providerError
435    */
436   public function testError($status, $group) {
437     // Mock up a TestBase object.
438     $mock_test_base = $this->getMockBuilder('Drupal\simpletest\TestBase')
439       ->setMethods(['assert'])
440       ->getMockForAbstractClass();
441
442     // Set expectations for assert().
443     $mock_test_base->expects($this->once())
444       ->method('assert')
445       // The first argument to assert() should be the expected $status. This is
446       // the most important expectation of this test.
447       ->with($status)
448       // Arbitrary return value.
449       ->willReturn("$status:$group");
450
451     // Invoke error().
452     $this->assertEquals(
453         "$status:$group",
454         $this->invokeProtectedMethod($mock_test_base, 'error', ['msg', $group])
455     );
456   }
457
458   /**
459    * @covers ::getRandomGenerator
460    */
461   public function testGetRandomGenerator() {
462     $test_base = $this->getTestBaseForAssertionTests('test_id');
463     $this->assertInstanceOf(
464         'Drupal\Component\Utility\Random',
465         $this->invokeProtectedMethod($test_base, 'getRandomGenerator', [])
466     );
467   }
468
469 }