Skip to content

Commit f867b08

Browse files
committed
optimize test
1 parent 31b4505 commit f867b08

3 files changed

Lines changed: 169 additions & 20 deletions

File tree

phpstan.neon

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
parameters:
2+
ignoreErrors:
3+
-
4+
message: '#Dead catch - ReflectionException is never thrown in the try block#'

src/Schema/ObjectConstructorSchema.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public function __construct(array $fieldToSchema, private string $classname)
6868
/**
6969
* @param array<string, mixed> $input
7070
*/
71-
protected function parseFields(array $input, Errors $childrenErrors): ?object
71+
protected function parseFields(array $input, Errors $childrenErrors): object
7272
{
7373
$parameters = [];
7474

tests/Unit/Schema/ObjectConstructorSchemaTest.php

Lines changed: 165 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Chubbyphp\Tests\Parsing\Unit\Schema;
66

77
use Chubbyphp\Parsing\ErrorsException;
8+
use Chubbyphp\Parsing\Schema\BoolSchema;
89
use Chubbyphp\Parsing\Schema\FloatSchema;
910
use Chubbyphp\Parsing\Schema\IntSchema;
1011
use Chubbyphp\Parsing\Schema\ObjectConstructorSchema;
@@ -17,6 +18,7 @@ public function __construct(
1718
public readonly string $field1,
1819
public readonly int $field2,
1920
public readonly ?float $field3 = null,
21+
public readonly ?float $field4 = null,
2022
) {}
2123

2224
public function jsonSerialize(): array
@@ -25,6 +27,7 @@ public function jsonSerialize(): array
2527
'field1' => $this->field1,
2628
'field2' => $this->field2,
2729
'field3' => $this->field3,
30+
'field4' => $this->field4,
2831
];
2932
}
3033
}
@@ -108,28 +111,30 @@ public function testConstructWithAdditionalFieldSchema(): void
108111
new ObjectConstructorSchema([
109112
'field1' => new StringSchema(),
110113
'field2' => new IntSchema(),
111-
'field3' => new FloatSchema(),
112-
'field4' => new FloatSchema(),
113-
], ObjectConstructorDemo::class)->optional(['field3']);
114+
'field3' => new FloatSchema()->nullable(),
115+
'field4' => new FloatSchema()->nullable(),
116+
'field5' => new FloatSchema(),
117+
], ObjectConstructorDemo::class)->optional(['field3', 'field4']);
114118

115119
throw new \Exception('code should not be reached');
116120
} catch (\InvalidArgumentException $invalidArgumentException) {
117121
self::assertSame(
118-
'Additional fieldToSchema for "'.ObjectConstructorDemo::class.'" __construct parameters: "field4"',
122+
'Additional fieldToSchema for "'.ObjectConstructorDemo::class.'" __construct parameters: "field5"',
119123
$invalidArgumentException->getMessage()
120124
);
121125
}
122126
}
123127

124128
public function testSuccessWithAllParameters(): void
125129
{
126-
$input = ['field1' => 'test', 'field2' => 5, 'field3' => 3.14159];
130+
$input = ['field1' => 'test', 'field2' => 5, 'field3' => 3.14159, 'field4' => 1.61803];
127131

128132
$schema = new ObjectConstructorSchema([
129133
'field1' => new StringSchema(),
130134
'field2' => new IntSchema(),
131-
'field3' => new FloatSchema(),
132-
], ObjectConstructorDemo::class)->optional(['field3']);
135+
'field3' => new FloatSchema()->nullable(),
136+
'field4' => new FloatSchema()->nullable(),
137+
], ObjectConstructorDemo::class)->optional(['field3', 'field4']);
133138

134139
/** @var ObjectConstructorDemo $object */
135140
$object = $schema->parse($input);
@@ -141,20 +146,21 @@ public function testSuccessWithAllParameters(): void
141146

142147
public function testSuccessWithAllParametersOptionalConsidered(): void
143148
{
144-
$input = ['field1' => 'test', 'field2' => 5];
149+
$input = ['field1' => 'test', 'field2' => 5, 'field4' => 1.61803];
145150

146151
$schema = new ObjectConstructorSchema([
147152
'field1' => new StringSchema(),
148153
'field2' => new IntSchema(),
149-
'field3' => new FloatSchema(),
150-
], ObjectConstructorDemo::class)->optional(['field3']);
154+
'field3' => new FloatSchema()->nullable(),
155+
'field4' => new FloatSchema()->nullable(),
156+
], ObjectConstructorDemo::class)->optional(['field3', 'field4']);
151157

152158
/** @var ObjectConstructorDemo $object */
153159
$object = $schema->parse($input);
154160

155161
self::assertInstanceOf(ObjectConstructorDemo::class, $object);
156162

157-
self::assertSame([...$input, 'field3' => null], $object->jsonSerialize());
163+
self::assertSame(['field1' => 'test', 'field2' => 5, 'field3' => null, 'field4' => 1.61803], $object->jsonSerialize());
158164
}
159165

160166
public function testSuccessWithRequiredParameters(): void
@@ -164,14 +170,14 @@ public function testSuccessWithRequiredParameters(): void
164170
$schema = new ObjectConstructorSchema([
165171
'field1' => new StringSchema(),
166172
'field2' => new IntSchema(),
167-
], ObjectConstructorDemo::class)->optional(['field3']);
173+
], ObjectConstructorDemo::class)->optional(['field3', 'field4']);
168174

169175
/** @var ObjectConstructorDemo $object */
170176
$object = $schema->parse($input);
171177

172178
self::assertInstanceOf(ObjectConstructorDemo::class, $object);
173179

174-
self::assertSame([...$input, 'field3' => null], $object->jsonSerialize());
180+
self::assertSame([...$input, 'field3' => null, 'field4' => null], $object->jsonSerialize());
175181
}
176182

177183
public function testFailedWithInvalidValue(): void
@@ -181,8 +187,9 @@ public function testFailedWithInvalidValue(): void
181187
$schema = new ObjectConstructorSchema([
182188
'field1' => new StringSchema(),
183189
'field2' => new IntSchema(),
184-
'field3' => new FloatSchema(),
185-
], ObjectConstructorDemo::class)->optional(['field3']);
190+
'field3' => new FloatSchema()->nullable(),
191+
'field4' => new FloatSchema()->nullable(),
192+
], ObjectConstructorDemo::class)->optional(['field3', 'field4']);
186193

187194
try {
188195
$schema->parse($input);
@@ -211,8 +218,9 @@ public function testFailedWithInvalidValueNotCatchedByFieldSchema(): void
211218
$schema = new ObjectConstructorSchema([
212219
'field1' => new StringSchema(),
213220
'field2' => new IntSchema(),
214-
'field3' => new StringSchema(),
215-
], ObjectConstructorDemo::class)->optional(['field3']);
221+
'field3' => new StringSchema()->nullable(),
222+
'field4' => new FloatSchema()->nullable(),
223+
], ObjectConstructorDemo::class)->optional(['field3', 'field4']);
216224

217225
try {
218226
$schema->parse($input);
@@ -246,8 +254,9 @@ public function testFailedWithUnknownException(): void
246254
$schema = new ObjectConstructorSchema([
247255
'field1' => new StringSchema(),
248256
'field2' => new IntSchema(),
249-
'field3' => new FloatSchema()->postParse(static fn () => throw $exception),
250-
], ObjectConstructorDemo::class)->optional(['field3']);
257+
'field3' => new FloatSchema()->nullable()->postParse(static fn () => throw $exception),
258+
'field4' => new FloatSchema()->nullable(),
259+
], ObjectConstructorDemo::class)->optional(['field3', 'field4']);
251260

252261
try {
253262
$schema->parse($input);
@@ -274,4 +283,141 @@ public function testFailedWithTypeErrorNotMatchingPattern(): void
274283
self::assertSame('some unrelated type error', $e->getMessage());
275284
}
276285
}
286+
287+
public function testParseSuccessWithPreParse(): void
288+
{
289+
$input = ['field1' => 'test', 'field2' => 5, 'field3' => null, 'field4' => null];
290+
291+
$schema = new ObjectConstructorSchema([
292+
'field1' => new StringSchema(),
293+
'field2' => new IntSchema(),
294+
'field3' => new FloatSchema()->nullable(),
295+
'field4' => new FloatSchema()->nullable(),
296+
], ObjectConstructorDemo::class)
297+
->optional(['field3', 'field4'])
298+
->preParse(static fn () => $input)
299+
;
300+
301+
self::assertSame($input, $schema->parse(null)->jsonSerialize());
302+
}
303+
304+
public function testParseSuccessWithPostParse(): void
305+
{
306+
$input = ['field1' => 'test', 'field2' => 5];
307+
308+
$schema = new ObjectConstructorSchema([
309+
'field1' => new StringSchema(),
310+
'field2' => new IntSchema(),
311+
'field3' => new FloatSchema()->nullable(),
312+
'field4' => new FloatSchema()->nullable(),
313+
], ObjectConstructorDemo::class)
314+
->optional(['field3', 'field4'])
315+
->postParse(static fn (ObjectConstructorDemo $output) => new ObjectConstructorDemo(...[...$output->jsonSerialize(), 'field2' => 10]))
316+
;
317+
318+
self::assertSame([...$input, 'field2' => 10, 'field3' => null, 'field4' => null], (array) $schema->parse($input));
319+
}
320+
321+
public function testParseFailedWithCatch(): void
322+
{
323+
$schema = (new ObjectConstructorSchema([
324+
'field1' => new StringSchema(),
325+
'field2' => new IntSchema(),
326+
'field3' => new FloatSchema()->nullable(),
327+
'field4' => new FloatSchema()->nullable(),
328+
], ObjectConstructorDemo::class))
329+
->optional(['field3', 'field4'])
330+
->catch(static function (mixed $input, ErrorsException $errorsException) {
331+
self::assertNull($input);
332+
self::assertSame([
333+
[
334+
'path' => '',
335+
'error' => [
336+
'code' => 'object.type',
337+
'template' => 'Type should be "array|\stdClass|\Traversable", {{given}} given',
338+
'variables' => [
339+
'given' => 'NULL',
340+
],
341+
],
342+
],
343+
], $errorsException->errors->jsonSerialize());
344+
345+
return 'catched';
346+
})
347+
;
348+
349+
self::assertSame('catched', $schema->parse(null));
350+
}
351+
352+
public function testSafeParseSuccess(): void
353+
{
354+
$input = ['field1' => 'test', 'field2' => 1];
355+
356+
$schema = (new ObjectConstructorSchema([
357+
'field1' => new StringSchema(),
358+
'field2' => new IntSchema(),
359+
'field3' => new FloatSchema()->nullable(),
360+
'field4' => new FloatSchema()->nullable(),
361+
], ObjectConstructorDemo::class))
362+
->optional(['field3', 'field4'])
363+
;
364+
365+
self::assertSame([...$input, 'field3' => null, 'field4' => null], $schema->safeParse($input)->data->jsonSerialize());
366+
}
367+
368+
public function testSafeParseFailed(): void
369+
{
370+
$schema = (new ObjectConstructorSchema([
371+
'field1' => new StringSchema(),
372+
'field2' => new IntSchema(),
373+
'field3' => new FloatSchema()->nullable(),
374+
'field4' => new FloatSchema()->nullable(),
375+
], ObjectConstructorDemo::class))
376+
->optional(['field3', 'field4'])
377+
;
378+
379+
self::assertSame([
380+
[
381+
'path' => '',
382+
'error' => [
383+
'code' => 'object.type',
384+
'template' => 'Type should be "array|\stdClass|\Traversable", {{given}} given',
385+
'variables' => [
386+
'given' => 'NULL',
387+
],
388+
],
389+
],
390+
], $schema->safeParse(null)->exception->errors->jsonSerialize());
391+
}
392+
393+
public function testGetFieldToSchema(): void
394+
{
395+
$fieldToSchema = ['field1' => new StringSchema(), 'field2' => new IntSchema()];
396+
397+
$schema = new ObjectConstructorSchema($fieldToSchema, ObjectConstructorDemo::class);
398+
399+
self::assertSame($fieldToSchema, $schema->getFieldToSchema());
400+
401+
$fieldToSchema2 = [...$schema->getFieldToSchema(), 'field3' => new BoolSchema()];
402+
403+
$schema2 = new ObjectConstructorSchema($fieldToSchema2, ObjectConstructorDemo::class);
404+
405+
self::assertSame($fieldToSchema2, $schema2->getFieldToSchema());
406+
}
407+
408+
public function testGetFieldSchemaSuccess(): void
409+
{
410+
$field2Schema = new IntSchema();
411+
412+
$schema = new ObjectConstructorSchema(['field1' => new StringSchema(), 'field2' => $field2Schema], ObjectConstructorDemo::class);
413+
414+
self::assertSame($field2Schema, $schema->getFieldSchema('field2'));
415+
}
416+
417+
public function testGetFieldSchemaFailed(): void
418+
{
419+
$schema = new ObjectConstructorSchema(['field1' => new StringSchema(), 'field2' => new IntSchema()], ObjectConstructorDemo::class);
420+
421+
self::assertNull($schema->getFieldSchema('field3'));
422+
}
277423
}

0 commit comments

Comments
 (0)