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 - <timueller+perl@suse.de> + +- 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" } + } +}