3 namespace Drupal\Tests\Component\Plugin\Discovery;
5 use PHPUnit\Framework\TestCase;
9 * @coversDefaultClass \Drupal\Component\Plugin\Discovery\StaticDiscoveryDecorator
11 class StaticDiscoveryDecoratorTest extends TestCase {
14 * Helper method to provide a mocked callback object with expectations.
16 * If there should be a registered definition, then we have to place a
17 * \Callable in the mock object. The return value of this callback is
20 * @return \PHPUnit_Framework_MockObject_MockObject
21 * Mocked object with expectation of registerDefinitionsCallback() being
24 public function getRegisterDefinitionsCallback() {
25 $mock_callable = $this->getMockBuilder('\stdClass')
26 ->setMethods(['registerDefinitionsCallback'])
28 // Set expectations for the callback method.
29 $mock_callable->expects($this->once())
30 ->method('registerDefinitionsCallback');
31 return $mock_callable;
35 * Data provider for testGetDefinitions().
38 * - Expected plugin definition.
39 * - Whether we require the method to register definitions through a
41 * - Whether to throw an exception if the definition is invalid.
42 * - A plugin definition.
45 public function providerGetDefinition() {
47 ['is_defined', TRUE, FALSE, ['plugin-definition' => 'is_defined'], 'plugin-definition'],
48 // Make sure we don't call the decorated method if we shouldn't.
49 ['is_defined', FALSE, FALSE, ['plugin-definition' => 'is_defined'], 'plugin-definition'],
50 // Return NULL for bad plugin id.
51 [NULL, FALSE, FALSE, ['plugin-definition' => 'is_defined'], 'BAD-plugin-definition'],
52 // Generate an exception.
53 [NULL, FALSE, TRUE, ['plugin-definition' => 'is_defined'], 'BAD-plugin-definition'],
58 * @covers ::getDefinition
59 * @dataProvider providerGetDefinition
61 public function testGetDefinition($expected, $has_register_definitions, $exception_on_invalid, $definitions, $base_plugin_id) {
62 // Mock our StaticDiscoveryDecorator.
63 $mock_decorator = $this->getMockBuilder('Drupal\Component\Plugin\Discovery\StaticDiscoveryDecorator')
64 ->disableOriginalConstructor()
65 ->setMethods(['registeredDefintionCallback'])
68 // Set up the ::$registerDefinitions property.
69 $ref_register_definitions = new \ReflectionProperty($mock_decorator, 'registerDefinitions');
70 $ref_register_definitions->setAccessible(TRUE);
71 if ($has_register_definitions) {
72 // Set the callback object on the mocked decorator.
73 $ref_register_definitions->setValue(
75 [$this->getRegisterDefinitionsCallback(), 'registerDefinitionsCallback']
79 // There should be no registerDefinitions callback.
80 $ref_register_definitions->setValue($mock_decorator, NULL);
83 // Set up ::$definitions to an empty array.
84 $ref_definitions = new \ReflectionProperty($mock_decorator, 'definitions');
85 $ref_definitions->setAccessible(TRUE);
86 $ref_definitions->setValue($mock_decorator, []);
88 // Mock a decorated object.
89 $mock_decorated = $this->getMockBuilder('Drupal\Component\Plugin\Discovery\DiscoveryInterface')
90 ->setMethods(['getDefinitions'])
91 ->getMockForAbstractClass();
92 // Return our definitions from getDefinitions().
93 $mock_decorated->expects($this->once())
94 ->method('getDefinitions')
95 ->willReturn($definitions);
97 // Set up ::$decorated to our mocked decorated object.
98 $ref_decorated = new \ReflectionProperty($mock_decorator, 'decorated');
99 $ref_decorated->setAccessible(TRUE);
100 $ref_decorated->setValue($mock_decorator, $mock_decorated);
102 if ($exception_on_invalid) {
103 $this->setExpectedException('Drupal\Component\Plugin\Exception\PluginNotFoundException');
106 // Exercise getDefinition(). It calls parent::getDefinition().
109 $mock_decorator->getDefinition($base_plugin_id, $exception_on_invalid)
114 * Data provider for testGetDefinitions().
117 * - bool Whether the test mock has a callback.
118 * - array Plugin definitions.
120 public function providerGetDefinitions() {
122 [TRUE, ['definition' => 'is_fake']],
123 [FALSE, ['definition' => 'array_of_stuff']],
128 * @covers ::getDefinitions
129 * @dataProvider providerGetDefinitions
131 public function testGetDefinitions($has_register_definitions, $definitions) {
132 // Mock our StaticDiscoveryDecorator.
133 $mock_decorator = $this->getMockBuilder('Drupal\Component\Plugin\Discovery\StaticDiscoveryDecorator')
134 ->disableOriginalConstructor()
135 ->setMethods(['registeredDefintionCallback'])
138 // Set up the ::$registerDefinitions property.
139 $ref_register_definitions = new \ReflectionProperty($mock_decorator, 'registerDefinitions');
140 $ref_register_definitions->setAccessible(TRUE);
141 if ($has_register_definitions) {
142 // Set the callback object on the mocked decorator.
143 $ref_register_definitions->setValue(
145 [$this->getRegisterDefinitionsCallback(), 'registerDefinitionsCallback']
149 // There should be no registerDefinitions callback.
150 $ref_register_definitions->setValue($mock_decorator, NULL);
153 // Set up ::$definitions to an empty array.
154 $ref_definitions = new \ReflectionProperty($mock_decorator, 'definitions');
155 $ref_definitions->setAccessible(TRUE);
156 $ref_definitions->setValue($mock_decorator, []);
158 // Mock a decorated object.
159 $mock_decorated = $this->getMockBuilder('Drupal\Component\Plugin\Discovery\DiscoveryInterface')
160 ->setMethods(['getDefinitions'])
161 ->getMockForAbstractClass();
162 // Our mocked method will return any arguments sent to it.
163 $mock_decorated->expects($this->once())
164 ->method('getDefinitions')
165 ->willReturn($definitions);
167 // Set up ::$decorated to our mocked decorated object.
168 $ref_decorated = new \ReflectionProperty($mock_decorator, 'decorated');
169 $ref_decorated->setAccessible(TRUE);
170 $ref_decorated->setValue($mock_decorator, $mock_decorated);
172 // Exercise getDefinitions(). It calls parent::getDefinitions() but in this
173 // case there will be no side-effects.
176 $mock_decorator->getDefinitions()
181 * Data provider for testCall().
185 * - Array of arguments to pass to the method, with the expectation that our
186 * mocked __call() will return them.
188 public function providerCall() {
190 ['complexArguments', ['1', 2.0, 3, ['4' => 'five']]],
197 * @dataProvider providerCall
199 public function testCall($method, $args) {
200 // Mock a decorated object.
201 $mock_decorated = $this->getMockBuilder('Drupal\Component\Plugin\Discovery\DiscoveryInterface')
202 ->setMethods([$method])
203 ->getMockForAbstractClass();
204 // Our mocked method will return any arguments sent to it.
205 $mock_decorated->expects($this->once())
207 ->willReturnCallback(
209 return \func_get_args();
213 // Create a mock decorator.
214 $mock_decorator = $this->getMockBuilder('Drupal\Component\Plugin\Discovery\StaticDiscoveryDecorator')
215 ->disableOriginalConstructor()
217 // Poke the decorated object into our decorator.
218 $ref_decorated = new \ReflectionProperty($mock_decorator, 'decorated');
219 $ref_decorated->setAccessible(TRUE);
220 $ref_decorated->setValue($mock_decorator, $mock_decorated);
225 \call_user_func_array([$mock_decorated, $method], $args)