Skip to content

Commit 10756d1

Browse files
committed
Refactor createArrayOfInputs to enforce array type for item data and improve error handling
1 parent f3c476e commit 10756d1

File tree

2 files changed

+45
-16
lines changed

2 files changed

+45
-16
lines changed

src/InputQuery.php

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use function array_key_exists;
2222
use function assert;
2323
use function class_exists;
24+
use function gettype;
2425
use function is_array;
2526
use function is_bool;
2627
use function is_float;
@@ -335,7 +336,7 @@ private function toCamelCase(string $string): string
335336
* @param array<string, mixed> $query
336337
* @param class-string<T> $itemClass
337338
*
338-
* @return array<mixed>
339+
* @return array<array-key, T>
339340
*/
340341
private function createArrayOfInputs(string $paramName, array $query, string $itemClass): array
341342
{
@@ -353,12 +354,20 @@ private function createArrayOfInputs(string $paramName, array $query, string $it
353354
$result = [];
354355
/** @var mixed $itemData */
355356
foreach ($arrayData as $key => $itemData) {
356-
if (is_array($itemData)) {
357-
// Query parameters from HTTP requests have string keys
358-
/** @psalm-var array<string, mixed> $itemData */
359-
/** @phpstan-var array<string, mixed> $itemData */
360-
$result[$key] = $this->create($itemClass, $itemData);
357+
if (! is_array($itemData)) {
358+
throw new InvalidArgumentException(
359+
sprintf(
360+
'Expected array for item at key "%s", got %s.',
361+
$key,
362+
gettype($itemData),
363+
),
364+
);
361365
}
366+
367+
// Query parameters from HTTP requests have string keys
368+
/** @psalm-var array<string, mixed> $itemData */
369+
/** @phpstan-var array<string, mixed> $itemData */
370+
$result[$key] = $this->create($itemClass, $itemData);
362371
}
363372

364373
return $result;

tests/ArrayInputTest.php

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Ray\InputQuery;
66

77
use ArrayObject;
8+
use InvalidArgumentException;
89
use PHPUnit\Framework\TestCase;
910
use Ray\Di\Injector;
1011
use Ray\InputQuery\Attribute\Input;
@@ -152,11 +153,8 @@ public function testArrayWithNonArrayElements(): void
152153
{
153154
$query = [
154155
'users' => [
155-
'string-value',
156-
123,
156+
'string-value', // Non-array element at index 0
157157
['id' => '1', 'name' => 'valid'],
158-
null,
159-
true,
160158
],
161159
];
162160

@@ -170,13 +168,11 @@ public function listUsers(
170168
};
171169

172170
$method = new ReflectionMethod($controller, 'listUsers');
173-
$args = $this->inputQuery->getArguments($method, $query);
174171

175-
$this->assertIsArray($args[0]);
176-
$this->assertCount(1, $args[0]); // Only the valid array element
177-
$this->assertInstanceOf(UserInputWithAttribute::class, $args[0][2]);
178-
$this->assertSame('1', $args[0][2]->id);
179-
$this->assertSame('valid', $args[0][2]->name);
172+
$this->expectException(InvalidArgumentException::class);
173+
$this->expectExceptionMessage('Expected array for item at key "0", got string.');
174+
175+
$this->inputQuery->getArguments($method, $query);
180176
}
181177

182178
public function testCustomArrayObjectOfInputObjects(): void
@@ -216,4 +212,28 @@ public function listUsers(
216212
$this->assertInstanceOf(UserInputWithAttribute::class, $firstUser);
217213
$this->assertSame('5', $firstUser->id);
218214
}
215+
216+
public function testArrayObjectWithoutItemAttribute(): void
217+
{
218+
$query = [
219+
'users' => [
220+
['id' => '1', 'name' => 'test'],
221+
],
222+
];
223+
224+
$controller = new class {
225+
public function listUsers(
226+
#[Input] // No item parameter specified
227+
ArrayObject $users,
228+
): ArrayObject {
229+
return $users;
230+
}
231+
};
232+
233+
$method = new ReflectionMethod($controller, 'listUsers');
234+
$args = $this->inputQuery->getArguments($method, $query);
235+
236+
// Should create a regular ArrayObject with the nested query data
237+
$this->assertInstanceOf(ArrayObject::class, $args[0]);
238+
}
219239
}

0 commit comments

Comments
 (0)