Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 /**
|
Chris@0
|
4 * @file
|
Chris@0
|
5 * Contains \Drupal\Tests\Component\ProxyBuilder\ProxyBuilderTest.
|
Chris@0
|
6 */
|
Chris@0
|
7
|
Chris@0
|
8 namespace Drupal\Tests\Component\ProxyBuilder;
|
Chris@0
|
9
|
Chris@0
|
10 use Drupal\Component\ProxyBuilder\ProxyBuilder;
|
Chris@0
|
11 use PHPUnit\Framework\TestCase;
|
Chris@0
|
12
|
Chris@0
|
13 /**
|
Chris@0
|
14 * @coversDefaultClass \Drupal\Component\ProxyBuilder\ProxyBuilder
|
Chris@0
|
15 * @group proxy_builder
|
Chris@0
|
16 */
|
Chris@0
|
17 class ProxyBuilderTest extends TestCase {
|
Chris@0
|
18
|
Chris@0
|
19 /**
|
Chris@0
|
20 * The tested proxy builder.
|
Chris@0
|
21 *
|
Chris@0
|
22 * @var \Drupal\Component\ProxyBuilder\ProxyBuilder
|
Chris@0
|
23 */
|
Chris@0
|
24 protected $proxyBuilder;
|
Chris@0
|
25
|
Chris@0
|
26 /**
|
Chris@0
|
27 * {@inheritdoc}
|
Chris@0
|
28 */
|
Chris@0
|
29 protected function setUp() {
|
Chris@0
|
30 parent::setUp();
|
Chris@0
|
31
|
Chris@0
|
32 $this->proxyBuilder = new ProxyBuilder();
|
Chris@0
|
33 }
|
Chris@0
|
34
|
Chris@0
|
35 /**
|
Chris@0
|
36 * @covers ::buildProxyClassName
|
Chris@0
|
37 */
|
Chris@0
|
38 public function testBuildProxyClassName() {
|
Chris@0
|
39 $class_name = $this->proxyBuilder->buildProxyClassName('Drupal\Tests\Component\ProxyBuilder\TestServiceNoMethod');
|
Chris@0
|
40 $this->assertEquals('Drupal\Tests\ProxyClass\Component\ProxyBuilder\TestServiceNoMethod', $class_name);
|
Chris@0
|
41 }
|
Chris@0
|
42
|
Chris@0
|
43 /**
|
Chris@0
|
44 * @covers ::buildProxyClassName
|
Chris@0
|
45 */
|
Chris@0
|
46 public function testBuildProxyClassNameForModule() {
|
Chris@0
|
47 $class_name = $this->proxyBuilder->buildProxyClassName('Drupal\views_ui\ParamConverter\ViewUIConverter');
|
Chris@0
|
48 $this->assertEquals('Drupal\views_ui\ProxyClass\ParamConverter\ViewUIConverter', $class_name);
|
Chris@0
|
49 }
|
Chris@0
|
50
|
Chris@0
|
51 /**
|
Chris@0
|
52 * @covers ::buildProxyNamespace
|
Chris@0
|
53 */
|
Chris@0
|
54 public function testBuildProxyNamespace() {
|
Chris@0
|
55 $class_name = $this->proxyBuilder->buildProxyNamespace('Drupal\Tests\Component\ProxyBuilder\TestServiceNoMethod');
|
Chris@0
|
56 $this->assertEquals('Drupal\Tests\ProxyClass\Component\ProxyBuilder', $class_name);
|
Chris@0
|
57 }
|
Chris@0
|
58
|
Chris@0
|
59 /**
|
Chris@0
|
60 * Tests the basic methods like the constructor and the lazyLoadItself method.
|
Chris@0
|
61 *
|
Chris@0
|
62 * @covers ::build
|
Chris@0
|
63 * @covers ::buildConstructorMethod
|
Chris@0
|
64 * @covers ::buildLazyLoadItselfMethod
|
Chris@0
|
65 */
|
Chris@0
|
66 public function testBuildNoMethod() {
|
Chris@0
|
67 $class = 'Drupal\Tests\Component\ProxyBuilder\TestServiceNoMethod';
|
Chris@0
|
68
|
Chris@0
|
69 $result = $this->proxyBuilder->build($class);
|
Chris@0
|
70 $this->assertEquals($this->buildExpectedClass($class, ''), $result);
|
Chris@0
|
71 }
|
Chris@0
|
72
|
Chris@0
|
73 /**
|
Chris@0
|
74 * @covers ::buildMethod
|
Chris@0
|
75 * @covers ::buildMethodBody
|
Chris@0
|
76 */
|
Chris@0
|
77 public function testBuildSimpleMethod() {
|
Chris@0
|
78 $class = 'Drupal\Tests\Component\ProxyBuilder\TestServiceSimpleMethod';
|
Chris@0
|
79
|
Chris@0
|
80 $result = $this->proxyBuilder->build($class);
|
Chris@0
|
81
|
Chris@0
|
82 $method_body = <<<'EOS'
|
Chris@0
|
83
|
Chris@0
|
84 /**
|
Chris@0
|
85 * {@inheritdoc}
|
Chris@0
|
86 */
|
Chris@0
|
87 public function method()
|
Chris@0
|
88 {
|
Chris@0
|
89 return $this->lazyLoadItself()->method();
|
Chris@0
|
90 }
|
Chris@0
|
91
|
Chris@0
|
92 EOS;
|
Chris@0
|
93 $this->assertEquals($this->buildExpectedClass($class, $method_body), $result);
|
Chris@0
|
94 }
|
Chris@0
|
95
|
Chris@0
|
96 /**
|
Chris@0
|
97 * @covers ::buildMethod
|
Chris@0
|
98 * @covers ::buildParameter
|
Chris@0
|
99 * @covers ::buildMethodBody
|
Chris@0
|
100 */
|
Chris@0
|
101 public function testBuildMethodWithParameter() {
|
Chris@0
|
102 $class = 'Drupal\Tests\Component\ProxyBuilder\TestServiceMethodWithParameter';
|
Chris@0
|
103
|
Chris@0
|
104 $result = $this->proxyBuilder->build($class);
|
Chris@0
|
105
|
Chris@0
|
106 $method_body = <<<'EOS'
|
Chris@0
|
107
|
Chris@0
|
108 /**
|
Chris@0
|
109 * {@inheritdoc}
|
Chris@0
|
110 */
|
Chris@0
|
111 public function methodWithParameter($parameter)
|
Chris@0
|
112 {
|
Chris@0
|
113 return $this->lazyLoadItself()->methodWithParameter($parameter);
|
Chris@0
|
114 }
|
Chris@0
|
115
|
Chris@0
|
116 EOS;
|
Chris@0
|
117 $this->assertEquals($this->buildExpectedClass($class, $method_body), $result);
|
Chris@0
|
118 }
|
Chris@0
|
119
|
Chris@0
|
120 /**
|
Chris@0
|
121 * @covers ::buildMethod
|
Chris@0
|
122 * @covers ::buildParameter
|
Chris@0
|
123 * @covers ::buildMethodBody
|
Chris@0
|
124 */
|
Chris@0
|
125 public function testBuildComplexMethod() {
|
Chris@0
|
126 $class = 'Drupal\Tests\Component\ProxyBuilder\TestServiceComplexMethod';
|
Chris@0
|
127
|
Chris@0
|
128 $result = $this->proxyBuilder->build($class);
|
Chris@0
|
129
|
Chris@0
|
130 // @todo Solve the silly linebreak for array()
|
Chris@0
|
131 $method_body = <<<'EOS'
|
Chris@0
|
132
|
Chris@0
|
133 /**
|
Chris@0
|
134 * {@inheritdoc}
|
Chris@0
|
135 */
|
Chris@0
|
136 public function complexMethod($parameter, callable $function, \Drupal\Tests\Component\ProxyBuilder\TestServiceNoMethod $test_service = NULL, array &$elements = array (
|
Chris@0
|
137 ))
|
Chris@0
|
138 {
|
Chris@0
|
139 return $this->lazyLoadItself()->complexMethod($parameter, $function, $test_service, $elements);
|
Chris@0
|
140 }
|
Chris@0
|
141
|
Chris@0
|
142 EOS;
|
Chris@0
|
143
|
Chris@0
|
144 $this->assertEquals($this->buildExpectedClass($class, $method_body), $result);
|
Chris@0
|
145 }
|
Chris@0
|
146
|
Chris@0
|
147 /**
|
Chris@0
|
148 * @covers ::buildMethod
|
Chris@0
|
149 * @covers ::buildMethodBody
|
Chris@0
|
150 */
|
Chris@0
|
151 public function testBuildReturnReference() {
|
Chris@0
|
152 $class = 'Drupal\Tests\Component\ProxyBuilder\TestServiceReturnReference';
|
Chris@0
|
153
|
Chris@0
|
154 $result = $this->proxyBuilder->build($class);
|
Chris@0
|
155
|
Chris@0
|
156 // @todo Solve the silly linebreak for array()
|
Chris@0
|
157 $method_body = <<<'EOS'
|
Chris@0
|
158
|
Chris@0
|
159 /**
|
Chris@0
|
160 * {@inheritdoc}
|
Chris@0
|
161 */
|
Chris@0
|
162 public function &returnReference()
|
Chris@0
|
163 {
|
Chris@0
|
164 return $this->lazyLoadItself()->returnReference();
|
Chris@0
|
165 }
|
Chris@0
|
166
|
Chris@0
|
167 EOS;
|
Chris@0
|
168
|
Chris@0
|
169 $this->assertEquals($this->buildExpectedClass($class, $method_body), $result);
|
Chris@0
|
170 }
|
Chris@0
|
171
|
Chris@0
|
172 /**
|
Chris@0
|
173 * @covers ::buildMethod
|
Chris@0
|
174 * @covers ::buildParameter
|
Chris@0
|
175 * @covers ::buildMethodBody
|
Chris@0
|
176 */
|
Chris@0
|
177 public function testBuildWithInterface() {
|
Chris@0
|
178 $class = 'Drupal\Tests\Component\ProxyBuilder\TestServiceWithInterface';
|
Chris@0
|
179
|
Chris@0
|
180 $result = $this->proxyBuilder->build($class);
|
Chris@0
|
181
|
Chris@0
|
182 $method_body = <<<'EOS'
|
Chris@0
|
183
|
Chris@0
|
184 /**
|
Chris@0
|
185 * {@inheritdoc}
|
Chris@0
|
186 */
|
Chris@0
|
187 public function testMethod($parameter)
|
Chris@0
|
188 {
|
Chris@0
|
189 return $this->lazyLoadItself()->testMethod($parameter);
|
Chris@0
|
190 }
|
Chris@0
|
191
|
Chris@0
|
192 EOS;
|
Chris@0
|
193
|
Chris@0
|
194 $interface_string = ' implements \Drupal\Tests\Component\ProxyBuilder\TestInterface';
|
Chris@0
|
195 $this->assertEquals($this->buildExpectedClass($class, $method_body, $interface_string), $result);
|
Chris@0
|
196 }
|
Chris@0
|
197
|
Chris@0
|
198 /**
|
Chris@0
|
199 * @covers ::build
|
Chris@0
|
200 */
|
Chris@0
|
201 public function testBuildWithNestedInterface() {
|
Chris@0
|
202 $class = 'Drupal\Tests\Component\ProxyBuilder\TestServiceWithChildInterfaces';
|
Chris@0
|
203
|
Chris@0
|
204 $result = $this->proxyBuilder->build($class);
|
Chris@0
|
205 $method_body = '';
|
Chris@0
|
206
|
Chris@0
|
207 $interface_string = ' implements \Drupal\Tests\Component\ProxyBuilder\TestChildInterface';
|
Chris@0
|
208 $this->assertEquals($this->buildExpectedClass($class, $method_body, $interface_string), $result);
|
Chris@0
|
209 }
|
Chris@0
|
210
|
Chris@0
|
211 /**
|
Chris@0
|
212 * @covers ::buildMethod
|
Chris@0
|
213 * @covers ::buildParameter
|
Chris@0
|
214 * @covers ::buildMethodBody
|
Chris@0
|
215 */
|
Chris@0
|
216 public function testBuildWithProtectedAndPrivateMethod() {
|
Chris@0
|
217 $class = 'Drupal\Tests\Component\ProxyBuilder\TestServiceWithProtectedMethods';
|
Chris@0
|
218
|
Chris@0
|
219 $result = $this->proxyBuilder->build($class);
|
Chris@0
|
220
|
Chris@0
|
221 $method_body = <<<'EOS'
|
Chris@0
|
222
|
Chris@0
|
223 /**
|
Chris@0
|
224 * {@inheritdoc}
|
Chris@0
|
225 */
|
Chris@0
|
226 public function testMethod($parameter)
|
Chris@0
|
227 {
|
Chris@0
|
228 return $this->lazyLoadItself()->testMethod($parameter);
|
Chris@0
|
229 }
|
Chris@0
|
230
|
Chris@0
|
231 EOS;
|
Chris@0
|
232
|
Chris@0
|
233 $this->assertEquals($this->buildExpectedClass($class, $method_body), $result);
|
Chris@0
|
234 }
|
Chris@0
|
235
|
Chris@0
|
236 /**
|
Chris@0
|
237 * @covers ::buildMethod
|
Chris@0
|
238 * @covers ::buildParameter
|
Chris@0
|
239 * @covers ::buildMethodBody
|
Chris@0
|
240 */
|
Chris@0
|
241 public function testBuildWithPublicStaticMethod() {
|
Chris@0
|
242 $class = 'Drupal\Tests\Component\ProxyBuilder\TestServiceWithPublicStaticMethod';
|
Chris@0
|
243
|
Chris@0
|
244 $result = $this->proxyBuilder->build($class);
|
Chris@0
|
245
|
Chris@0
|
246 // Ensure that the static method is not wrapped.
|
Chris@0
|
247 $method_body = <<<'EOS'
|
Chris@0
|
248
|
Chris@0
|
249 /**
|
Chris@0
|
250 * {@inheritdoc}
|
Chris@0
|
251 */
|
Chris@0
|
252 public static function testMethod($parameter)
|
Chris@0
|
253 {
|
Chris@0
|
254 \Drupal\Tests\Component\ProxyBuilder\TestServiceWithPublicStaticMethod::testMethod($parameter);
|
Chris@0
|
255 }
|
Chris@0
|
256
|
Chris@0
|
257 EOS;
|
Chris@0
|
258
|
Chris@0
|
259 $this->assertEquals($this->buildExpectedClass($class, $method_body), $result);
|
Chris@0
|
260 }
|
Chris@0
|
261
|
Chris@0
|
262 /**
|
Chris@0
|
263 * Constructs the expected class output.
|
Chris@0
|
264 *
|
Chris@0
|
265 * @param string $expected_methods_body
|
Chris@0
|
266 * The expected body of decorated methods.
|
Chris@0
|
267 *
|
Chris@0
|
268 * @return string
|
Chris@0
|
269 * The code of the entire proxy.
|
Chris@0
|
270 */
|
Chris@0
|
271 protected function buildExpectedClass($class, $expected_methods_body, $interface_string = '') {
|
Chris@0
|
272 $namespace = ProxyBuilder::buildProxyNamespace($class);
|
Chris@0
|
273 $reflection = new \ReflectionClass($class);
|
Chris@0
|
274 $proxy_class = $reflection->getShortName();
|
Chris@0
|
275
|
Chris@0
|
276 $expected_string = <<<'EOS'
|
Chris@0
|
277
|
Chris@0
|
278 namespace {{ namespace }} {
|
Chris@0
|
279
|
Chris@0
|
280 /**
|
Chris@0
|
281 * Provides a proxy class for \{{ class }}.
|
Chris@0
|
282 *
|
Chris@0
|
283 * @see \Drupal\Component\ProxyBuilder
|
Chris@0
|
284 */
|
Chris@0
|
285 class {{ proxy_class }}{{ interface_string }}
|
Chris@0
|
286 {
|
Chris@0
|
287
|
Chris@0
|
288 /**
|
Chris@0
|
289 * The id of the original proxied service.
|
Chris@0
|
290 *
|
Chris@0
|
291 * @var string
|
Chris@0
|
292 */
|
Chris@0
|
293 protected $drupalProxyOriginalServiceId;
|
Chris@0
|
294
|
Chris@0
|
295 /**
|
Chris@0
|
296 * The real proxied service, after it was lazy loaded.
|
Chris@0
|
297 *
|
Chris@0
|
298 * @var \{{ class }}
|
Chris@0
|
299 */
|
Chris@0
|
300 protected $service;
|
Chris@0
|
301
|
Chris@0
|
302 /**
|
Chris@0
|
303 * The service container.
|
Chris@0
|
304 *
|
Chris@0
|
305 * @var \Symfony\Component\DependencyInjection\ContainerInterface
|
Chris@0
|
306 */
|
Chris@0
|
307 protected $container;
|
Chris@0
|
308
|
Chris@0
|
309 /**
|
Chris@0
|
310 * Constructs a ProxyClass Drupal proxy object.
|
Chris@0
|
311 *
|
Chris@0
|
312 * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
|
Chris@0
|
313 * The container.
|
Chris@0
|
314 * @param string $drupal_proxy_original_service_id
|
Chris@0
|
315 * The service ID of the original service.
|
Chris@0
|
316 */
|
Chris@0
|
317 public function __construct(\Symfony\Component\DependencyInjection\ContainerInterface $container, $drupal_proxy_original_service_id)
|
Chris@0
|
318 {
|
Chris@0
|
319 $this->container = $container;
|
Chris@0
|
320 $this->drupalProxyOriginalServiceId = $drupal_proxy_original_service_id;
|
Chris@0
|
321 }
|
Chris@0
|
322
|
Chris@0
|
323 /**
|
Chris@0
|
324 * Lazy loads the real service from the container.
|
Chris@0
|
325 *
|
Chris@0
|
326 * @return object
|
Chris@0
|
327 * Returns the constructed real service.
|
Chris@0
|
328 */
|
Chris@0
|
329 protected function lazyLoadItself()
|
Chris@0
|
330 {
|
Chris@0
|
331 if (!isset($this->service)) {
|
Chris@0
|
332 $this->service = $this->container->get($this->drupalProxyOriginalServiceId);
|
Chris@0
|
333 }
|
Chris@0
|
334
|
Chris@0
|
335 return $this->service;
|
Chris@0
|
336 }
|
Chris@0
|
337 {{ expected_methods_body }}
|
Chris@0
|
338 }
|
Chris@0
|
339
|
Chris@0
|
340 }
|
Chris@0
|
341
|
Chris@0
|
342 EOS;
|
Chris@0
|
343
|
Chris@0
|
344 $expected_methods_body = implode("\n", array_map(function ($value) {
|
Chris@0
|
345 if ($value === '') {
|
Chris@0
|
346 return $value;
|
Chris@0
|
347 }
|
Chris@0
|
348 return " $value";
|
Chris@0
|
349 }, explode("\n", $expected_methods_body)));
|
Chris@0
|
350
|
Chris@0
|
351 $expected_string = str_replace('{{ proxy_class }}', $proxy_class, $expected_string);
|
Chris@0
|
352 $expected_string = str_replace('{{ namespace }}', $namespace, $expected_string);
|
Chris@0
|
353 $expected_string = str_replace('{{ class }}', $class, $expected_string);
|
Chris@0
|
354 $expected_string = str_replace('{{ expected_methods_body }}', $expected_methods_body, $expected_string);
|
Chris@0
|
355 $expected_string = str_replace('{{ interface_string }}', $interface_string, $expected_string);
|
Chris@0
|
356
|
Chris@0
|
357 return $expected_string;
|
Chris@0
|
358 }
|
Chris@0
|
359
|
Chris@0
|
360 }
|
Chris@0
|
361
|
Chris@0
|
362 class TestServiceNoMethod {
|
Chris@0
|
363
|
Chris@0
|
364 }
|
Chris@0
|
365
|
Chris@0
|
366 class TestServiceSimpleMethod {
|
Chris@0
|
367
|
Chris@0
|
368 public function method() {
|
Chris@0
|
369
|
Chris@0
|
370 }
|
Chris@0
|
371
|
Chris@0
|
372 }
|
Chris@0
|
373
|
Chris@0
|
374 class TestServiceMethodWithParameter {
|
Chris@0
|
375
|
Chris@0
|
376 public function methodWithParameter($parameter) {
|
Chris@0
|
377
|
Chris@0
|
378 }
|
Chris@0
|
379
|
Chris@0
|
380 }
|
Chris@0
|
381
|
Chris@0
|
382 class TestServiceComplexMethod {
|
Chris@0
|
383
|
Chris@0
|
384 public function complexMethod($parameter, callable $function, TestServiceNoMethod $test_service = NULL, array &$elements = []) {
|
Chris@0
|
385
|
Chris@0
|
386 }
|
Chris@0
|
387
|
Chris@0
|
388 }
|
Chris@0
|
389
|
Chris@0
|
390 class TestServiceReturnReference {
|
Chris@0
|
391
|
Chris@0
|
392 public function &returnReference() {
|
Chris@0
|
393
|
Chris@0
|
394 }
|
Chris@0
|
395
|
Chris@0
|
396 }
|
Chris@0
|
397
|
Chris@0
|
398 interface TestInterface {
|
Chris@0
|
399
|
Chris@0
|
400 public function testMethod($parameter);
|
Chris@0
|
401
|
Chris@0
|
402 }
|
Chris@0
|
403
|
Chris@0
|
404 class TestServiceWithInterface implements TestInterface {
|
Chris@0
|
405
|
Chris@0
|
406 public function testMethod($parameter) {
|
Chris@0
|
407
|
Chris@0
|
408 }
|
Chris@0
|
409
|
Chris@0
|
410 }
|
Chris@0
|
411
|
Chris@0
|
412 class TestServiceWithProtectedMethods {
|
Chris@0
|
413
|
Chris@0
|
414 public function testMethod($parameter) {
|
Chris@0
|
415
|
Chris@0
|
416 }
|
Chris@0
|
417
|
Chris@0
|
418 protected function protectedMethod($parameter) {
|
Chris@0
|
419
|
Chris@0
|
420 }
|
Chris@0
|
421
|
Chris@0
|
422 protected function privateMethod($parameter) {
|
Chris@0
|
423
|
Chris@0
|
424 }
|
Chris@0
|
425
|
Chris@0
|
426 }
|
Chris@0
|
427
|
Chris@0
|
428 class TestServiceWithPublicStaticMethod {
|
Chris@0
|
429
|
Chris@0
|
430 public static function testMethod($parameter) {
|
Chris@0
|
431 }
|
Chris@0
|
432
|
Chris@0
|
433 }
|
Chris@0
|
434
|
Chris@0
|
435 interface TestBaseInterface {
|
Chris@0
|
436
|
Chris@0
|
437 }
|
Chris@0
|
438
|
Chris@0
|
439 interface TestChildInterface extends TestBaseInterface {
|
Chris@0
|
440
|
Chris@0
|
441 }
|
Chris@0
|
442
|
Chris@0
|
443 class TestServiceWithChildInterfaces implements TestChildInterface {
|
Chris@0
|
444
|
Chris@0
|
445 }
|