class StaticDiscoveryDecoratorTest

Same name in other branches
  1. 9 core/tests/Drupal/Tests/Component/Plugin/Discovery/StaticDiscoveryDecoratorTest.php \Drupal\Tests\Component\Plugin\Discovery\StaticDiscoveryDecoratorTest
  2. 8.9.x core/tests/Drupal/Tests/Component/Plugin/Discovery/StaticDiscoveryDecoratorTest.php \Drupal\Tests\Component\Plugin\Discovery\StaticDiscoveryDecoratorTest
  3. 10 core/tests/Drupal/Tests/Component/Plugin/Discovery/StaticDiscoveryDecoratorTest.php \Drupal\Tests\Component\Plugin\Discovery\StaticDiscoveryDecoratorTest

@group Plugin @coversDefaultClass \Drupal\Component\Plugin\Discovery\StaticDiscoveryDecorator

Hierarchy

Expanded class hierarchy of StaticDiscoveryDecoratorTest

File

core/tests/Drupal/Tests/Component/Plugin/Discovery/StaticDiscoveryDecoratorTest.php, line 16

Namespace

Drupal\Tests\Component\Plugin\Discovery
View source
class StaticDiscoveryDecoratorTest extends TestCase {
    
    /**
     * Helper method to provide a mocked callback object with expectations.
     *
     * If there should be a registered definition, then we have to place a
     * \Callable in the mock object. The return value of this callback is
     * never used.
     *
     * @return \PHPUnit\Framework\MockObject\MockObject
     *   Mocked object with expectation of registerDefinitionsCallback() being
     *   called once.
     */
    public function getRegisterDefinitionsCallback() {
        $mock_callable = $this->createMock(StaticDiscoveryDecoratorTestMockInterface::class);
        // Set expectations for the callback method.
        $mock_callable->expects($this->once())
            ->method('registerDefinitionsCallback');
        return $mock_callable;
    }
    
    /**
     * Data provider for testGetDefinitions().
     *
     * @return array
     *   - Expected plugin definition.
     *   - Whether we require the method to register definitions through a
     *     callback.
     *   - Whether to throw an exception if the definition is invalid.
     *   - A plugin definition.
     *   - Base plugin ID.
     */
    public static function providerGetDefinition() {
        return [
            [
                'is_defined',
                TRUE,
                FALSE,
                [
                    'plugin-definition' => 'is_defined',
                ],
                'plugin-definition',
            ],
            // Make sure we don't call the decorated method if we shouldn't.
[
                'is_defined',
                FALSE,
                FALSE,
                [
                    'plugin-definition' => 'is_defined',
                ],
                'plugin-definition',
            ],
            // Return NULL for bad plugin id.
[
                NULL,
                FALSE,
                FALSE,
                [
                    'plugin-definition' => 'is_defined',
                ],
                'BAD-plugin-definition',
            ],
            // Generate an exception.
[
                NULL,
                FALSE,
                TRUE,
                [
                    'plugin-definition' => 'is_defined',
                ],
                'BAD-plugin-definition',
            ],
        ];
    }
    
    /**
     * @covers ::getDefinition
     * @dataProvider providerGetDefinition
     */
    public function testGetDefinition($expected, $has_register_definitions, $exception_on_invalid, $definitions, $base_plugin_id) : void {
        // Mock our StaticDiscoveryDecorator.
        $mock_decorator = $this->getMockBuilder(StaticDiscoveryDecorator::class)
            ->disableOriginalConstructor()
            ->onlyMethods([])
            ->getMock();
        // Set up the ::$registerDefinitions property.
        $ref_register_definitions = new \ReflectionProperty($mock_decorator, 'registerDefinitions');
        if ($has_register_definitions) {
            // Set the callback object on the mocked decorator.
            $ref_register_definitions->setValue($mock_decorator, [
                $this->getRegisterDefinitionsCallback(),
                'registerDefinitionsCallback',
            ]);
        }
        else {
            // There should be no registerDefinitions callback.
            $ref_register_definitions->setValue($mock_decorator, NULL);
        }
        // Set up ::$definitions to an empty array.
        $ref_definitions = new \ReflectionProperty($mock_decorator, 'definitions');
        $ref_definitions->setValue($mock_decorator, []);
        // Mock a decorated object.
        $mock_decorated = $this->createMock(DiscoveryInterface::class);
        // Return our definitions from getDefinitions().
        $mock_decorated->expects($this->once())
            ->method('getDefinitions')
            ->willReturn($definitions);
        // Set up ::$decorated to our mocked decorated object.
        $ref_decorated = new \ReflectionProperty($mock_decorator, 'decorated');
        $ref_decorated->setValue($mock_decorator, $mock_decorated);
        if ($exception_on_invalid) {
            $this->expectException('Drupal\\Component\\Plugin\\Exception\\PluginNotFoundException');
        }
        // Exercise getDefinition(). It calls parent::getDefinition().
        $this->assertEquals($expected, $mock_decorator->getDefinition($base_plugin_id, $exception_on_invalid));
    }
    
    /**
     * Data provider for testGetDefinitions().
     *
     * @return array
     *   - bool Whether the test mock has a callback.
     *   - array Plugin definitions.
     */
    public static function providerGetDefinitions() {
        return [
            [
                TRUE,
                [
                    'definition' => 'is_fake',
                ],
            ],
            [
                FALSE,
                [
                    'definition' => 'array_of_stuff',
                ],
            ],
        ];
    }
    
    /**
     * @covers ::getDefinitions
     * @dataProvider providerGetDefinitions
     */
    public function testGetDefinitions($has_register_definitions, $definitions) : void {
        // Mock our StaticDiscoveryDecorator.
        $mock_decorator = $this->getMockBuilder(StaticDiscoveryDecorator::class)
            ->disableOriginalConstructor()
            ->onlyMethods([])
            ->getMock();
        // Set up the ::$registerDefinitions property.
        $ref_register_definitions = new \ReflectionProperty($mock_decorator, 'registerDefinitions');
        if ($has_register_definitions) {
            // Set the callback object on the mocked decorator.
            $ref_register_definitions->setValue($mock_decorator, [
                $this->getRegisterDefinitionsCallback(),
                'registerDefinitionsCallback',
            ]);
        }
        else {
            // There should be no registerDefinitions callback.
            $ref_register_definitions->setValue($mock_decorator, NULL);
        }
        // Set up ::$definitions to an empty array.
        $ref_definitions = new \ReflectionProperty($mock_decorator, 'definitions');
        $ref_definitions->setValue($mock_decorator, []);
        // Mock a decorated object.
        $mock_decorated = $this->createMock(DiscoveryInterface::class);
        // Our mocked method will return any arguments sent to it.
        $mock_decorated->expects($this->once())
            ->method('getDefinitions')
            ->willReturn($definitions);
        // Set up ::$decorated to our mocked decorated object.
        $ref_decorated = new \ReflectionProperty($mock_decorator, 'decorated');
        $ref_decorated->setValue($mock_decorator, $mock_decorated);
        // Exercise getDefinitions(). It calls parent::getDefinitions() but in this
        // case there will be no side-effects.
        $this->assertEquals($definitions, $mock_decorator->getDefinitions());
    }
    
    /**
     * Data provider for testCall().
     *
     * @return array
     *   - Method name.
     *   - Array of arguments to pass to the method, with the expectation that our
     *     mocked __call() will return them.
     */
    public static function providerCall() {
        return [
            [
                'complexArguments',
                [
                    '1',
                    2.0,
                    3,
                    [
                        '4' => 'five',
                    ],
                ],
            ],
            [
                'noArguments',
                [],
            ],
        ];
    }
    
    /**
     * @covers ::__call
     * @dataProvider providerCall
     */
    public function testCall($method, $args) : void {
        // Mock a decorated object.
        $mock_decorated = $this->getMockBuilder(StaticDiscoveryTestDecoratedClass::class)
            ->onlyMethods([
            $method,
        ])
            ->getMock();
        // Our mocked method will return any arguments sent to it.
        $mock_decorated->expects($this->once())
            ->method($method)
            ->willReturnCallback(function () {
            return \func_get_args();
        });
        // Create the decorator.
        $decorator = new StaticDiscoveryDecorator($mock_decorated);
        // Exercise __call on the decorator.
        $this->assertEquals($args, \call_user_func_array([
            $decorator,
            $method,
        ], $args));
    }

}

Members

Title Sort descending Modifiers Object type Summary
StaticDiscoveryDecoratorTest::getRegisterDefinitionsCallback public function Helper method to provide a mocked callback object with expectations.
StaticDiscoveryDecoratorTest::providerCall public static function Data provider for testCall().
StaticDiscoveryDecoratorTest::providerGetDefinition public static function Data provider for testGetDefinitions().
StaticDiscoveryDecoratorTest::providerGetDefinitions public static function Data provider for testGetDefinitions().
StaticDiscoveryDecoratorTest::testCall public function @covers ::__call
@dataProvider providerCall
StaticDiscoveryDecoratorTest::testGetDefinition public function @covers ::getDefinition
@dataProvider providerGetDefinition
StaticDiscoveryDecoratorTest::testGetDefinitions public function @covers ::getDefinitions
@dataProvider providerGetDefinitions

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