3 namespace Drupal\Tests\Component\Plugin;
5 use Drupal\Component\Plugin\Exception\PluginNotFoundException;
6 use Drupal\Component\Plugin\Mapper\MapperInterface;
7 use Drupal\Component\Plugin\PluginManagerBase;
8 use PHPUnit\Framework\TestCase;
11 * @coversDefaultClass \Drupal\Component\Plugin\PluginManagerBase
14 class PluginManagerBaseTest extends TestCase {
17 * A callback method for mocking FactoryInterface objects.
19 public function createInstanceCallback() {
20 $args = func_get_args();
21 $plugin_id = $args[0];
22 $configuration = $args[1];
23 if ('invalid' == $plugin_id) {
24 throw new PluginNotFoundException($plugin_id);
27 'plugin_id' => $plugin_id,
28 'configuration' => $configuration,
33 * Generates a mocked FactoryInterface object with known properties.
35 public function getMockFactoryInterface($expects_count) {
36 $mock_factory = $this->getMockBuilder('Drupal\Component\Plugin\Factory\FactoryInterface')
37 ->setMethods(['createInstance'])
38 ->getMockForAbstractClass();
39 $mock_factory->expects($this->exactly($expects_count))
40 ->method('createInstance')
41 ->willReturnCallback([$this, 'createInstanceCallback']);
46 * Tests createInstance() with no fallback methods.
48 * @covers ::createInstance
50 public function testCreateInstance() {
51 $manager = $this->getMockBuilder('Drupal\Component\Plugin\PluginManagerBase')
52 ->getMockForAbstractClass();
53 // PluginManagerBase::createInstance() looks for a factory object and then
54 // calls createInstance() on it. So we have to mock a factory object.
55 $factory_ref = new \ReflectionProperty($manager, 'factory');
56 $factory_ref->setAccessible(TRUE);
57 $factory_ref->setValue($manager, $this->getMockFactoryInterface(1));
60 $configuration_array = ['config' => 'something'];
61 $result = $manager->createInstance('valid', $configuration_array);
62 $this->assertEquals('valid', $result['plugin_id']);
63 $this->assertEquals($configuration_array, $result['configuration']);
67 * Tests createInstance() with a fallback method.
69 * @covers ::createInstance
71 public function testCreateInstanceFallback() {
72 // We use our special stub class which extends PluginManagerBase and also
73 // implements FallbackPluginManagerInterface.
74 $manager = new StubFallbackPluginManager();
75 // Put our stubbed factory on the base object.
76 $factory_ref = new \ReflectionProperty($manager, 'factory');
77 $factory_ref->setAccessible(TRUE);
79 // Set up the configuration array.
80 $configuration_array = ['config' => 'something'];
82 // Test with fallback interface and valid plugin_id.
83 $factory_ref->setValue($manager, $this->getMockFactoryInterface(1));
84 $no_fallback_result = $manager->createInstance('valid', $configuration_array);
85 $this->assertEquals('valid', $no_fallback_result['plugin_id']);
86 $this->assertEquals($configuration_array, $no_fallback_result['configuration']);
88 // Test with fallback interface and invalid plugin_id.
89 $factory_ref->setValue($manager, $this->getMockFactoryInterface(2));
90 $fallback_result = $manager->createInstance('invalid', $configuration_array);
91 $this->assertEquals('invalid_fallback', $fallback_result['plugin_id']);
92 $this->assertEquals($configuration_array, $fallback_result['configuration']);
96 * @covers ::getInstance
98 public function testGetInstance() {
103 $instance = new \stdClass();
104 $mapper = $this->prophesize(MapperInterface::class);
105 $mapper->getInstance($options)
106 ->shouldBeCalledTimes(1)
107 ->willReturn($instance);
108 $manager = new StubPluginManagerBaseWithMapper($mapper->reveal());
109 $this->assertEquals($instance, $manager->getInstance($options));
113 * @covers ::getInstance
115 public function testGetInstanceWithoutMapperShouldThrowException() {
120 /** @var \Drupal\Component\Plugin\PluginManagerBase $manager */
121 $manager = $this->getMockBuilder(PluginManagerBase::class)
122 ->getMockForAbstractClass();
123 // Set the expected exception thrown by ::getInstance.
124 if (method_exists($this, 'expectException')) {
125 $this->expectException(\BadMethodCallException::class);
126 $this->expectExceptionMessage(sprintf('%s does not support this method unless %s::$mapper is set.', get_class($manager), get_class($manager)));
129 $this->setExpectedException(\BadMethodCallException::class, sprintf('%s does not support this method unless %s::$mapper is set.', get_class($manager), get_class($manager)));
131 $manager->getInstance($options);