e4ea6450cf563ae4df1120266948db85f3374851
[yaffs-website] / DerivativeDiscoveryDecoratorTest.php
1 <?php
2
3 namespace Drupal\Tests\Core\Plugin\Discovery;
4
5 use Drupal\Component\Plugin\Definition\DerivablePluginDefinitionInterface;
6 use Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator;
7 use Drupal\Component\Plugin\Exception\InvalidDeriverException;
8 use Drupal\Tests\UnitTestCase;
9
10 /**
11  * Unit tests for the derivative discovery decorator.
12  *
13  * @coversDefaultClass \Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator
14  *
15  * @group Plugin
16  */
17 class DerivativeDiscoveryDecoratorTest extends UnitTestCase {
18
19   /**
20    * The mock main discovery object.
21    *
22    * @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface|\PHPUnit_Framework_MockObject_MockObject
23    */
24   protected $discoveryMain;
25
26   /**
27    * {@inheritdoc}
28    */
29   protected function setUp() {
30     $this->discoveryMain = $discovery_main = $this->getMock('Drupal\Component\Plugin\Discovery\DiscoveryInterface');
31   }
32
33   /**
34    * Tests the getDerivativeFetcher method.
35    *
36    * @see \Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator::getDerivativeFetcher()
37    */
38   public function testGetDerivativeFetcher() {
39     $definitions = [];
40     $definitions['non_container_aware_discovery'] = [
41       'id' => 'non_container_aware_discovery',
42       'deriver' => '\Drupal\Tests\Core\Plugin\Discovery\TestDerivativeDiscovery',
43     ];
44
45     $this->discoveryMain->expects($this->any())
46       ->method('getDefinitions')
47       ->will($this->returnValue($definitions));
48
49     $discovery = new DerivativeDiscoveryDecorator($this->discoveryMain);
50     $definitions = $discovery->getDefinitions();
51
52     // Ensure that both test derivatives got added.
53     $this->assertEquals(2, count($definitions));
54     $this->assertEquals('non_container_aware_discovery', $definitions['non_container_aware_discovery:test_discovery_0']['id']);
55     $this->assertEquals('\Drupal\Tests\Core\Plugin\Discovery\TestDerivativeDiscovery', $definitions['non_container_aware_discovery:test_discovery_0']['deriver']);
56
57     $this->assertEquals('non_container_aware_discovery', $definitions['non_container_aware_discovery:test_discovery_1']['id']);
58     $this->assertEquals('\Drupal\Tests\Core\Plugin\Discovery\TestDerivativeDiscovery', $definitions['non_container_aware_discovery:test_discovery_1']['deriver']);
59   }
60
61   /**
62    * Tests the getDerivativeFetcher method with objects instead of arrays.
63    */
64   public function testGetDerivativeFetcherWithAnnotationObjects() {
65     $definitions = [];
66     $definitions['non_container_aware_discovery'] = (object) [
67       'id' => 'non_container_aware_discovery',
68       'deriver' => '\Drupal\Tests\Core\Plugin\Discovery\TestDerivativeDiscoveryWithObject',
69     ];
70
71     $this->discoveryMain->expects($this->any())
72       ->method('getDefinitions')
73       ->will($this->returnValue($definitions));
74
75     $discovery = new DerivativeDiscoveryDecorator($this->discoveryMain);
76     $definitions = $discovery->getDefinitions();
77
78     // Ensure that both test derivatives got added.
79     $this->assertEquals(2, count($definitions));
80     $this->assertInstanceOf('\stdClass', $definitions['non_container_aware_discovery:test_discovery_0']);
81     $this->assertEquals('non_container_aware_discovery', $definitions['non_container_aware_discovery:test_discovery_0']->id);
82     $this->assertEquals('\Drupal\Tests\Core\Plugin\Discovery\TestDerivativeDiscoveryWithObject', $definitions['non_container_aware_discovery:test_discovery_0']->deriver);
83
84     $this->assertInstanceOf('\stdClass', $definitions['non_container_aware_discovery:test_discovery_1']);
85     $this->assertEquals('non_container_aware_discovery', $definitions['non_container_aware_discovery:test_discovery_1']->id);
86     $this->assertEquals('\Drupal\Tests\Core\Plugin\Discovery\TestDerivativeDiscoveryWithObject', $definitions['non_container_aware_discovery:test_discovery_1']->deriver);
87   }
88
89   /**
90    * Tests getDeriverClass with classed objects instead of arrays.
91    *
92    * @covers ::getDeriverClass
93    */
94   public function testGetDeriverClassWithClassedDefinitions() {
95     $definitions = [];
96     $definition = $this->prophesize(DerivablePluginDefinitionInterface::class);
97     $definition->id()->willReturn('non_container_aware_discovery');
98     $definition->getDeriver()->willReturn(TestDerivativeDiscoveryWithObject::class);
99     $definitions['non_container_aware_discovery'] = $definition->reveal();
100
101     $this->discoveryMain->expects($this->any())
102       ->method('getDefinitions')
103       ->will($this->returnValue($definitions));
104
105     $discovery = new DerivativeDiscoveryDecorator($this->discoveryMain);
106     $definitions = $discovery->getDefinitions();
107
108     // Ensure that both test derivatives got added.
109     $this->assertContainsOnlyInstancesOf(DerivablePluginDefinitionInterface::class, $definitions);
110     $this->assertEquals(['non_container_aware_discovery:test_discovery_0', 'non_container_aware_discovery:test_discovery_1'], array_keys($definitions));
111   }
112
113   /**
114    * @covers ::getDeriverClass
115    */
116   public function testGetDeriverClassWithInvalidClassedDefinitions() {
117     $definition = $this->prophesize(DerivablePluginDefinitionInterface::class);
118     $definition->id()->willReturn('non_existent_discovery');
119     $definition->getDeriver()->willReturn('\Drupal\system\Tests\Plugin\NonExistentDeriver');
120
121     $definitions['non_existent_discovery'] = $definition->reveal();
122
123     $this->discoveryMain->expects($this->any())
124       ->method('getDefinitions')
125       ->willReturn($definitions);
126
127     $discovery = new DerivativeDiscoveryDecorator($this->discoveryMain);
128
129     $this->setExpectedException(InvalidDeriverException::class, 'Plugin (non_existent_discovery) deriver "\Drupal\system\Tests\Plugin\NonExistentDeriver" does not exist.');
130     $discovery->getDefinitions();
131   }
132
133   /**
134    * Tests the getDerivativeFetcher method with a non-existent class.
135    *
136    * @see \Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator::getDeriver().\
137    */
138   public function testNonExistentDerivativeFetcher() {
139     $definitions = [];
140     // Do this with a class that doesn't exist.
141     $definitions['non_existent_discovery'] = [
142       'id' => 'non_existent_discovery',
143       'deriver' => '\Drupal\system\Tests\Plugin\NonExistentDeriver',
144     ];
145     $this->discoveryMain->expects($this->any())
146       ->method('getDefinitions')
147       ->will($this->returnValue($definitions));
148
149     $discovery = new DerivativeDiscoveryDecorator($this->discoveryMain);
150     $this->setExpectedException(InvalidDeriverException::class, 'Plugin (non_existent_discovery) deriver "\Drupal\system\Tests\Plugin\NonExistentDeriver" does not exist.');
151     $discovery->getDefinitions();
152   }
153
154   /**
155    * Tests the getDerivativeFetcher method with an invalid class.
156    *
157    * @see \Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator::getDeriver().\
158    */
159   public function testInvalidDerivativeFetcher() {
160     $definitions = [];
161     // Do this with a class that doesn't implement the interface.
162     $definitions['invalid_discovery'] = [
163       'id' => 'invalid_discovery',
164       'deriver' => '\Drupal\KernelTests\Core\Plugin\DerivativeTest',
165     ];
166     $this->discoveryMain->expects($this->any())
167       ->method('getDefinitions')
168       ->will($this->returnValue($definitions));
169
170     $discovery = new DerivativeDiscoveryDecorator($this->discoveryMain);
171     $this->setExpectedException(InvalidDeriverException::class, 'Plugin (invalid_discovery) deriver "\Drupal\KernelTests\Core\Plugin\DerivativeTest" must implement \Drupal\Component\Plugin\Derivative\DeriverInterface.');
172     $discovery->getDefinitions();
173   }
174
175   /**
176    * Tests derivative definitions when a definition already exists.
177    */
178   public function testExistingDerivative() {
179     $definitions = [];
180     $definitions['non_container_aware_discovery'] = [
181       'id' => 'non_container_aware_discovery',
182       'deriver' => '\Drupal\Tests\Core\Plugin\Discovery\TestDerivativeDiscovery',
183       'string' => 'string',
184       'empty_string' => 'not_empty',
185       'array' => ['one', 'two'],
186       'empty_array' => ['three'],
187       'null_value' => TRUE,
188     ];
189     // This will clash with a derivative id.
190     // @see \Drupal\Tests\Core\Plugin\Discovery\TestDerivativeDiscovery
191     $definitions['non_container_aware_discovery:test_discovery_1'] = [
192       'id' => 'non_container_aware_discovery:test_discovery_1',
193       'string' => 'string',
194       'empty_string' => '',
195       'array' => ['one', 'two'],
196       'empty_array' => [],
197       'null_value' => NULL,
198     ];
199
200     $this->discoveryMain->expects($this->any())
201       ->method('getDefinitions')
202       ->will($this->returnValue($definitions));
203
204     $discovery = new DerivativeDiscoveryDecorator($this->discoveryMain);
205     $returned_definitions = $discovery->getDefinitions();
206
207     // If the definition was merged, there should only be two.
208     $this->assertCount(2, $returned_definitions);
209
210     $expected = $definitions['non_container_aware_discovery'];
211     $expected['id'] = 'non_container_aware_discovery:test_discovery_1';
212     $this->assertArrayEquals($expected, $returned_definitions['non_container_aware_discovery:test_discovery_1']);
213   }
214
215   /**
216    * Tests a single definition when a derivative already exists.
217    */
218   public function testSingleExistingDerivative() {
219     $base_definition = [
220       'id' => 'non_container_aware_discovery',
221       'deriver' => '\Drupal\Tests\Core\Plugin\Discovery\TestDerivativeDiscovery',
222       'string' => 'string',
223       'empty_string' => 'not_empty',
224       'array' => ['one', 'two'],
225       'empty_array' => ['three'],
226       'null_value' => TRUE,
227     ];
228     // This will clash with a derivative id.
229     // @see \Drupal\Tests\Core\Plugin\Discovery\TestDerivativeDiscovery
230     $derivative_definition = [
231       'id' => 'non_container_aware_discovery:test_discovery_1',
232       'string' => 'string',
233       'empty_string' => '',
234       'array' => ['one', 'two'],
235       'empty_array' => [],
236       'null_value' => NULL,
237     ];
238
239     $this->discoveryMain->expects($this->at(0))
240       ->method('getDefinition')
241       ->with('non_container_aware_discovery:test_discovery_1')
242       ->will($this->returnValue($derivative_definition));
243     $this->discoveryMain->expects($this->at(1))
244       ->method('getDefinition')
245       ->with('non_container_aware_discovery')
246       ->will($this->returnValue($base_definition));
247
248     $discovery = new DerivativeDiscoveryDecorator($this->discoveryMain);
249
250     $expected = $base_definition;
251     $expected['id'] = 'non_container_aware_discovery:test_discovery_1';
252     $this->assertArrayEquals($expected, $discovery->getDefinition('non_container_aware_discovery:test_discovery_1'));
253   }
254
255 }