Version 1
[yaffs-website] / web / core / tests / Drupal / Tests / Component / Utility / ArgumentsResolverTest.php
1 <?php
2
3 /**
4  * @file
5  * Contains \Drupal\Tests\Component\Utility\ArgumentsResolverTest.
6  */
7
8 namespace Drupal\Tests\Component\Utility;
9
10 use Drupal\Component\Utility\ArgumentsResolver;
11 use Drupal\Tests\UnitTestCase;
12
13 /**
14  * @coversDefaultClass \Drupal\Component\Utility\ArgumentsResolver
15  * @group Access
16  */
17 class ArgumentsResolverTest extends UnitTestCase {
18
19   /**
20    * {@inheritdoc}
21    */
22   protected function setUp() {
23     parent::setUp();
24   }
25
26   /**
27    * Tests the getArgument() method.
28    *
29    * @dataProvider providerTestGetArgument
30    */
31   public function testGetArgument($callable, $scalars, $objects, $wildcards, $expected) {
32     $arguments = (new ArgumentsResolver($scalars, $objects, $wildcards))->getArguments($callable);
33     $this->assertSame($expected, $arguments);
34   }
35
36   /**
37    * Provides test data to testGetArgument().
38    */
39   public function providerTestGetArgument() {
40     $data = [];
41
42     // Test an optional parameter with no provided value.
43     $data[] = [
44       function($foo = 'foo') {}, [], [], [] , ['foo'],
45     ];
46
47     // Test an optional parameter with a provided value.
48     $data[] = [
49       function($foo = 'foo') {}, ['foo' => 'bar'], [], [], ['bar'],
50     ];
51
52     // Test with a provided value.
53     $data[] = [
54       function($foo) {}, ['foo' => 'bar'], [], [], ['bar'],
55     ];
56
57     // Test with an explicitly NULL value.
58     $data[] = [
59       function($foo) {}, [], ['foo' => NULL], [], [NULL],
60     ];
61
62     // Test with a raw value that overrides the provided upcast value, since
63     // it is not typehinted.
64     $scalars  = ['foo' => 'baz'];
65     $objects = ['foo' => new \stdClass()];
66     $data[] = [
67       function($foo) {}, $scalars, $objects, [], ['baz'],
68     ];
69
70     return $data;
71   }
72
73   /**
74    * Tests getArgument() with an object.
75    */
76   public function testGetArgumentObject() {
77     $callable = function(\stdClass $object) {};
78
79     $object = new \stdClass();
80     $arguments = (new ArgumentsResolver([], ['object' => $object], []))->getArguments($callable);
81     $this->assertSame([$object], $arguments);
82   }
83
84   /**
85    * Tests getArgument() with a wildcard object for a parameter with a custom name.
86    */
87   public function testGetWildcardArgument() {
88     $callable = function(\stdClass $custom_name) {};
89
90     $object = new \stdClass();
91     $arguments = (new ArgumentsResolver([], [], [$object]))->getArguments($callable);
92     $this->assertSame([$object], $arguments);
93   }
94
95   /**
96    * Tests getArgument() with a Route, Request, and Account object.
97    */
98   public function testGetArgumentOrder() {
99     $a1 = $this->getMock('\Drupal\Tests\Component\Utility\TestInterface1');
100     $a2 = $this->getMock('\Drupal\Tests\Component\Utility\TestClass');
101     $a3 = $this->getMock('\Drupal\Tests\Component\Utility\TestInterface2');
102
103     $objects = [
104       't1' => $a1,
105       'tc' => $a2,
106     ];
107     $wildcards = [$a3];
108     $resolver = new ArgumentsResolver([], $objects, $wildcards);
109
110     $callable = function(TestInterface1 $t1, TestClass $tc, TestInterface2 $t2) {};
111     $arguments = $resolver->getArguments($callable);
112     $this->assertSame([$a1, $a2, $a3], $arguments);
113
114     // Test again, but with the arguments in a different order.
115     $callable = function(TestInterface2 $t2, TestClass $tc, TestInterface1 $t1) {};
116     $arguments = $resolver->getArguments($callable);
117     $this->assertSame([$a3, $a2, $a1], $arguments);
118   }
119
120   /**
121    * Tests getArgument() with a wildcard parameter with no typehint.
122    *
123    * Without the typehint, the wildcard object will not be passed to the callable.
124    */
125   public function testGetWildcardArgumentNoTypehint() {
126     $a = $this->getMock('\Drupal\Tests\Component\Utility\TestInterface1');
127     $wildcards = [$a];
128     $resolver = new ArgumentsResolver([], [], $wildcards);
129
130     $callable = function($route) {};
131     $this->setExpectedException(\RuntimeException::class, 'requires a value for the "$route" argument.');
132     $resolver->getArguments($callable);
133   }
134
135   /**
136    * Tests getArgument() with a named parameter with no typehint and a value.
137    *
138    * Without the typehint, passing a value to a named parameter will still
139    * receive the provided value.
140    */
141   public function testGetArgumentRouteNoTypehintAndValue() {
142     $scalars = ['route' => 'foo'];
143     $resolver = new ArgumentsResolver($scalars, [], []);
144
145     $callable = function($route) {};
146     $arguments = $resolver->getArguments($callable);
147     $this->assertSame(['foo'], $arguments);
148   }
149
150   /**
151    * Tests handleUnresolvedArgument() for a scalar argument.
152    */
153   public function testHandleNotUpcastedArgument() {
154     $objects = ['foo' => 'bar'];
155     $scalars = ['foo' => 'baz'];
156     $resolver = new ArgumentsResolver($scalars, $objects, []);
157
158     $callable = function(\stdClass $foo) {};
159     $this->setExpectedException(\RuntimeException::class, 'requires a value for the "$foo" argument.');
160     $resolver->getArguments($callable);
161   }
162
163   /**
164    * Tests handleUnresolvedArgument() for missing arguments.
165    *
166    * @dataProvider providerTestHandleUnresolvedArgument
167    */
168   public function testHandleUnresolvedArgument($callable) {
169     $resolver = new ArgumentsResolver([], [], []);
170     $this->setExpectedException(\RuntimeException::class, 'requires a value for the "$foo" argument.');
171     $resolver->getArguments($callable);
172   }
173
174   /**
175    * Provides test data to testHandleUnresolvedArgument().
176    */
177   public function providerTestHandleUnresolvedArgument() {
178     $data = [];
179     $data[] = [function($foo) {}];
180     $data[] = [[new TestClass(), 'access']];
181     $data[] = ['Drupal\Tests\Component\Utility\test_access_arguments_resolver_access'];
182     return $data;
183   }
184
185 }
186
187 /**
188  * Provides a test class.
189  */
190 class TestClass {
191   public function access($foo) {
192   }
193
194 }
195
196 /**
197  * Provides a test interface.
198  */
199 interface TestInterface1 {
200 }
201
202 /**
203  * Provides a different test interface.
204  */
205 interface TestInterface2 {
206 }
207
208 function test_access_arguments_resolver_access($foo) {
209 }