TestBaseTest.php

Namespace

Drupal\Tests\simpletest\Unit

File

core/modules/simpletest/tests/src/Unit/TestBaseTest.php

View source
<?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')
            ->with($status)
            ->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', []));
    }

}

Classes

Title Deprecated Summary
TestBaseTest @requires extension curl @coversDefaultClass \Drupal\simpletest\TestBase @group simpletest @group TestBase

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.