simpletest-8.x-3.x-dev/tests/src/Unit/TestBaseTest.php
tests/src/Unit/TestBaseTest.php
<?php
namespace Drupal\Tests\simpletest\Unit;
use Drupal\Tests\UnitTestCase;
/**
* @requires extension curl
* @coversDefaultClass \Drupal\simpletest\TestBase
* @group simpletest
* @group TestBase
*/
class TestBaseTest extends UnitTestCase {
/**
* Helper method for constructing a mock TestBase object.
*
* TestBase is abstract, so we have to mock it. We'll also
* mock the storeAssertion() method so we don't need the database.
*
* @param string $test_id
* An identifying name for the mocked test.
*
* @return object
* Mock of Drupal\simpletest\TestBase.
*/
public function getTestBaseForAssertionTests($test_id) {
$mock_test_base = $this->getMockBuilder('Drupal\simpletest\TestBase')
->setConstructorArgs([$test_id])
->setMethods(['storeAssertion'])
->getMockForAbstractClass();
// Override storeAssertion() so we don't need a database.
$mock_test_base->expects($this->any())
->method('storeAssertion')
->will($this->returnValue(NULL));
return $mock_test_base;
}
/**
* Invoke methods that are protected or private.
*
* @param object $object
* Object on which to invoke the method.
* @param string $method_name
* Name of the method to invoke.
* @param array $arguments
* Array of arguments to be passed to the method.
*
* @return mixed
* Value returned by the invoked method.
*/
public function invokeProtectedMethod($object, $method_name, array $arguments) {
$ref_method = new \ReflectionMethod($object, $method_name);
$ref_method->setAccessible(TRUE);
return $ref_method->invokeArgs($object, $arguments);
}
/**
* Provides data for the random string validation test.
*
* @return array
* - The expected result of the validation.
* - The string to validate.
*/
public function providerRandomStringValidate() {
return [
[FALSE, ' curry paste'],
[FALSE, 'curry paste '],
[FALSE, 'curry paste'],
[FALSE, 'curry paste'],
[TRUE, 'curry paste'],
[TRUE, 'thai green curry paste'],
[TRUE, '@startswithat'],
[TRUE, 'contains@at'],
];
}
/**
* @covers ::randomStringValidate
* @dataProvider providerRandomStringValidate
*/
public function testRandomStringValidate($expected, $string) {
$mock_test_base = $this->getMockForAbstractClass('Drupal\simpletest\TestBase');
$actual = $mock_test_base->randomStringValidate($string);
$this->assertEquals($expected, $actual);
}
/**
* Provides data for testRandomString() and others.
*
* @return array
* - The number of items (characters, object properties) we expect any of
* the random functions to give us.
*/
public function providerRandomItems() {
return [
[NULL],
[0],
[1],
[2],
[3],
[4],
[7],
];
}
/**
* @covers ::randomString
* @dataProvider providerRandomItems
*/
public function testRandomString($length) {
$mock_test_base = $this->getMockForAbstractClass('Drupal\simpletest\TestBase');
$string = $mock_test_base->randomString($length);
$this->assertEquals($length, strlen($string));
// randomString() should always include an ampersand ('&') and a
// greater than ('>') if $length is greater than 3.
if ($length > 4) {
$this->assertContains('&', $string);
$this->assertContains('>', $string);
}
}
/**
* @covers ::randomObject
* @dataProvider providerRandomItems
*/
public function testRandomObject($size) {
$test_base = $this->getTestBaseForAssertionTests('test_id');
// Note: count((array)object) works for now, maybe not later.
$this->assertEquals($size, count((array) $test_base->randomObject($size)));
}
/**
* @covers ::checkRequirements
*/
public function testCheckRequirements() {
$test_base = $this->getTestBaseForAssertionTests('test_id');
$this->assertInternalType(
'array',
$this->invokeProtectedMethod($test_base, 'checkRequirements', [])
);
}
/**
* Data provider for testAssert().
*
* @return array
* Standard dataProvider array of arrays:
* - Expected result from assert().
* - Expected status stored in TestBase->assertions.
* - Status, passed to assert().
* - Message, passed to assert().
* - Group, passed to assert().
* - Caller, passed to assert().
*/
public function providerAssert() {
return [
[TRUE, 'pass', TRUE, 'Yay pass', 'test', []],
[FALSE, 'fail', FALSE, 'Boo fail', 'test', []],
[TRUE, 'pass', 'pass', 'Yay pass', 'test', []],
[FALSE, 'fail', 'fail', 'Boo fail', 'test', []],
[FALSE, 'exception', 'exception', 'Boo fail', 'test', []],
[FALSE, 'debug', 'debug', 'Boo fail', 'test', []],
];
}
/**
* @covers ::assert
* @dataProvider providerAssert
*/
public function testAssert($expected, $assertion_status, $status, $message, $group, $caller) {
$test_id = 'luke_i_am_your_' . $assertion_status;
$test_base = $this->getTestBaseForAssertionTests($test_id);
// Verify some startup values.
$this->assertAttributeEmpty('assertions', $test_base);
if (is_string($status)) {
$this->assertEquals(0, $test_base->results['#' . $status]);
}
// assert() is protected so we have to make it accessible.
$ref_assert = new \ReflectionMethod($test_base, 'assert');
$ref_assert->setAccessible(TRUE);
// Call assert() from within our hall of mirrors.
$this->assertEquals(
$expected,
$ref_assert->invokeArgs($test_base,
[$status, $message, $group, $caller]
)
);
// Check the side-effects of assert().
if (is_string($status)) {
$this->assertEquals(1, $test_base->results['#' . $status]);
}
$this->assertAttributeNotEmpty('assertions', $test_base);
// Make a ReflectionProperty for the assertions property,
// since it's protected.
$ref_assertions = new \ReflectionProperty($test_base, 'assertions');
$ref_assertions->setAccessible(TRUE);
$assertions = $ref_assertions->getValue($test_base);
$assertion = reset($assertions);
$this->assertEquals($assertion_status, $assertion['status']);
$this->assertEquals($test_id, $assertion['test_id']);
$this->assertEquals(get_class($test_base), $assertion['test_class']);
$this->assertEquals($message, $assertion['message']);
$this->assertEquals($group, $assertion['message_group']);
}
/**
* Data provider for assertTrue().
*/
public function providerAssertTrue() {
return [
[TRUE, TRUE],
[FALSE, FALSE],
];
}
/**
* @covers ::assertTrue
* @dataProvider providerAssertTrue
*/
public function testAssertTrue($expected, $value) {
$test_base = $this->getTestBaseForAssertionTests('test_id');
$this->assertEquals(
$expected,
$this->invokeProtectedMethod($test_base, 'assertTrue', [$value])
);
}
/**
* @covers ::assertFalse
* @dataProvider providerAssertTrue
*/
public function testAssertFalse($expected, $value) {
$test_base = $this->getTestBaseForAssertionTests('test_id');
$this->assertEquals(
(!$expected),
$this->invokeProtectedMethod($test_base, 'assertFalse', [$value])
);
}
/**
* Data provider for assertNull().
*/
public function providerAssertNull() {
return [
[TRUE, NULL],
[FALSE, ''],
];
}
/**
* @covers ::assertNull
* @dataProvider providerAssertNull
*/
public function testAssertNull($expected, $value) {
$test_base = $this->getTestBaseForAssertionTests('test_id');
$this->assertEquals(
$expected,
$this->invokeProtectedMethod($test_base, 'assertNull', [$value])
);
}
/**
* @covers ::assertNotNull
* @dataProvider providerAssertNull
*/
public function testAssertNotNull($expected, $value) {
$test_base = $this->getTestBaseForAssertionTests('test_id');
$this->assertEquals(
(!$expected),
$this->invokeProtectedMethod($test_base, 'assertNotNull', [$value])
);
}
/**
* Data provider for tests of equality assertions.
*
* Used by testAssertIdentical(), testAssertEqual(), testAssertNotIdentical(),
* and testAssertNotEqual().
*
* @return
* Array of test data.
* - Expected assertion value for identical comparison.
* - Expected assertion value for equal comparison.
* - First value to compare.
* - Second value to compare.
*/
public function providerEqualityAssertions() {
return [
// Integers and floats.
[TRUE, TRUE, 0, 0],
[FALSE, TRUE, 0, 0.0],
[FALSE, TRUE, '0', 0],
[FALSE, TRUE, '0.0', 0.0],
[FALSE, FALSE, 23, 77],
[TRUE, TRUE, 23.0, 23.0],
// Strings.
[FALSE, FALSE, 'foof', 'yay'],
[TRUE, TRUE, 'yay', 'yay'],
// Bools with type conversion.
[TRUE, TRUE, TRUE, TRUE],
[TRUE, TRUE, FALSE, FALSE],
[FALSE, TRUE, NULL, FALSE],
[FALSE, TRUE, 'TRUE', TRUE],
[FALSE, FALSE, 'FALSE', FALSE],
[FALSE, TRUE, 0, FALSE],
[FALSE, TRUE, 1, TRUE],
[FALSE, TRUE, -1, TRUE],
[FALSE, TRUE, '1', TRUE],
[FALSE, TRUE, '1.3', TRUE],
// Null.
[FALSE, FALSE, 'NULL', NULL],
[TRUE, TRUE, NULL, NULL],
];
}
/**
* @covers ::assertIdentical
* @dataProvider providerEqualityAssertions
*/
public function testAssertIdentical($expected_identical, $expected_equal, $first, $second) {
$test_base = $this->getTestBaseForAssertionTests('test_id');
$this->assertEquals(
$expected_identical,
$this->invokeProtectedMethod($test_base, 'assertIdentical', [$first, $second])
);
}
/**
* @covers ::assertNotIdentical
* @dataProvider providerEqualityAssertions
*/
public function testAssertNotIdentical($expected_identical, $expected_equal, $first, $second) {
$test_base = $this->getTestBaseForAssertionTests('test_id');
$this->assertEquals(
(!$expected_identical),
$this->invokeProtectedMethod($test_base, 'assertNotIdentical', [$first, $second])
);
}
/**
* @covers ::assertEqual
* @dataProvider providerEqualityAssertions
*/
public function testAssertEqual($expected_identical, $expected_equal, $first, $second) {
$test_base = $this->getTestBaseForAssertionTests('test_id');
$this->assertEquals(
$expected_equal,
$this->invokeProtectedMethod($test_base, 'assertEqual', [$first, $second])
);
}
/**
* @covers ::assertNotEqual
* @dataProvider providerEqualityAssertions
*/
public function testAssertNotEqual($expected_identical, $expected_equal, $first, $second) {
$test_base = $this->getTestBaseForAssertionTests('test_id');
$this->assertEquals(
(!$expected_equal),
$this->invokeProtectedMethod($test_base, 'assertNotEqual', [$first, $second])
);
}
/**
* Data provider for testAssertIdenticalObject().
*/
public function providerAssertIdenticalObject() {
$obj1 = new \stdClass();
$obj1->foof = 'yay';
$obj2 = $obj1;
$obj3 = clone $obj1;
$obj4 = new \stdClass();
return [
[TRUE, $obj1, $obj2],
[TRUE, $obj1, $obj3],
[FALSE, $obj1, $obj4],
];
}
/**
* @covers ::assertIdenticalObject
* @dataProvider providerAssertIdenticalObject
*/
public function testAssertIdenticalObject($expected, $first, $second) {
$test_base = $this->getTestBaseForAssertionTests('test_id');
$this->assertEquals(
$expected,
$this->invokeProtectedMethod($test_base, 'assertIdenticalObject', [$first, $second])
);
}
/**
* @covers ::pass
*/
public function testPass() {
$test_base = $this->getTestBaseForAssertionTests('test_id');
$this->assertEquals(
TRUE,
$this->invokeProtectedMethod($test_base, 'pass', [])
);
}
/**
* @covers ::fail
*/
public function testFail() {
$test_base = $this->getTestBaseForAssertionTests('test_id');
$this->assertEquals(
FALSE,
$this->invokeProtectedMethod($test_base, 'fail', [])
);
}
/**
* Data provider for testError().
*
* @return array
* - Expected status for assertion.
* - Group for use in assert().
*/
public function providerError() {
return [
['debug', 'User notice'],
['exception', 'Not User notice'],
];
}
/**
* @covers ::error
* @dataProvider providerError
*/
public function testError($status, $group) {
// Mock up a TestBase object.
$mock_test_base = $this->getMockBuilder('Drupal\simpletest\TestBase')
->setMethods(['assert'])
->getMockForAbstractClass();
// Set expectations for assert().
$mock_test_base->expects($this->once())
->method('assert')
// The first argument to assert() should be the expected $status. This is
// the most important expectation of this test.
->with($status)
// Arbitrary return value.
->willReturn("$status:$group");
// Invoke error().
$this->assertEquals(
"$status:$group",
$this->invokeProtectedMethod($mock_test_base, 'error', ['msg', $group])
);
}
/**
* @covers ::getRandomGenerator
*/
public function testGetRandomGenerator() {
$test_base = $this->getTestBaseForAssertionTests('test_id');
$this->assertInstanceOf(
'Drupal\Component\Utility\Random',
$this->invokeProtectedMethod($test_base, 'getRandomGenerator', [])
);
}
}
