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 if (method_exists($this, 'expectException')) {
104 $this->expectException('Drupal\Component\Plugin\Exception\PluginNotFoundException');
107 $this->setExpectedException('Drupal\Component\Plugin\Exception\PluginNotFoundException');
111 // Exercise getDefinition(). It calls parent::getDefinition().
114 $mock_decorator->getDefinition($base_plugin_id, $exception_on_invalid)
119 * Data provider for testGetDefinitions().
122 * - bool Whether the test mock has a callback.
123 * - array Plugin definitions.
125 public function providerGetDefinitions() {
127 [TRUE, ['definition' => 'is_fake']],
128 [FALSE, ['definition' => 'array_of_stuff']],
133 * @covers ::getDefinitions
134 * @dataProvider providerGetDefinitions
136 public function testGetDefinitions($has_register_definitions, $definitions) {
137 // Mock our StaticDiscoveryDecorator.
138 $mock_decorator = $this->getMockBuilder('Drupal\Component\Plugin\Discovery\StaticDiscoveryDecorator')
139 ->disableOriginalConstructor()
140 ->setMethods(['registeredDefintionCallback'])
143 // Set up the ::$registerDefinitions property.
144 $ref_register_definitions = new \ReflectionProperty($mock_decorator, 'registerDefinitions');
145 $ref_register_definitions->setAccessible(TRUE);
146 if ($has_register_definitions) {
147 // Set the callback object on the mocked decorator.
148 $ref_register_definitions->setValue(
150 [$this->getRegisterDefinitionsCallback(), 'registerDefinitionsCallback']
154 // There should be no registerDefinitions callback.
155 $ref_register_definitions->setValue($mock_decorator, NULL);
158 // Set up ::$definitions to an empty array.
159 $ref_definitions = new \ReflectionProperty($mock_decorator, 'definitions');
160 $ref_definitions->setAccessible(TRUE);
161 $ref_definitions->setValue($mock_decorator, []);
163 // Mock a decorated object.
164 $mock_decorated = $this->getMockBuilder('Drupal\Component\Plugin\Discovery\DiscoveryInterface')
165 ->setMethods(['getDefinitions'])
166 ->getMockForAbstractClass();
167 // Our mocked method will return any arguments sent to it.
168 $mock_decorated->expects($this->once())
169 ->method('getDefinitions')
170 ->willReturn($definitions);
172 // Set up ::$decorated to our mocked decorated object.
173 $ref_decorated = new \ReflectionProperty($mock_decorator, 'decorated');
174 $ref_decorated->setAccessible(TRUE);
175 $ref_decorated->setValue($mock_decorator, $mock_decorated);
177 // Exercise getDefinitions(). It calls parent::getDefinitions() but in this
178 // case there will be no side-effects.
181 $mock_decorator->getDefinitions()
186 * Data provider for testCall().
190 * - Array of arguments to pass to the method, with the expectation that our
191 * mocked __call() will return them.
193 public function providerCall() {
195 ['complexArguments', ['1', 2.0, 3, ['4' => 'five']]],
202 * @dataProvider providerCall
204 public function testCall($method, $args) {
205 // Mock a decorated object.
206 $mock_decorated = $this->getMockBuilder('Drupal\Component\Plugin\Discovery\DiscoveryInterface')
207 ->setMethods([$method])
208 ->getMockForAbstractClass();
209 // Our mocked method will return any arguments sent to it.
210 $mock_decorated->expects($this->once())
212 ->willReturnCallback(
214 return \func_get_args();
218 // Create a mock decorator.
219 $mock_decorator = $this->getMockBuilder('Drupal\Component\Plugin\Discovery\StaticDiscoveryDecorator')
220 ->disableOriginalConstructor()
222 // Poke the decorated object into our decorator.
223 $ref_decorated = new \ReflectionProperty($mock_decorator, 'decorated');
224 $ref_decorated->setAccessible(TRUE);
225 $ref_decorated->setValue($mock_decorator, $mock_decorated);
230 \call_user_func_array([$mock_decorated, $method], $args)