Skip to content

Commit d1ccfba

Browse files
committed
fix a bug in all AbstractObjectSchema implementations
1 parent 17ba81b commit d1ccfba

4 files changed

Lines changed: 67 additions & 8 deletions

File tree

src/Schema/AssocSchema.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,28 @@ final class AssocSchema extends AbstractObjectSchema implements ObjectSchemaInte
1515
/**
1616
* @param array<string, mixed> $input
1717
*
18-
* @return array<string, mixed>
18+
* @return null|array<string, mixed>
1919
*/
20-
protected function parseFields(array $input, Errors $childrenErrors): array
20+
protected function parseFields(array $input, Errors $childrenErrors): ?array
2121
{
22-
$output = [];
22+
$fields = [];
2323

2424
foreach ($this->getFieldToSchema() as $fieldName => $fieldSchema) {
2525
try {
2626
if ($this->skip($input, $fieldName)) {
2727
continue;
2828
}
2929

30-
$output[$fieldName] = $fieldSchema->parse($input[$fieldName] ?? null);
30+
$fields[$fieldName] = $fieldSchema->parse($input[$fieldName] ?? null);
3131
} catch (ErrorsException $e) {
3232
$childrenErrors->add($e->errors, $fieldName);
3333
}
3434
}
3535

36-
return $output;
36+
if ($childrenErrors->has()) {
37+
return null;
38+
}
39+
40+
return $fields;
3741
}
3842
}

src/Schema/ObjectSchema.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,18 @@ final class ObjectSchema extends AbstractObjectSchema implements ObjectSchemaInt
1616
* @param array<mixed, mixed> $fieldToSchema
1717
* @param class-string $classname
1818
*/
19-
public function __construct(array $fieldToSchema, private string $classname = \stdClass::class, private bool $construct = false)
20-
{
19+
public function __construct(
20+
array $fieldToSchema,
21+
private string $classname = \stdClass::class,
22+
private bool $construct = false
23+
) {
2124
parent::__construct($fieldToSchema);
2225
}
2326

2427
/**
2528
* @param array<string, mixed> $input
2629
*/
27-
protected function parseFields(array $input, Errors $childrenErrors): object
30+
protected function parseFields(array $input, Errors $childrenErrors): ?object
2831
{
2932
$fields = [];
3033
foreach ($this->getFieldToSchema() as $fieldName => $fieldSchema) {
@@ -39,6 +42,10 @@ protected function parseFields(array $input, Errors $childrenErrors): object
3942
}
4043
}
4144

45+
if ($childrenErrors->has()) {
46+
return null;
47+
}
48+
4249
if (!$this->construct) {
4350
$object = new ($this->classname);
4451

tests/Unit/Schema/AssocSchemaTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Chubbyphp\Tests\Parsing\Unit\Schema;
66

7+
use Chubbyphp\Parsing\Errors;
78
use Chubbyphp\Parsing\ErrorsException;
89
use Chubbyphp\Parsing\Schema\AssocSchema;
910
use Chubbyphp\Parsing\Schema\BoolSchema;
@@ -289,6 +290,29 @@ public function testParseFailedWithFailedFields(): void
289290
}
290291
}
291292

293+
public function testParseFieldsReturnsNullWithChildrenErrors(): void
294+
{
295+
$schema = new AssocSchema(['field1' => new StringSchema(), 'field2' => new IntSchema()]);
296+
$childrenErrors = new Errors();
297+
298+
$parseFields = new \ReflectionMethod(AssocSchema::class, 'parseFields');
299+
$parseFields->setAccessible(true);
300+
301+
self::assertNull($parseFields->invoke($schema, ['field1' => 'test', 'field2' => 'invalid'], $childrenErrors));
302+
self::assertSame([
303+
[
304+
'path' => 'field2',
305+
'error' => [
306+
'code' => 'int.type',
307+
'template' => 'Type should be "int", {{given}} given',
308+
'variables' => [
309+
'given' => 'string',
310+
],
311+
],
312+
],
313+
], $childrenErrors->jsonSerialize());
314+
}
315+
292316
public function testParseFailedWithOptionalButStillNotProvidedEnoughFields(): void
293317
{
294318
try {

tests/Unit/Schema/ObjectSchemaTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Chubbyphp\Tests\Parsing\Unit\Schema;
66

7+
use Chubbyphp\Parsing\Errors;
78
use Chubbyphp\Parsing\ErrorsException;
89
use Chubbyphp\Parsing\Schema\BoolSchema;
910
use Chubbyphp\Parsing\Schema\FloatSchema;
@@ -348,6 +349,29 @@ public function testParseFailedWithFailedFields(): void
348349
}
349350
}
350351

352+
public function testParseFieldsReturnsNullWithChildrenErrors(): void
353+
{
354+
$schema = new ObjectSchema(['field1' => new StringSchema(), 'field2' => new IntSchema()]);
355+
$childrenErrors = new Errors();
356+
357+
$parseFields = new \ReflectionMethod(ObjectSchema::class, 'parseFields');
358+
$parseFields->setAccessible(true);
359+
360+
self::assertNull($parseFields->invoke($schema, ['field1' => 'test', 'field2' => 'invalid'], $childrenErrors));
361+
self::assertSame([
362+
[
363+
'path' => 'field2',
364+
'error' => [
365+
'code' => 'int.type',
366+
'template' => 'Type should be "int", {{given}} given',
367+
'variables' => [
368+
'given' => 'string',
369+
],
370+
],
371+
],
372+
], $childrenErrors->jsonSerialize());
373+
}
374+
351375
public function testParseFailedWithOptionalButStillNotProvidedEnoughFields(): void
352376
{
353377
try {

0 commit comments

Comments
 (0)