Skip to content

Commit 0e9e8c0

Browse files
validate_formats now defaults to true
This reflects new understandings of how "$vocabulary": [ <vocab uri>: false ] should work, as discussed in json-schema-org/json-schema-spec#1020 (comment)
1 parent 070a5f3 commit 0e9e8c0

File tree

6 files changed

+25
-37
lines changed

6 files changed

+25
-37
lines changed

Changes

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
Revision history for JSON-Schema-Draft201909
22

33
{{$NEXT}}
4+
- the default value for "validate_formats" is now true, to reflect
5+
the most typical usecase.
46

57
0.019 2020-12-08 18:40:10Z
68
- further improvements to the "terse" output format

lib/JSON/Schema/Draft201909.pm

+5-3
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ has max_traversal_depth => (
5454
has validate_formats => (
5555
is => 'ro',
5656
isa => Bool,
57-
default => 0, # as specified by https://json-schema.org/draft/2019-09/schema#/$vocabulary
57+
default => 1,
5858
);
5959

6060
has collect_annotations => (
@@ -569,8 +569,10 @@ other, or badly-written schemas that could be optimized. Defaults to 50.
569569
570570
=head2 validate_formats
571571
572-
When true, the C<format> keyword will be treated as an assertion, not merely an annotation. Defaults
573-
to false.
572+
When false, the C<format> keyword will be treated as an annotation only (that is, no evaluation
573+
failure will result if the format of the data string is not as specified). When true, the C<format>
574+
keyword will be treated as an assertion, where failure is possible.
575+
Defaults to true.
574576
575577
=head2 format_validations
576578

lib/JSON/Schema/Draft201909/Vocabulary/Format.pm

+5-4
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,15 @@ has _format_validations => (
111111
fc(Mojo::URL->new($_[0])->to_unsafe_string) eq fc($_[0]) && $_[0] !~ /[^[:ascii:]]/;
112112
},
113113
iri => sub { Mojo::URL->new($_[0])->is_abs },
114-
'iri-reference' => sub { 1 },
115114
uuid => sub { $_[0] =~ /^[[:xdigit:]]{8}-(?:[[:xdigit:]]{4}-){3}[[:xdigit:]]{12}$/ },
116-
'uri-template' => sub { 1 },
117115
'json-pointer' => sub { (!length($_[0]) || $_[0] =~ m{^/}) && $_[0] !~ m{~(?![01])} },
118116
'relative-json-pointer' => sub { $_[0] =~ m{^[0-9]+(?:#$|$|/)} && $_[0] !~ m{~(?![01])} },
119117
regex => sub { eval { qr/$_[0]/; 1 ? 1 : 0 } },
118+
119+
# TODO: if the metaschema's $vocabulary entry is true, then we must die on
120+
# encountering these unimplemented formats.
121+
'iri-reference' => sub { 1 },
122+
'uri-template' => sub { 1 },
120123
};
121124

122125
# the subrefs from JSON::Schema::Draft201909->new(format_evaluations => { ... })
@@ -140,8 +143,6 @@ sub _traverse_keyword_format {
140143
sub _eval_keyword_format {
141144
my ($self, $data, $schema, $state) = @_;
142145

143-
# TODO: instead of checking 'validate_formats', we should be referring to the metaschema's entry
144-
# for $vocabulary: { <format url>: <bool> }
145146
if ($state->{validate_formats}
146147
and my $spec = $self->_get_format_validation($schema->{format})) {
147148
return E($state, 'not a%s %s', $schema->{format} =~ /^[aeio]/ ? 'n' : '', $schema->{format})

t/additional-tests.t

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ my $accepter = Test::JSON::Schema::Acceptance->new(test_dir => 't/additional-tes
1515

1616
plan skip_all => 'no tests in this directory to test' if not @{$accepter->_test_data};
1717

18-
my %options = (validate_formats => 1);
18+
my %options = ();
1919
my $js = JSON::Schema::Draft201909->new(%options);
2020
my $js_short_circuit = JSON::Schema::Draft201909->new(%options, short_circuit => 1);
2121
my $encoder = JSON::MaybeXS->new(allow_nonref => 1, utf8 => 0, convert_blessed => 1, canonical => 1, pretty => 1);

t/formats.t

+11-28
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ use Test::Deep;
1111
use Test::Fatal;
1212
use JSON::Schema::Draft201909;
1313

14+
my ($annotation_result, $validation_result);
1415
subtest 'no validation' => sub {
1516
cmp_deeply(
1617
JSON::Schema::Draft201909->new(collect_annotations => 1, validate_formats => 0)
1718
->evaluate('abc', { format => 'uuid' })->TO_JSON,
18-
my $result = {
19+
$annotation_result = {
1920
valid => bool(1),
2021
annotations => [
2122
{
@@ -31,7 +32,7 @@ subtest 'no validation' => sub {
3132
cmp_deeply(
3233
JSON::Schema::Draft201909->new(collect_annotations => 1, validate_formats => 1)
3334
->evaluate('abc', { format => 'uuid' }, { validate_formats => 0 })->TO_JSON,
34-
$result,
35+
$annotation_result,
3536
'format validation can be turned off in evaluate()',
3637
);
3738
};
@@ -41,16 +42,7 @@ subtest 'simple validation' => sub {
4142

4243
cmp_deeply(
4344
$js->evaluate(123, { format => 'uuid' })->TO_JSON,
44-
{
45-
valid => bool(1),
46-
annotations => [
47-
{
48-
instanceLocation => '',
49-
keywordLocation => '/format',
50-
annotation => 'uuid',
51-
},
52-
],
53-
},
45+
$annotation_result,
5446
'non-string values are valid, and produce an annotation',
5547
);
5648

@@ -59,22 +51,13 @@ subtest 'simple validation' => sub {
5951
'2eb8aa08-aa98-11ea-b4aa-73b441d16380',
6052
{ format => 'uuid' },
6153
)->TO_JSON,
62-
{
63-
valid => bool(1),
64-
annotations => [
65-
{
66-
instanceLocation => '',
67-
keywordLocation => '/format',
68-
annotation => 'uuid',
69-
},
70-
],
71-
},
54+
$annotation_result,
7255
'simple success',
7356
);
7457

7558
cmp_deeply(
7659
$js->evaluate('123', { format => 'uuid' })->TO_JSON,
77-
my $result = {
60+
$validation_result = {
7861
valid => bool(0),
7962
errors => [
8063
{
@@ -88,14 +71,14 @@ subtest 'simple validation' => sub {
8871
);
8972

9073
$js = JSON::Schema::Draft201909->new(collect_annotations => 1);
91-
ok(!$js->validate_formats, 'format_validation defaults to false');
74+
ok($js->validate_formats, 'format_validation defaults to true');
9275
cmp_deeply(
93-
$js->evaluate('123', { format => 'uuid' }, { validate_formats => 1 })->TO_JSON,
94-
$result,
95-
'format validation can be turned on in evaluate()',
76+
$js->evaluate('123', { format => 'uuid' }, { validate_formats => 0 })->TO_JSON,
77+
$annotation_result,
78+
'format validation can be turned off in evaluate()',
9679
);
9780

98-
ok(!$js->validate_formats, '...but the value is still false on the object');
81+
ok($js->validate_formats, '...but the value is still true on the object');
9982
};
10083

10184
subtest 'unknown format attribute' => sub {

t/zzz-acceptance.t

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ my $accepter = Test::JSON::Schema::Acceptance->new(
3434
verbose => 1,
3535
);
3636

37-
my %options = (validate_formats => 1);
37+
my %options = ();
3838
my $js = JSON::Schema::Draft201909->new(%options);
3939
my $js_short_circuit = JSON::Schema::Draft201909->new(%options, short_circuit => 1);
4040

0 commit comments

Comments
 (0)