Skip to content

Commit 33e6341

Browse files
committed
Set the IDs of of results of Each as the array keys
This will make the messages easier to understand and map than they are described now.
1 parent 18d8246 commit 33e6341

File tree

8 files changed

+56
-54
lines changed

8 files changed

+56
-54
lines changed

library/Rules/Each.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
use Respect\Validation\Result;
1515
use Respect\Validation\Rules\Core\FilteredNonEmptyArray;
1616

17-
use function array_map;
1817
use function array_reduce;
1918

2019
#[Attribute(Attribute::TARGET_PROPERTY | Attribute::IS_REPEATABLE)]
@@ -27,7 +26,10 @@ final class Each extends FilteredNonEmptyArray
2726
/** @param non-empty-array<mixed> $input */
2827
protected function evaluateNonEmptyArray(array $input): Result
2928
{
30-
$children = array_map(fn ($item) => $this->rule->evaluate($item), $input);
29+
$children = [];
30+
foreach ($input as $key => $value) {
31+
$children[] = $this->rule->evaluate($value)->withUnchangeableId((string) $key);
32+
}
3133
$isValid = array_reduce($children, static fn ($carry, $childResult) => $carry && $childResult->isValid, true);
3234
if ($isValid) {
3335
return Result::passed($input, $this)->withChildren(...$children);

tests/Pest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
use function PHPUnit\Framework\assertStringMatchesFormat;
1414

15-
/** @param array<string, mixed> $messages */
15+
/** @param array<string|int, mixed> $messages */
1616
function expectAll(Closure $callback, string $message, string $fullMessage, array $messages): Closure
1717
{
1818
return function () use ($callback, $message, $fullMessage, $messages): void {
@@ -27,7 +27,7 @@ function expectAll(Closure $callback, string $message, string $fullMessage, arra
2727
};
2828
}
2929

30-
/** @param array<string, mixed> $messages */
30+
/** @param array<string|int, mixed> $messages */
3131
function expectAllToMatch(Closure $callback, string $message, string $fullMessage, array $messages): Closure
3232
{
3333
return function () use ($callback, $message, $fullMessage, $messages): void {
@@ -70,7 +70,7 @@ function expectFullMessage(Closure $callback, string $fullMessage): Closure
7070
};
7171
}
7272

73-
/** @param array<string, mixed> $messages */
73+
/** @param array<string|int, mixed> $messages */
7474
function expectMessages(Closure $callback, array $messages): Closure
7575
{
7676
return function () use ($callback, $messages): void {

tests/feature/Issues/Issue1033Test.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
FULL_MESSAGE,
1919
[
2020
'__root__' => 'Each item in `["A", "B", "B"]` must be valid',
21-
'equals.1' => '"A" must be equal to 1',
22-
'equals.2' => '"B" must be equal to 1',
23-
'equals.3' => '"B" must be equal to 1',
21+
0 => '"A" must be equal to 1',
22+
1 => '"B" must be equal to 1',
23+
2 => '"B" must be equal to 1',
2424
]
2525
));

tests/feature/Issues/Issue1289Test.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
- description must be a string value
5555
FULL_MESSAGE,
5656
[
57-
'allOf' => [
57+
0 => [
5858
'__root__' => 'These rules must pass for `["default": 2, "description": [], "children": ["nope"]]`',
5959
'default' => [
6060
'__root__' => 'Only one of these rules must pass for default',

tests/feature/Issues/Issue1334Test.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ function (): void {
3737
[
3838
'each' => [
3939
'__root__' => 'Each item in `[["region": "Oregon", "country": "USA", "other": 123], ["street": "", "region": "Oregon", "country": "USA"], ["s ... ]` must be valid',
40-
'allOf.1' => [
40+
0 => [
4141
'__root__' => 'These rules must pass for `["region": "Oregon", "country": "USA", "other": 123]`',
4242
'street' => 'street must be present',
4343
'other' => 'other must be a string or must be null',
4444
],
45-
'allOf.2' => 'street must not be empty',
46-
'allOf.3' => 'street must be a string',
45+
1 => 'street must not be empty',
46+
2 => 'street must be a string',
4747
],
4848
]
4949
));

tests/feature/Issues/Issue1348Test.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
[
5050
'each' => [
5151
'__root__' => 'Each item in `[["manufacturer": "Honda", "model": "Accord"], ["manufacturer": "Toyota", "model": "Rav4"], ["manufacturer": "Fo ... ]` must be valid',
52-
'oneOf.3' => [
52+
2 => [
5353
'__root__' => 'Only one of these rules must pass for `["manufacturer": "Ford", "model": "not real"]`',
5454
'allOf.1' => [
5555
'__root__' => 'All the required rules must pass for `["manufacturer": "Ford", "model": "not real"]`',
@@ -63,7 +63,7 @@
6363
],
6464
'allOf.3' => 'model must be in `["F150", "Bronco"]`',
6565
],
66-
'oneOf.4' => [
66+
3 => [
6767
'__root__' => 'Only one of these rules must pass for `["manufacturer": "Honda", "model": "not valid"]`',
6868
'allOf.1' => 'model must be in `["Accord", "Fit"]`',
6969
'allOf.2' => [

tests/feature/Issues/Issue1469Test.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ function (): void {
4141
[
4242
'keySet' => [
4343
'__root__' => 'Each item in order_items must be valid',
44-
'keySet.1' => 'quantity must be an integer value',
45-
'keySet.2' => [
44+
0 => 'quantity must be an integer value',
45+
1 => [
4646
'__root__' => 'order_items contains both missing and extra keys',
4747
'product_title' => 'product_title must be present',
4848
'quantity' => 'quantity must be present',

tests/feature/Rules/EachTest.php

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@
3232
FULL_MESSAGE,
3333
[
3434
'__root__' => 'Each item in `["a", "b", "c"]` must be valid',
35-
'intType.1' => '"a" must be an integer',
36-
'intType.2' => '"b" must be an integer',
37-
'intType.3' => '"c" must be an integer',
35+
0 => '"a" must be an integer',
36+
1 => '"b" must be an integer',
37+
2 => '"c" must be an integer',
3838
]
3939
));
4040

@@ -49,9 +49,9 @@
4949
FULL_MESSAGE,
5050
[
5151
'__root__' => 'Each item in `[1, 2, 3]` must be invalid',
52-
'intType.1' => '1 must not be an integer',
53-
'intType.2' => '2 must not be an integer',
54-
'intType.3' => '3 must not be an integer',
52+
0 => '1 must not be an integer',
53+
1 => '2 must not be an integer',
54+
2 => '3 must not be an integer',
5555
]
5656
));
5757

@@ -80,9 +80,9 @@
8080
FULL_MESSAGE,
8181
[
8282
'__root__' => 'Each item in Wrapped must be valid',
83-
'intType.1' => 'Wrapped must be an integer',
84-
'intType.2' => 'Wrapped must be an integer',
85-
'intType.3' => 'Wrapped must be an integer',
83+
0 => 'Wrapped must be an integer',
84+
1 => 'Wrapped must be an integer',
85+
2 => 'Wrapped must be an integer',
8686
]
8787
));
8888

@@ -97,9 +97,9 @@
9797
FULL_MESSAGE,
9898
[
9999
'__root__' => 'Each item in Wrapped must be invalid',
100-
'intType.1' => 'Wrapped must not be an integer',
101-
'intType.2' => 'Wrapped must not be an integer',
102-
'intType.3' => 'Wrapped must not be an integer',
100+
0 => 'Wrapped must not be an integer',
101+
1 => 'Wrapped must not be an integer',
102+
2 => 'Wrapped must not be an integer',
103103
]
104104
));
105105

@@ -114,9 +114,9 @@
114114
FULL_MESSAGE,
115115
[
116116
'__root__' => 'Each item in Wrapper must be valid',
117-
'intType.1' => 'Wrapper must be an integer',
118-
'intType.2' => 'Wrapper must be an integer',
119-
'intType.3' => 'Wrapper must be an integer',
117+
0 => 'Wrapper must be an integer',
118+
1 => 'Wrapper must be an integer',
119+
2 => 'Wrapper must be an integer',
120120
]
121121
));
122122

@@ -131,9 +131,9 @@
131131
FULL_MESSAGE,
132132
[
133133
'__root__' => 'Each item in Wrapper must be invalid',
134-
'intType.1' => 'Wrapper must not be an integer',
135-
'intType.2' => 'Wrapper must not be an integer',
136-
'intType.3' => 'Wrapper must not be an integer',
134+
0 => 'Wrapper must not be an integer',
135+
1 => 'Wrapper must not be an integer',
136+
2 => 'Wrapper must not be an integer',
137137
]
138138
));
139139

@@ -148,9 +148,9 @@
148148
FULL_MESSAGE,
149149
[
150150
'__root__' => 'Each item in Not must be invalid',
151-
'intType.1' => 'Not must not be an integer',
152-
'intType.2' => 'Not must not be an integer',
153-
'intType.3' => 'Not must not be an integer',
151+
0 => 'Not must not be an integer',
152+
1 => 'Not must not be an integer',
153+
2 => 'Not must not be an integer',
154154
]
155155
));
156156

@@ -192,9 +192,9 @@
192192
->setTemplates([
193193
'each' => [
194194
'__root__' => 'Here a sequence of items that did not pass the validation',
195-
'intType.1' => 'First item should have been an integer',
196-
'intType.2' => 'Second item should have been an integer',
197-
'intType.3' => 'Third item should have been an integer',
195+
0 => 'First item should have been an integer',
196+
1 => 'Second item should have been an integer',
197+
2 => 'Third item should have been an integer',
198198
],
199199
])
200200
->assert(['a', 'b', 'c']),
@@ -207,9 +207,9 @@
207207
FULL_MESSAGE,
208208
[
209209
'__root__' => 'Here a sequence of items that did not pass the validation',
210-
'intType.1' => 'First item should have been an integer',
211-
'intType.2' => 'Second item should have been an integer',
212-
'intType.3' => 'Third item should have been an integer',
210+
0 => 'First item should have been an integer',
211+
1 => 'Second item should have been an integer',
212+
2 => 'Third item should have been an integer',
213213
]
214214
));
215215

@@ -219,9 +219,9 @@
219219
->setTemplates([
220220
'Wrapped' => [
221221
'__root__' => 'Here a sequence of items that did not pass the validation',
222-
'Wrapped.1' => 'First item should have been an integer',
223-
'Wrapped.2' => 'Second item should have been an integer',
224-
'Wrapped.3' => 'Third item should have been an integer',
222+
0 => 'First item should have been an integer',
223+
1 => 'Second item should have been an integer',
224+
2 => 'Third item should have been an integer',
225225
],
226226
])
227227
->assert(['a', 'b', 'c']),
@@ -234,9 +234,9 @@
234234
FULL_MESSAGE,
235235
[
236236
'__root__' => 'Each item in Wrapped must be valid',
237-
'intType.1' => 'Wrapped must be an integer',
238-
'intType.2' => 'Wrapped must be an integer',
239-
'intType.3' => 'Wrapped must be an integer',
237+
0 => 'Wrapped must be an integer',
238+
1 => 'Wrapped must be an integer',
239+
2 => 'Wrapped must be an integer',
240240
]
241241
));
242242

@@ -254,12 +254,12 @@
254254
FULL_MESSAGE,
255255
[
256256
'__root__' => 'Each item in `[2, 4]` must be valid',
257-
'allOf.1' => [
257+
0 => [
258258
'__root__' => 'All the required rules must pass for 2',
259259
'between' => '2 must be between 5 and 7',
260260
'odd' => '2 must be an odd number',
261261
],
262-
'allOf.2' => [
262+
1 => [
263263
'__root__' => 'All the required rules must pass for 4',
264264
'between' => '4 must be between 5 and 7',
265265
'odd' => '4 must be an odd number',
@@ -282,9 +282,9 @@
282282
FULL_MESSAGE,
283283
[
284284
'__root__' => 'Each item in `[["not_int": "wrong"], ["my_int": 2], "not an array"]` must be valid',
285-
'allOf.1' => 'my_int must be present',
286-
'allOf.2' => 'my_int must be an odd number',
287-
'allOf.3' => [
285+
0 => 'my_int must be present',
286+
1 => 'my_int must be an odd number',
287+
2 => [
288288
'__root__' => 'All the required rules must pass for "not an array"',
289289
'arrayType' => '"not an array" must be an array',
290290
'my_int' => 'my_int must be present',

0 commit comments

Comments
 (0)