Hello community,
here is the log from the commit of package perl-JSON-Validator for openSUSE:Factory checked in at 2019-09-30 16:01:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-JSON-Validator (Old)
and /work/SRC/openSUSE:Factory/.perl-JSON-Validator.new.2352 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-JSON-Validator"
Mon Sep 30 16:01:28 2019 rev:8 rq:733997 version:3.15
Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-JSON-Validator/perl-JSON-Validator.changes 2019-08-13 13:20:17.505433742 +0200
+++ /work/SRC/openSUSE:Factory/.perl-JSON-Validator.new.2352/perl-JSON-Validator.changes 2019-09-30 16:01:43.768844493 +0200
@@ -1,0 +2,10 @@
+Fri Sep 27 08:43:15 UTC 2019 -
+
+- updated to 3.15
+ see /usr/share/doc/packages/perl-JSON-Validator/Changes
+
+ 3.15 2019-09-27T09:28:32+0900
+ - Add JSON::Validator::Error->details() #133
+ - Reversed the checksum and nice name for generated definitions #173
+
+-------------------------------------------------------------------
Old:
----
JSON-Validator-3.14.tar.gz
New:
----
JSON-Validator-3.15.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ perl-JSON-Validator.spec ++++++
--- /var/tmp/diff_new_pack.CzGEex/_old 2019-09-30 16:01:44.488842577 +0200
+++ /var/tmp/diff_new_pack.CzGEex/_new 2019-09-30 16:01:44.488842577 +0200
@@ -17,7 +17,7 @@
Name: perl-JSON-Validator
-Version: 3.14
+Version: 3.15
Release: 0
%define cpan_name JSON-Validator
Summary: Validate data against a JSON schema
++++++ JSON-Validator-3.14.tar.gz -> JSON-Validator-3.15.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/JSON-Validator-3.14/Changes new/JSON-Validator-3.15/Changes
--- old/JSON-Validator-3.14/Changes 2019-08-09 23:52:24.000000000 +0200
+++ new/JSON-Validator-3.15/Changes 2019-09-27 02:28:32.000000000 +0200
@@ -1,5 +1,9 @@
Revision history for perl distribution JSON-Validator
+3.15 2019-09-27T09:28:32+0900
+ - Add JSON::Validator::Error->details() #133
+ - Reversed the checksum and nice name for generated definitions #173
+
3.14 2019-08-09T23:52:24+0200
- Fix failing tests #169
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/JSON-Validator-3.14/MANIFEST new/JSON-Validator-3.15/MANIFEST
--- old/JSON-Validator-3.14/MANIFEST 2019-08-09 23:52:25.000000000 +0200
+++ new/JSON-Validator-3.15/MANIFEST 2019-09-27 02:28:34.000000000 +0200
@@ -106,6 +106,7 @@
t/spec/person.json
t/spec/petstore.json
't/spec/space bundle.json'
+t/spec/test-definitions-key.json
t/spec/with-deep-mixed-ref.json
t/spec/with-relative-ref.json
t/stack/Some.pm
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/JSON-Validator-3.14/META.json new/JSON-Validator-3.15/META.json
--- old/JSON-Validator-3.14/META.json 2019-08-09 23:52:25.000000000 +0200
+++ new/JSON-Validator-3.15/META.json 2019-09-27 02:28:34.000000000 +0200
@@ -61,6 +61,6 @@
},
"x_IRC" : "irc://irc.freenode.net/#mojo"
},
- "version" : "3.14",
- "x_serialization_backend" : "JSON::PP version 2.97001"
+ "version" : "3.15",
+ "x_serialization_backend" : "JSON::PP version 4.02"
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/JSON-Validator-3.14/META.yml new/JSON-Validator-3.15/META.yml
--- old/JSON-Validator-3.14/META.yml 2019-08-09 23:52:25.000000000 +0200
+++ new/JSON-Validator-3.15/META.yml 2019-09-27 02:28:33.000000000 +0200
@@ -30,5 +30,5 @@
homepage: https://mojolicious.org
license: http://www.opensource.org/licenses/artistic-license-2.0
repository: https://github.com/mojolicious/json-validator.git
-version: '3.14'
+version: '3.15'
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/JSON-Validator-3.14/lib/JSON/Validator/Error.pm new/JSON-Validator-3.15/lib/JSON/Validator/Error.pm
--- old/JSON-Validator-3.14/lib/JSON/Validator/Error.pm 2019-06-04 21:37:12.000000000 +0200
+++ new/JSON-Validator-3.15/lib/JSON/Validator/Error.pm 2019-09-27 02:18:23.000000000 +0200
@@ -3,16 +3,92 @@
use overload q("") => \&to_string, bool => sub {1}, fallback => 1;
+our $MESSAGES = {
+ allOf => {type => '/allOf Expected %3 - got %4.'},
+ anyOf => {type => '/anyOf Expected %3 - got %4.'},
+ array => {
+ additionalItems => 'Invalid number of items: %3/%4.',
+ maxItems => 'Too many items: %3/%4.',
+ minItems => 'Not enough items: %3/%4.',
+ uniqueItems => 'Unique items required.',
+ },
+ const => {const => 'Does not match const: %3.'},
+ enum => {enum => 'Not in enum list: %3.'},
+ integer => {
+ maximum => '%3 > maximum(%4)',
+ minimum => '%3 < minimum(%4)',
+ multipleOf => 'Not multiple of %3.',
+ },
+ not => {not => 'Should not match.'},
+ null => {null => 'Not null.'},
+ number => {
+ maximum => '%3 > maximum(%4)',
+ minimum => '%3 < minimum(%4)',
+ multipleOf => 'Not multiple of %3.',
+ },
+ object => {
+ additionalProperties => 'Properties not allowed: %3.',
+ maxProperties => 'Too many properties: %3/%4.',
+ minProperties => 'Not enough properties: %3/%4.',
+ required => 'Missing property.',
+ },
+ oneOf => {
+ all_rules_match => 'All of the oneOf rules match.',
+ type => '/oneOf Expected %3 - got %4.',
+ },
+ string => {
+ pattern => 'String does not match %3.',
+ maxLength => 'String is too long: %3/%4.',
+ minLength => 'String is too short: %3/%4.',
+ }
+};
+
+has details => sub { [qw(generic generic)] };
+
+has message => sub {
+ my $self = shift;
+ my $details = $self->details;
+ my $message;
+
+ if (($details->[0] || '') eq 'format') {
+ $message = '%3';
+ }
+ elsif (($details->[1] || '') eq 'type' and @$details == 3) {
+ $message = 'Expected %1 - got %3.';
+ }
+ elsif (my $group = $MESSAGES->{$details->[0]}) {
+ $message = $group->{$details->[1] || 'default'};
+ }
+
+ return join ' ', Failed => @$details unless defined $message;
+
+ $message =~ s!\%(\d)\b!{$details->[$1 - 1] // ''}!ge;
+ return $message;
+};
+
+has path => '/';
+
sub new {
- my $self = bless {}, shift;
- @$self{qw(path message)} = ($_[0] || '/', $_[1] || '');
- $self;
+ my $class = shift;
+
+ # Constructed with attributes
+ return $class->SUPER::new($_[0]) if ref $_[0] eq 'HASH';
+
+ # Constructed with ($path, ...)
+ my $self = $class->SUPER::new;
+ $self->{path} = shift || '/';
+
+ # Constructed with ($path, $message)
+ $self->message(shift) unless ref $_[0];
+
+ # Constructed with ($path, \@details)
+ $self->details(shift) if ref $_[0];
+
+ return $self;
}
-sub message { shift->{message} }
-sub path { shift->{path} }
-sub to_string { sprintf '%s: %s', @{$_[0]}{qw(path message)} }
-sub TO_JSON { {message => $_[0]->{message}, path => $_[0]->{path}} }
+sub to_string { sprintf '%s: %s', $_[0]->path, $_[0]->message }
+sub TO_JSON { {message => $_[0]->message, path => $_[0]->path} }
1;
@@ -34,11 +110,58 @@
=head1 ATTRIBUTES
+=head2 details
+
+ my $error = $error->details(["generic", "generic"]);
+ my $error = $error->details([qw(array type object)]);
+ my $error = $error->details([qw(format date-time Invalid)]);
+ my $array_ref = $error->details;
+
+Details about the error:
+
+=over 2
+
+=item 1.
+
+Often the category of tests that was run. Example values: allOf, anyOf, array,
+const, enum, format, integer, not, null, number, object, oneOf and string.
+
+=item 2.
+
+Often the test that failed. Example values: additionalItems,
+additionalProperties, const, enum, maxItems, maxLength, maxProperties, maximum,
+minItems, minLength. minProperties, minimum, multipleOf, not, null, pattern,
+required, type and uniqueItems,
+
+=item 3.
+
+The rest of the list contains parameters for the test that failed. It can be a
+plain human-readable string or numbers indicating things such as max/min
+values.
+
+=back
+
=head2 message
my $str = $error->message;
-A human readable description of the error. Defaults to empty string.
+A human readable description of the error. Defaults to being being constructed
+from L</details>. See the C<$MESSAGES> variable in the source code for more
+details.
+
+As an EXPERIMENTAL hack you can localize C<$JSON::Validator::Error::MESSAGES>
+to get i18n support. Example:
+
+ sub validate_i18n {
+ local $JSON::Validator::Error::MESSAGES = {
+ allOf => {type => '/allOf Forventet %3 - fikk %4.'},
+ };
+
+ my @error_norwegian = $jv->validate({age => 42});
+ }
+
+Note that the error messages might contain a mix of English and the local
+language. Run some tests to see how it looks.
=head2 path
@@ -50,7 +173,9 @@
=head2 new
- my $error = JSON::Validator::Error->new($path, $message);
+ my $error = JSON::Validator::Error->new(\%attributes);
+ my $error = JSON::Validator::Error->new($path, \@details);
+ my $error = JSON::Validator::Error->new($path, \@details);
Object constructor.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/JSON-Validator-3.14/lib/JSON/Validator.pm new/JSON-Validator-3.15/lib/JSON/Validator.pm
--- old/JSON-Validator-3.14/lib/JSON/Validator.pm 2019-08-09 23:52:24.000000000 +0200
+++ new/JSON-Validator-3.15/lib/JSON/Validator.pm 2019-09-27 02:28:32.000000000 +0200
@@ -23,8 +23,7 @@
use constant RECURSION_LIMIT => $ENV{JSON_VALIDATOR_RECURSION_LIMIT} || 100;
use constant SPECIFICATION_URL => 'http://json-schema.org/draft-04/schema#';
-our $DEFINITIONS = 'definitions';
-our $VERSION = '3.14';
+our $VERSION = '3.15';
our $YAML_LOADER = eval q[use YAML::XS 0.67; YAML::XS->can('Load')]; # internal
our @EXPORT_OK = qw(joi validate_json);
@@ -60,51 +59,55 @@
sub bundle {
my ($self, $args) = @_;
- my @topics = ([undef, my $bundle = {}]);
my ($cloner, $tied);
- $topics[0][0]
+ my $schema
= $args->{schema} ? $self->_resolve($args->{schema}) : $self->schema->data;
-
- local $DEFINITIONS = $args->{ref_key} || $DEFINITIONS;
- Mojo::Util::deprecated('bundle({ref_key => "..."}) will be removed.')
- if $args->{ref_key};
+ my @topics = ([$schema, my $bundle = {}, '']); # ([$from, $to], ...);
if ($args->{replace}) {
$cloner = sub {
- my $from = shift;
- my $ref = ref $from;
- $from = $tied->schema if $ref eq 'HASH' and $tied = tied %$from;
- my $to = $ref eq 'ARRAY' ? [] : $ref eq 'HASH' ? {} : $from;
- push @topics, [$from, $to] if $ref;
+ my $from = shift;
+ my $from_type = ref $from;
+ $from = $tied->schema if $from_type eq 'HASH' and $tied = tied %$from;
+ my $to = $from_type eq 'ARRAY' ? [] : $from_type eq 'HASH' ? {} : $from;
+ push @topics, [$from, $to] if $from_type;
return $to;
};
}
else {
- my %seen;
- $bundle->{$DEFINITIONS} = $topics[0][0]{$DEFINITIONS} || {};
$cloner = sub {
my $from = shift;
my $from_type = ref $from;
- if ($from_type eq 'HASH' and my $ref = tied %$from) {
- return $from
- if !$args->{schema}
- and $ref->fqn =~ m!^\Q$self->{root_schema_url}\E\#!;
-
- my $k = $self->_definitions_key($bundle, $ref, \%seen);
- push @topics, [$ref->schema, $bundle->{$DEFINITIONS}{$k} ||= {}]
- unless $seen{$ref->fqn}++;
- tie my %ref, 'JSON::Validator::Ref', $ref->schema, "#/$DEFINITIONS/$k";
- return \%ref;
+ $tied = $from_type eq 'HASH' && tied %$from;
+ unless ($tied) {
+ my $to = $from_type eq 'ARRAY' ? [] : $from_type eq 'HASH' ? {} : $from;
+ push @topics, [$from, $to] if $from_type;
+ return $to;
}
- my $to = $from_type eq 'ARRAY' ? [] : $from_type eq 'HASH' ? {} : $from;
- push @topics, [$from, $to] if $from_type;
- return $to;
+ return $from
+ if !$args->{schema}
+ and $tied->fqn =~ m!^\Q$self->{root_schema_url}\E\#!;
+
+ my $p = $self->_definitions_path($bundle, $tied);
+ unless ($self->{bundled_refs}{$tied->fqn}) {
+ $self->{bundled_refs}{$tied->fqn} = $tied;
+ push @topics, [$schema->{$p->[0]} || {}, $bundle->{$p->[0]} ||= {}];
+ push @topics, [$tied->schema, $bundle->{$p->[0]}{$p->[1]} ||= {}];
+ }
+
+ tie my %ref, 'JSON::Validator::Ref', $tied->schema, "#/$p->[0]/$p->[1]";
+ return \%ref;
};
}
+ Mojo::Util::deprecated('bundle({ref_key => "..."}) will be removed.')
+ if $args->{ref_key};
+ local $self->{definitions_key} = $args->{ref_key};
+ local $self->{bundled_refs} = {};
+
while (@topics) {
my ($from, $to) = @{shift @topics};
if (ref $from eq 'ARRAY') {
@@ -119,7 +122,6 @@
}
}
- delete $bundle->{$DEFINITIONS} unless keys %{$bundle->{$DEFINITIONS}};
return $bundle;
}
@@ -225,27 +227,34 @@
};
}
-sub _definitions_key {
- my ($self, $bundle, $ref, $seen) = @_;
+sub _definitions_path {
+ my ($self, $bundle, $ref) = @_;
+ my $definitions_key = $self->{definitions_key} || 'definitions';
+
+ # No need to rewrite, if it already has a nice name
+ if ($ref->fqn =~ m!#/$definitions_key/([^/]+)$!) {
+ my $key = $1;
+
+ if ( $self->{bundled_refs}{$ref->fqn}
+ or !$bundle->{$definitions_key}{$key}
+ or D($ref->schema) eq D($bundle->{$definitions_key}{$key}))
+ {
+ return [$definitions_key, $key];
+ }
+ }
- # No need to rewrite, when it already has a nice name
- return $1
- if $ref->fqn =~ m!#/$DEFINITIONS/([^/]+)$!
- and ($seen->{$ref->fqn}
- or !$bundle->{$DEFINITIONS}{$1}
- or D($ref->schema) eq D($bundle->{$DEFINITIONS}{$1}));
-
- # Must mask path to file on disk
- my $key = $ref->fqn;
- my $spec_path = (split '#', $key)[0];
+ # Generate definitions key based on filename
+ my ($spec_path, $fragment) = split '#', $ref->fqn;
+ my $key = $fragment;
if (-e $spec_path) {
- $key = sprintf '%s-%s', substr(sha1_sum($key), 0, 10),
- path($spec_path)->basename;
+ $key = join '-', map { s!^\W+!!; $_ } grep {$_} path($spec_path)->basename,
+ $fragment, substr(sha1_sum($spec_path), 0, 10);
}
# Fallback or nicer path name
$key =~ s![^\w-]!_!g;
- $key;
+
+ return [$definitions_key, $key];
}
sub _get {
@@ -611,7 +620,7 @@
if (my $rules = $schema->{not}) {
push @errors, $self->_validate($to_json ? $$to_json : $_[1], $path, $rules);
$self->_report_errors($path, 'not', \@errors) if REPORT;
- return @errors ? () : (E $path, 'Should not match.');
+ return @errors ? () : (E $path, [not => 'not']);
}
if (my $rules = $schema->{allOf}) {
@@ -650,7 +659,7 @@
}
$self->_report_errors($path, 'allOf', \@errors) if REPORT;
- return E $path, "/allOf Expected @{[join '/', _uniq(@expected)]} - got $type."
+ return E $path, [allOf => type => join('/', _uniq(@expected)), $type]
if !@errors and @expected;
return _add_path_to_error_messages(allOf => @errors) if @errors;
return;
@@ -678,7 +687,7 @@
$self->_report_errors($path, 'anyOf', \@errors) if REPORT;
my $expected = join '/', _uniq(@expected);
- return E $path, "/anyOf Expected $expected - got $type." unless @errors;
+ return E $path, [anyOf => type => $expected, $type] unless @errors;
return _add_path_to_error_messages(anyOf => @errors);
}
@@ -711,8 +720,8 @@
return if @errors + @expected + 1 == @$rules;
my $expected = join '/', _uniq(@expected);
- return E $path, "All of the oneOf rules match." unless @errors + @expected;
- return E $path, "/oneOf Expected $expected - got $type." unless @errors;
+ return E $path, [oneOf => 'all_rules_match'] unless @errors + @expected;
+ return E $path, [oneOf => type => $expected => $type] unless @errors;
return _add_path_to_error_messages(oneOf => @errors);
}
@@ -725,9 +734,9 @@
return if $m eq S $i;
}
- local $" = ', ';
- return E $path, sprintf 'Not in enum list: %s.', join ', ',
+ $enum = join ', ',
map { (!defined or ref) ? Mojo::JSON::encode_json($_) : $_ } @$enum;
+ return E $path, [enum => enum => $enum];
}
sub _validate_type_const {
@@ -736,8 +745,7 @@
my $m = S $data;
return if $m eq S $const;
- return E $path, sprintf 'Does not match const: %s.',
- Mojo::JSON::encode_json($const);
+ return E $path, [const => const => Mojo::JSON::encode_json($const)];
}
sub _validate_format {
@@ -746,7 +754,7 @@
return do { warn "Format rule for '$schema->{format}' is missing"; return }
unless $code;
return unless my $err = $code->($value);
- return E $path, $err;
+ return E $path, [format => $schema->{format}, $err];
}
sub _validate_type_any { }
@@ -756,21 +764,21 @@
my @errors;
if (ref $data ne 'ARRAY') {
- return E $path, _expected(array => $data);
+ return E $path, [array => type => _guess_data_type($data)];
}
if (defined $schema->{minItems} and $schema->{minItems} > @$data) {
- push @errors, E $path, sprintf 'Not enough items: %s/%s.', int @$data,
- $schema->{minItems};
+ push @errors, E $path,
+ [array => minItems => int(@$data), $schema->{minItems}];
}
if (defined $schema->{maxItems} and $schema->{maxItems} < @$data) {
- push @errors, E $path, sprintf 'Too many items: %s/%s.', int @$data,
- $schema->{maxItems};
+ push @errors, E $path,
+ [array => maxItems => int(@$data), $schema->{maxItems}];
}
if ($schema->{uniqueItems}) {
my %uniq;
for (@$data) {
next if !$uniq{S($_)}++;
- push @errors, E $path, 'Unique items required.';
+ push @errors, E $path, [array => 'uniqueItems'];
last;
}
}
@@ -797,8 +805,8 @@
}
}
elsif (!$additional_items) {
- push @errors, E $path, sprintf "Invalid number of items: %s/%s.",
- int(@$data), int(@rules);
+ push @errors, E $path,
+ [array => additionalItems => int(@$data), int(@rules)];
}
}
elsif (UNIVERSAL::isa($schema->{items}, 'HASH')) {
@@ -832,7 +840,7 @@
return;
}
- return E $path, _expected(boolean => $value);
+ return E $path, [boolean => type => _guess_data_type($value)];
}
sub _validate_type_integer {
@@ -841,14 +849,14 @@
return @errors if @errors;
return if $value =~ /^-?\d+$/;
- return E $path, "Expected integer - got number.";
+ return E $path, [integer => type => _guess_data_type($value)];
}
sub _validate_type_null {
my ($self, $value, $path, $schema) = @_;
- return E $path, 'Not null.' if defined $value;
- return;
+ return unless defined $value;
+ return E $path, ['null', 'null'];
}
sub _validate_type_number {
@@ -858,10 +866,10 @@
$expected ||= 'number';
if (!defined $value or ref $value) {
- return E $path, _expected($expected => $value);
+ return E $path, [$expected => type => _guess_data_type($value)];
}
unless (_is_number($value)) {
- return E $path, "Expected $expected - got string."
+ return E $path, [$expected => type => _guess_data_type($value)]
if !$self->{coerce}{numbers}
or $value !~ /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
$_[1] = 0 + $value; # coerce input value
@@ -873,16 +881,16 @@
if (my $e
= _cmp($schema->{minimum}, $value, $schema->{exclusiveMinimum}, '<'))
{
- push @errors, E $path, "$value $e minimum($schema->{minimum})";
+ push @errors, E $path, [$expected => minimum => $value, $schema->{minimum}];
}
if (my $e
= _cmp($value, $schema->{maximum}, $schema->{exclusiveMaximum}, '>'))
{
- push @errors, E $path, "$value $e maximum($schema->{maximum})";
+ push @errors, E $path, [$expected => maximum => $value, $schema->{maximum}];
}
if (my $d = $schema->{multipleOf}) {
if (($value / $d) =~ /\.[^0]+$/) {
- push @errors, E $path, "Not multiple of $d.";
+ push @errors, E $path, [$expected => multipleOf => $d];
}
}
@@ -895,17 +903,17 @@
my ($additional, @errors, %rules);
if (ref $data ne 'HASH') {
- return E $path, _expected(object => $data);
+ return E $path, [object => type => _guess_data_type($data)];
}
my @dkeys = sort keys %$data;
if (defined $schema->{maxProperties} and $schema->{maxProperties} < @dkeys) {
- push @errors, E $path, sprintf 'Too many properties: %s/%s.', int @dkeys,
- $schema->{maxProperties};
+ push @errors, E $path,
+ [object => maxProperties => int(@dkeys), $schema->{maxProperties}];
}
if (defined $schema->{minProperties} and $schema->{minProperties} > @dkeys) {
- push @errors, E $path, sprintf 'Not enough properties: %s/%s.', int @dkeys,
- $schema->{minProperties};
+ push @errors, E $path,
+ [object => minProperties => int(@dkeys), $schema->{minProperties}];
}
if (my $n_schema = $schema->{propertyNames}) {
for my $name (keys %$data) {
@@ -942,12 +950,12 @@
}
elsif (my @k = grep { !$rules{$_} } @dkeys) {
local $" = ', ';
- return E $path, "Properties not allowed: @k.";
+ return E $path, [object => additionalProperties => join '/', @k];
}
for my $k (sort keys %required) {
next if exists $data->{$k};
- push @errors, E _path($path, $k), 'Missing property.';
+ push @errors, E _path($path, $k), [object => 'required'];
delete $rules{$k};
}
@@ -974,13 +982,13 @@
my @errors;
if (!defined $value or ref $value) {
- return E $path, _expected(string => $value);
+ return E $path, [string => type => _guess_data_type($value)];
}
if ( B::svref_2object(\$value)->FLAGS & (B::SVp_IOK | B::SVp_NOK)
and 0 + $value eq $value
and $value * 0 == 0)
{
- return E $path, "Expected string - got number."
+ return E $path, [string => type => _guess_data_type($value)]
unless $self->{coerce}{strings};
$_[1] = "$value"; # coerce input value
}
@@ -989,21 +997,19 @@
}
if (defined $schema->{maxLength}) {
if (length($value) > $schema->{maxLength}) {
- push @errors, E $path, sprintf "String is too long: %s/%s.",
- length($value), $schema->{maxLength};
+ push @errors, E $path,
+ [string => maxLength => length($value), $schema->{maxLength}];
}
}
if (defined $schema->{minLength}) {
if (length($value) < $schema->{minLength}) {
- push @errors, E $path, sprintf "String is too short: %s/%s.",
- length($value), $schema->{minLength};
+ push @errors, E $path,
+ [string => minLength => length($value), $schema->{minLength}];
}
}
if (defined $schema->{pattern}) {
my $p = $schema->{pattern};
- unless ($value =~ /$p/) {
- push @errors, E $path, "String does not match '$p'";
- }
+ push @errors, E $path, [string => pattern => $p] unless $value =~ /$p/;
}
return @errors;
@@ -1018,7 +1024,7 @@
for my $e (@errors_with_index) {
my $index = shift @$e;
push @errors, map {
- my $msg = sprintf '/%s/%s %s', $type, $index, $_->{message};
+ my $msg = sprintf '/%s/%s %s', $type, $index, $_->message;
$msg =~ s!(\d+)\s/!$1/!g;
E $_->path, $msg;
} @$e;
@@ -1034,12 +1040,6 @@
return "";
}
-sub _expected {
- my $type = _guess_data_type($_[1], []);
- return "Expected $_[0] - got different $type." if $_[0] =~ /\b$type\b/;
- return "Expected $_[0] - got $type.";
-}
-
# _guess_data_type($data, [{type => ...}, ...])
sub _guess_data_type {
my $ref = ref $_[0];
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/JSON-Validator-3.14/t/bundle.t new/JSON-Validator-3.15/t/bundle.t
--- old/JSON-Validator-3.14/t/bundle.t 2019-06-01 11:27:46.000000000 +0200
+++ new/JSON-Validator-3.15/t/bundle.t 2019-09-27 02:18:23.000000000 +0200
@@ -21,57 +21,61 @@
$bundled = $jv->bundle({
replace => 1,
schema => {
- name => {'$ref' => '#/definitions/name'},
- definitions => {name => {type => 'string'}}
+ definitions => {name => {type => 'string'}},
+ surname => {'$ref' => '#/definitions/name'},
},
});
- is $bundled->{name}{type}, 'string', "[$n] replace=1";
+ is $bundled->{surname}{type}, 'string', "[$n] replace=1";
note "[$n] replace=0";
$bundled = $jv->schema({
- name => {'$ref' => '#/definitions/name'},
- age => {'$ref' => 'b.json#/definitions/age'},
+ surname => {'$ref' => '#/definitions/name'},
+ age => {'$ref' => 'b.json#/definitions/years'},
definitions => {name => {type => 'string'}},
- B => {id => 'b.json', definitions => {age => {type => 'integer'}}},
+ B => {id => 'b.json', definitions => {years => {type => 'integer'}}},
})->bundle;
+ ok $bundled->{definitions}{name},
+ "[$n] definitions/name still in definitions";
is $bundled->{definitions}{name}{type}, 'string',
- "[$n] name still in definitions";
- is $bundled->{definitions}{age}{type}, 'integer', "[$n] added to definitions";
- isnt $bundled->{age}, $jv->schema->get('/age'), "[$n] new age ref";
- is $bundled->{name}, $jv->schema->get('/name'), "[$n] same name ref";
- is $bundled->{age}{'$ref'}, '#/definitions/age',
- "[$n] age \$ref point to /definitions/age";
- is $bundled->{name}{'$ref'}, '#/definitions/name',
- "[$n] name \$ref point to /definitions/name";
+ "[$n] definitions/name/type still in definitions";
+ is $bundled->{definitions}{years}{type}, 'integer',
+ "[$n] added to definitions";
+ isnt $bundled->{age}, $jv->schema->get('/age'), "[$n] new age ref";
+ is $bundled->{surname}, $jv->schema->get('/surname'), "[$n] same surname ref";
+ is $bundled->{age}{'$ref'}, '#/definitions/years',
+ "[$n] age \$ref point to /definitions/years";
+ is $bundled->{surname}{'$ref'}, '#/definitions/name',
+ "[$n] surname \$ref point to /definitions/name";
}
-is $jv->get([qw(name type)]), 'string', 'get /name/$ref';
-is $jv->get('/name/type'), 'string', 'get /name/type';
-is $jv->get('/name/$ref'), undef, 'get /name/$ref';
-is $jv->schema->get('/name/type'), 'string', 'schema get /name/type';
-is $jv->schema->get('/name/$ref'), '#/definitions/name',
- 'schema get /name/$ref';
+is $jv->get([qw(surname type)]), 'string', 'get /surname/$ref';
+is $jv->get('/surname/type'), 'string', 'get /surname/type';
+is $jv->get('/surname/$ref'), undef, 'get /surname/$ref';
+is $jv->schema->get('/surname/type'), 'string', 'schema get /surname/type';
+is $jv->schema->get('/surname/$ref'), '#/definitions/name',
+ 'schema get /surname/$ref';
$bundled = $jv->schema('data://main/bundled.json')->bundle;
is_deeply [sort keys %{$bundled->{definitions}}], ['objtype'],
'no dup definitions';
-my @pathlists = (
- ['spec', 'with-deep-mixed-ref.json'],
- ['spec', File::Spec->updir, 'spec', 'with-deep-mixed-ref.json'],
-);
-for my $pathlist (@pathlists) {
- my $file = path $workdir, @$pathlist;
+for my $path (
+ ['test-definitions-key.json'],
+ ['with-deep-mixed-ref.json'],
+ ['with-deep-mixed-ref.json'],
+ [File::Spec->updir, 'spec', 'with-deep-mixed-ref.json'],
+ )
+{
+ my $file = path $workdir, 'spec', @$path;
+
+ my @expected = qw(age_json-SHA height unit_json-SHA weight_json-SHA);
+ $expected[0] = 'age_json-type-SHA'
+ if $path->[0] eq 'test-definitions-key.json';
+
$bundled = $jv->schema($file)->bundle;
- is_deeply [sort map { s!^[a-z0-9]{10}!SHA!; $_ }
- keys %{$bundled->{definitions}}],
- [qw(
- SHA-age_json
- SHA-unit_json
- SHA-weight_json
- height
- )],
+ is_deeply [sort map { s!-[a-z0-9]{10}$!-SHA!; $_ }
+ keys %{$bundled->{definitions}}], \@expected,
'right definitions in disk spec'
or diag explain $bundled->{definitions};
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/JSON-Validator-3.14/t/coerce-default.t new/JSON-Validator-3.15/t/coerce-default.t
--- old/JSON-Validator-3.14/t/coerce-default.t 2019-06-04 21:37:12.000000000 +0200
+++ new/JSON-Validator-3.15/t/coerce-default.t 2019-09-27 02:18:23.000000000 +0200
@@ -30,11 +30,11 @@
$jv->schema({
type => 'object',
- properties => {tos => {type => 'boolean', default => 'invalid'}},
+ properties => {age => {type => 'number', default => 'invalid'}},
});
@errors = $jv->validate({});
-is $errors[0]{message}, 'Expected boolean - got string.',
+is $errors[0]->message, 'Expected number - got string.',
'default values must be valid';
done_testing;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/JSON-Validator-3.14/t/more-bundle.t new/JSON-Validator-3.15/t/more-bundle.t
--- old/JSON-Validator-3.14/t/more-bundle.t 2019-08-09 23:48:57.000000000 +0200
+++ new/JSON-Validator-3.15/t/more-bundle.t 2019-09-27 02:18:23.000000000 +0200
@@ -150,23 +150,20 @@
return 1
if (eq_deeply($got->{dupe_name}, {type => 'integer'})
and eq_deeply($got->{$other_key}, {type => 'string'})
- and eq_deeply($other_key, re(qr/-more-bundle2_yaml$/)))
- or ((
- eq_deeply($got->{dupe_name}, {type => 'string'})
+ and $other_key =~ qr/\bmore-bundle2_yaml-definitions_dupe_name-\w+$/)
+ or (eq_deeply($got->{dupe_name}, {type => 'string'})
and eq_deeply($got->{$other_key}, {type => 'integer'})
- and eq_deeply($other_key, re(qr/-more-bundle_yaml$/))
- ));
+ and $other_key =~ qr/\bmore-bundle_yaml-definitions_dupe_name-\w+$/);
return (0, 'uh oh, got: ' . (Test::More::explain($got))[0]);
}),
# begin i_contain_refs_to_same_named_definitions definition
type => 'object',
properties => {
- foo => {
- '$ref' => re(qr/^#\/definitions\/(dupe_name|\w+-more-bundle_yaml)$/)
- },
+ foo =>
+ {'$ref' => re(qr/^#\/definitions\/(dupe_name|more-bundle_yaml-.*)$/)},
bar => {
- '$ref' => re(qr/^#\/definitions\/(dupe_name|\w+-more-bundle2_yaml)/)
+ '$ref' => re(qr/^#\/definitions\/(dupe_name|more-bundle2_yaml-.*)$/)
},
},
},
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/JSON-Validator-3.14/t/spec/test-definitions-key.json new/JSON-Validator-3.15/t/spec/test-definitions-key.json
--- old/JSON-Validator-3.14/t/spec/test-definitions-key.json 1970-01-01 01:00:00.000000000 +0100
+++ new/JSON-Validator-3.15/t/spec/test-definitions-key.json 2019-09-27 02:18:23.000000000 +0200
@@ -0,0 +1,11 @@
+{
+ "type": "object",
+ "properties": {
+ "age": { "type": { "$ref": "../definitions/age.json#type" } },
+ "weight": { "$ref": "../definitions/weight.json" },
+ "height": { "$ref": "#/definitions/height" }
+ },
+ "definitions": {
+ "height": { "type": "integer" }
+ }
+}