Skip to content

Commit de4af98

Browse files
authored
Merge pull request #80 from slackhq/ih_fix_empty_objects
Fix codegen for empty shapes
2 parents 8fa6864 + 54a6298 commit de4af98

File tree

4 files changed

+58
-2
lines changed

4 files changed

+58
-2
lines changed

src/Codegen/Constraints/ObjectBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ protected function getCheckMethodCode(
153153
$hb->addInlineComment('Hack to prevent us from having to change the params names when we are not using them.');
154154
$hb->addAssignment('$_', '$input', HackBuilderValues::literal());
155155
$hb->addAssignment('$_', '$pointer', HackBuilderValues::literal());
156-
$hb->addReturn('dict[]', HackBuilderValues::literal());
156+
$hb->addReturn('shape()', HackBuilderValues::literal());
157157

158158
return $hb;
159159
}

tests/ObjectSchemaValidatorTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,4 +692,21 @@ public function testInvalidMinPropertiesWithNoAdditionalProperties(): void {
692692
expect($constraint['got'] ?? null)->toEqual('a');
693693
}
694694

695+
public function testEmptyClosedShape(): void {
696+
$validator = new ObjectSchemaValidator(dict[
697+
'empty_closed_shape' => dict[]
698+
]);
699+
$validator->validate();
700+
expect($validator->isValid())->toBeTrue();
701+
expect($validator->getValidatedInput())->toEqual(shape('empty_closed_shape' => shape()));
702+
703+
// Additional properties are discarded
704+
$validator = new ObjectSchemaValidator(dict[
705+
'empty_closed_shape' => dict['foo' => 'bar']
706+
]);
707+
$validator->validate();
708+
expect($validator->isValid())->toBeTrue();
709+
expect($validator->getValidatedInput())->toEqual(shape('empty_closed_shape' => shape()));
710+
}
711+
695712
}

tests/examples/codegen/ObjectSchemaValidator.php

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* To re-generate this file run `make test`
66
*
77
*
8-
* @generated SignedSource<<7fa7d1f5ae7e84bf34ab173568728f05>>
8+
* @generated SignedSource<<39430f90b530b5635008632715853853>>
99
*/
1010
namespace Slack\Hack\JsonSchema\Tests\Generated;
1111
use namespace Slack\Hack\JsonSchema;
@@ -97,6 +97,9 @@
9797

9898
type TObjectSchemaValidatorPropertiesInvalidMinPropertiesWithNoAdditionalProperties = dict<string, mixed>;
9999

100+
type TObjectSchemaValidatorPropertiesEmptyClosedShape = shape(
101+
);
102+
100103
type TObjectSchemaValidator = shape(
101104
?'only_additional_properties' => TObjectSchemaValidatorPropertiesOnlyAdditionalProperties,
102105
?'only_no_additional_properties' => TObjectSchemaValidatorPropertiesOnlyNoAdditionalProperties,
@@ -119,6 +122,7 @@
119122
?'only_max_properties' => TObjectSchemaValidatorPropertiesOnlyMaxProperties,
120123
?'min_and_max_properties' => TObjectSchemaValidatorPropertiesMinAndMaxProperties,
121124
?'invalid_min_properties_with_no_additional_properties' => TObjectSchemaValidatorPropertiesInvalidMinPropertiesWithNoAdditionalProperties,
125+
?'empty_closed_shape' => TObjectSchemaValidatorPropertiesEmptyClosedShape,
122126
...
123127
);
124128

@@ -1648,6 +1652,24 @@ public static function check(
16481652
}
16491653
}
16501654

1655+
final class ObjectSchemaValidatorPropertiesEmptyClosedShape {
1656+
1657+
private static bool $coerce = false;
1658+
private static keyset<string> $properties = keyset[
1659+
];
1660+
1661+
public static function check(
1662+
mixed $input,
1663+
string $pointer,
1664+
): TObjectSchemaValidatorPropertiesEmptyClosedShape {
1665+
// Hack to prevent us from having to change the params names when we are not
1666+
// using them.
1667+
$_ = $input;
1668+
$_ = $pointer;
1669+
return shape();
1670+
}
1671+
}
1672+
16511673
final class ObjectSchemaValidator
16521674
extends JsonSchema\BaseValidator<TObjectSchemaValidator> {
16531675

@@ -1899,6 +1921,17 @@ public static function check(
18991921
}
19001922
}
19011923

1924+
if (\HH\Lib\C\contains_key($typed, 'empty_closed_shape')) {
1925+
try {
1926+
$output['empty_closed_shape'] = ObjectSchemaValidatorPropertiesEmptyClosedShape::check(
1927+
$typed['empty_closed_shape'],
1928+
JsonSchema\get_pointer($pointer, 'empty_closed_shape'),
1929+
);
1930+
} catch (JsonSchema\InvalidFieldException $e) {
1931+
$errors = \HH\Lib\Vec\concat($errors, $e->errors);
1932+
}
1933+
}
1934+
19021935
if (\HH\Lib\C\count($errors)) {
19031936
throw new JsonSchema\InvalidFieldException($pointer, $errors);
19041937
}

tests/examples/object-schema.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,12 @@
176176
"type": "object",
177177
"minProperties": 1,
178178
"additionalProperties": false
179+
},
180+
"empty_closed_shape": {
181+
"type": "object",
182+
"additionalProperties": false,
183+
"discardAdditionalProperties": true,
184+
"properties": {}
179185
}
180186
}
181187
}

0 commit comments

Comments
 (0)