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