annotate core/tests/Drupal/Tests/Component/Utility/ArgumentsResolverTest.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
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 }