Skip to content

Commit

Permalink
Merge pull request #80 from slackhq/ih_fix_empty_objects
Browse files Browse the repository at this point in the history
Fix codegen for empty shapes
  • Loading branch information
ianhoffman authored Mar 9, 2023
2 parents 8fa6864 + 54a6298 commit de4af98
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/Codegen/Constraints/ObjectBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ protected function getCheckMethodCode(
$hb->addInlineComment('Hack to prevent us from having to change the params names when we are not using them.');
$hb->addAssignment('$_', '$input', HackBuilderValues::literal());
$hb->addAssignment('$_', '$pointer', HackBuilderValues::literal());
$hb->addReturn('dict[]', HackBuilderValues::literal());
$hb->addReturn('shape()', HackBuilderValues::literal());

return $hb;
}
Expand Down
17 changes: 17 additions & 0 deletions tests/ObjectSchemaValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -692,4 +692,21 @@ public function testInvalidMinPropertiesWithNoAdditionalProperties(): void {
expect($constraint['got'] ?? null)->toEqual('a');
}

public function testEmptyClosedShape(): void {
$validator = new ObjectSchemaValidator(dict[
'empty_closed_shape' => dict[]
]);
$validator->validate();
expect($validator->isValid())->toBeTrue();
expect($validator->getValidatedInput())->toEqual(shape('empty_closed_shape' => shape()));

// Additional properties are discarded
$validator = new ObjectSchemaValidator(dict[
'empty_closed_shape' => dict['foo' => 'bar']
]);
$validator->validate();
expect($validator->isValid())->toBeTrue();
expect($validator->getValidatedInput())->toEqual(shape('empty_closed_shape' => shape()));
}

}
35 changes: 34 additions & 1 deletion tests/examples/codegen/ObjectSchemaValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* To re-generate this file run `make test`
*
*
* @generated SignedSource<<7fa7d1f5ae7e84bf34ab173568728f05>>
* @generated SignedSource<<39430f90b530b5635008632715853853>>
*/
namespace Slack\Hack\JsonSchema\Tests\Generated;
use namespace Slack\Hack\JsonSchema;
Expand Down Expand Up @@ -97,6 +97,9 @@

type TObjectSchemaValidatorPropertiesInvalidMinPropertiesWithNoAdditionalProperties = dict<string, mixed>;

type TObjectSchemaValidatorPropertiesEmptyClosedShape = shape(
);

type TObjectSchemaValidator = shape(
?'only_additional_properties' => TObjectSchemaValidatorPropertiesOnlyAdditionalProperties,
?'only_no_additional_properties' => TObjectSchemaValidatorPropertiesOnlyNoAdditionalProperties,
Expand All @@ -119,6 +122,7 @@
?'only_max_properties' => TObjectSchemaValidatorPropertiesOnlyMaxProperties,
?'min_and_max_properties' => TObjectSchemaValidatorPropertiesMinAndMaxProperties,
?'invalid_min_properties_with_no_additional_properties' => TObjectSchemaValidatorPropertiesInvalidMinPropertiesWithNoAdditionalProperties,
?'empty_closed_shape' => TObjectSchemaValidatorPropertiesEmptyClosedShape,
...
);

Expand Down Expand Up @@ -1648,6 +1652,24 @@ public static function check(
}
}

final class ObjectSchemaValidatorPropertiesEmptyClosedShape {

private static bool $coerce = false;
private static keyset<string> $properties = keyset[
];

public static function check(
mixed $input,
string $pointer,
): TObjectSchemaValidatorPropertiesEmptyClosedShape {
// Hack to prevent us from having to change the params names when we are not
// using them.
$_ = $input;
$_ = $pointer;
return shape();
}
}

final class ObjectSchemaValidator
extends JsonSchema\BaseValidator<TObjectSchemaValidator> {

Expand Down Expand Up @@ -1899,6 +1921,17 @@ public static function check(
}
}

if (\HH\Lib\C\contains_key($typed, 'empty_closed_shape')) {
try {
$output['empty_closed_shape'] = ObjectSchemaValidatorPropertiesEmptyClosedShape::check(
$typed['empty_closed_shape'],
JsonSchema\get_pointer($pointer, 'empty_closed_shape'),
);
} catch (JsonSchema\InvalidFieldException $e) {
$errors = \HH\Lib\Vec\concat($errors, $e->errors);
}
}

if (\HH\Lib\C\count($errors)) {
throw new JsonSchema\InvalidFieldException($pointer, $errors);
}
Expand Down
6 changes: 6 additions & 0 deletions tests/examples/object-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,12 @@
"type": "object",
"minProperties": 1,
"additionalProperties": false
},
"empty_closed_shape": {
"type": "object",
"additionalProperties": false,
"discardAdditionalProperties": true,
"properties": {}
}
}
}

0 comments on commit de4af98

Please sign in to comment.