5 * Contains \Drupal\Tests\Component\Utility\ArgumentsResolverTest.
8 namespace Drupal\Tests\Component\Utility;
10 use Drupal\Component\Utility\ArgumentsResolver;
11 use Drupal\Tests\UnitTestCase;
14 * @coversDefaultClass \Drupal\Component\Utility\ArgumentsResolver
17 class ArgumentsResolverTest extends UnitTestCase {
22 protected function setUp() {
27 * Tests the getArgument() method.
29 * @dataProvider providerTestGetArgument
31 public function testGetArgument($callable, $scalars, $objects, $wildcards, $expected) {
32 $arguments = (new ArgumentsResolver($scalars, $objects, $wildcards))->getArguments($callable);
33 $this->assertSame($expected, $arguments);
37 * Provides test data to testGetArgument().
39 public function providerTestGetArgument() {
42 // Test an optional parameter with no provided value.
44 function($foo = 'foo') {}, [], [], [] , ['foo'],
47 // Test an optional parameter with a provided value.
49 function($foo = 'foo') {}, ['foo' => 'bar'], [], [], ['bar'],
52 // Test with a provided value.
54 function($foo) {}, ['foo' => 'bar'], [], [], ['bar'],
57 // Test with an explicitly NULL value.
59 function($foo) {}, [], ['foo' => NULL], [], [NULL],
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()];
67 function($foo) {}, $scalars, $objects, [], ['baz'],
74 * Tests getArgument() with an object.
76 public function testGetArgumentObject() {
77 $callable = function(\stdClass $object) {};
79 $object = new \stdClass();
80 $arguments = (new ArgumentsResolver([], ['object' => $object], []))->getArguments($callable);
81 $this->assertSame([$object], $arguments);
85 * Tests getArgument() with a wildcard object for a parameter with a custom name.
87 public function testGetWildcardArgument() {
88 $callable = function(\stdClass $custom_name) {};
90 $object = new \stdClass();
91 $arguments = (new ArgumentsResolver([], [], [$object]))->getArguments($callable);
92 $this->assertSame([$object], $arguments);
96 * Tests getArgument() with a Route, Request, and Account object.
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');
108 $resolver = new ArgumentsResolver([], $objects, $wildcards);
110 $callable = function(TestInterface1 $t1, TestClass $tc, TestInterface2 $t2) {};
111 $arguments = $resolver->getArguments($callable);
112 $this->assertSame([$a1, $a2, $a3], $arguments);
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);
121 * Tests getArgument() with a wildcard parameter with no typehint.
123 * Without the typehint, the wildcard object will not be passed to the callable.
125 public function testGetWildcardArgumentNoTypehint() {
126 $a = $this->getMock('\Drupal\Tests\Component\Utility\TestInterface1');
128 $resolver = new ArgumentsResolver([], [], $wildcards);
130 $callable = function($route) {};
131 $this->setExpectedException(\RuntimeException::class, 'requires a value for the "$route" argument.');
132 $resolver->getArguments($callable);
136 * Tests getArgument() with a named parameter with no typehint and a value.
138 * Without the typehint, passing a value to a named parameter will still
139 * receive the provided value.
141 public function testGetArgumentRouteNoTypehintAndValue() {
142 $scalars = ['route' => 'foo'];
143 $resolver = new ArgumentsResolver($scalars, [], []);
145 $callable = function($route) {};
146 $arguments = $resolver->getArguments($callable);
147 $this->assertSame(['foo'], $arguments);
151 * Tests handleUnresolvedArgument() for a scalar argument.
153 public function testHandleNotUpcastedArgument() {
154 $objects = ['foo' => 'bar'];
155 $scalars = ['foo' => 'baz'];
156 $resolver = new ArgumentsResolver($scalars, $objects, []);
158 $callable = function(\stdClass $foo) {};
159 $this->setExpectedException(\RuntimeException::class, 'requires a value for the "$foo" argument.');
160 $resolver->getArguments($callable);
164 * Tests handleUnresolvedArgument() for missing arguments.
166 * @dataProvider providerTestHandleUnresolvedArgument
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);
175 * Provides test data to testHandleUnresolvedArgument().
177 public function providerTestHandleUnresolvedArgument() {
179 $data[] = [function($foo) {}];
180 $data[] = [[new TestClass(), 'access']];
181 $data[] = ['Drupal\Tests\Component\Utility\test_access_arguments_resolver_access'];
188 * Provides a test class.
191 public function access($foo) {
197 * Provides a test interface.
199 interface TestInterface1 {
203 * Provides a different test interface.
205 interface TestInterface2 {
208 function test_access_arguments_resolver_access($foo) {