Skip to content

Commit

Permalink
unevaluated* now checks adjacent keywords not just for annotations, b…
Browse files Browse the repository at this point in the history
…ut existence

see json-schema-org/json-schema-spec#1172 and #collaborators thread
  • Loading branch information
karenetheridge committed Feb 25, 2022
1 parent 2da02c2 commit ef98622
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 6 deletions.
21 changes: 17 additions & 4 deletions lib/JSON/Schema/Modern/Vocabulary/Unevaluated.pm
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ sub _eval_keyword_unevaluatedItems ($self, $data, $schema, $state) {

return 1 if not is_type('array', $data);

# local applicator keywords count as "evaluated"
return 1 if exists $schema->{ $state->{spec_version} =~ /^draft(?:7|2019-09)$/ ? 'additionalItems' : 'items' };
return 1 if $state->{spec_version} !~ /^draft(?:7|2019-09)$/ and exists $schema->{contains};

my @annotations = local_annotations($state);

# a relevant keyword already produced a 'true' annotation at this location
Expand All @@ -61,11 +65,14 @@ sub _eval_keyword_unevaluatedItems ($self, $data, $schema, $state) {
if any { $bools{$_->keyword} && is_type('boolean', $_->annotation) && $_->annotation }
@annotations;

# otherwise, evaluate at every instance item greater than the max of all 'prefixItems'/numeric
# 'items' annotations that isn't in a 'contains' annotation
# otherwise, evaluate at every instance item greater than the max of all 'prefixItems'
# or numeric 'items' annotations
my $max_index_annotation_keyword = $state->{spec_version} eq 'draft2019-09' ? 'items' : 'prefixItems';
my $last_index = max(-1, grep is_type('integer', $_),
map +($_->keyword eq $max_index_annotation_keyword ? $_->annotation : ()), @annotations);
my $last_index = max(-1,
(grep is_type('integer', $_),
map +($_->keyword eq $max_index_annotation_keyword ? $_->annotation : ()), @annotations),
($schema->{$max_index_annotation_keyword}//[])->$#*,
);

return 1 if $last_index == $data->$#*;

Expand Down Expand Up @@ -120,6 +127,8 @@ sub _eval_keyword_unevaluatedProperties ($self, $data, $schema, $state) {

return 1 if not is_type('object', $data);

return 1 if exists $schema->{additionalProperties};

my @evaluated_properties = map {
my $keyword = $_->keyword;
(grep $keyword eq $_, qw(properties additionalProperties patternProperties unevaluatedProperties))
Expand All @@ -130,6 +139,10 @@ sub _eval_keyword_unevaluatedProperties ($self, $data, $schema, $state) {
my @orig_annotations = $state->{annotations}->@*;
my (@valid_properties, @new_annotations);
foreach my $property (sort keys %$data) {
next if exists(($schema->{properties}//{})->{$property})
or any { $property =~ m/$_/ } keys(($schema->{patternProperties}//{})->%*)
or exists $schema->{additionalProperties};

next if any { $_ eq $property } @evaluated_properties;

if (is_type('boolean', $schema->{unevaluatedProperties})) {
Expand Down
4 changes: 2 additions & 2 deletions t/results/draft2020-12-acceptance.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ ref.json 43 0 0
refRemote.json 17 0 0
required.json 9 0 0
type.json 80 0 0
unevaluatedItems.json 48 0 0
unevaluatedItems.json 47 0 1
unevaluatedProperties.json 103 0 0
uniqueItems.json 68 0 0
unknownKeyword.json 3 0 0
Expand All @@ -62,4 +62,4 @@ optional/format-assertion.json 4 0 0
optional/non-bmp-regex.json 12 0 0
optional/refOfUnknownKeyword.json 4 0 0
---------------------------------------------------------------
TOTAL 1153 14 0
TOTAL 1152 14 1

0 comments on commit ef98622

Please sign in to comment.