The path values in validation errors are incorrect when a data structure contains references to the same object.
Here is a test script:
#!/usr/bin/env perl
use 5.016;
use strict;
use warnings;
use utf8;
use JSON::Validator::Joi qw(joi);
use Mojo::JSON qw(true);
use Test::More;
my $schema = joi->object->props(
array_of_strings => joi->array->items( joi->string ),
);
subtest different_array_refs => sub {
my @errors = $schema->validate( { array_of_strings => [ [], [], [], [] ] } );
is $errors[0]->path, '/array_of_strings/0';
is $errors[1]->path, '/array_of_strings/1';
is $errors[2]->path, '/array_of_strings/2';
is $errors[3]->path, '/array_of_strings/3';
};
subtest same_array_ref => sub {
my $ref = [];
my @errors = $schema->validate( { array_of_strings => [ $ref, $ref, $ref, $ref ] } );
is $errors[0]->path, '/array_of_strings/0';
is $errors[1]->path, '/array_of_strings/1';
is $errors[2]->path, '/array_of_strings/2';
is $errors[3]->path, '/array_of_strings/3';
};
subtest same_boolean_ref => sub {
my @errors = $schema->validate( { array_of_strings => [ true, true, true, true ] } );
is $errors[0]->path, '/array_of_strings/0';
is $errors[1]->path, '/array_of_strings/1';
is $errors[2]->path, '/array_of_strings/2';
is $errors[3]->path, '/array_of_strings/3';
};
done_testing;
# Output:
#
# # Subtest: different_array_refs
# ok 1
# ok 2
# ok 3
# ok 4
# 1..4
# ok 1 - different_array_refs
# # Subtest: same_array_ref
# ok 1
# not ok 2
# # Failed test at t/json-validator.t line 28.
# # got: '/array_of_strings/0'
# # expected: '/array_of_strings/1'
# not ok 3
# # Failed test at t/json-validator.t line 29.
# # got: '/array_of_strings/0'
# # expected: '/array_of_strings/2'
# not ok 4
# # Failed test at t/json-validator.t line 30.
# # got: '/array_of_strings/0'
# # expected: '/array_of_strings/3'
# 1..4
# # Looks like you failed 3 tests of 4.
# not ok 2 - same_array_ref
# # Failed test 'same_array_ref'
# # at t/json-validator.t line 31.
# # Subtest: same_boolean_ref
# ok 1
# not ok 2
# # Failed test at t/json-validator.t line 36.
# # got: '/array_of_strings/0'
# # expected: '/array_of_strings/1'
# not ok 3
# # Failed test at t/json-validator.t line 37.
# # got: '/array_of_strings/0'
# # expected: '/array_of_strings/2'
# not ok 4
# # Failed test at t/json-validator.t line 38.
# # got: '/array_of_strings/0'
# # expected: '/array_of_strings/3'
# 1..4
# # Looks like you failed 3 tests of 4.
# not ok 3 - same_boolean_ref
# # Failed test 'same_boolean_ref'
# # at t/json-validator.t line 39.
# 1..3
# # Looks like you failed 2 tests of 3.
The Problem seems to be line 436 in JSON::Validator. Cloning the errors and overwritting the path fixes the problem:
# Avoid recursion
if ($self->{seen}{$seen_addr}) {
my $errors_copy = Clone::clone($self->{seen}{$seen_addr});
$_->path($path) for @{$errors_copy};
return @{$errors_copy};
}
Expected behavior
All path values in validation errors are correct.
Actual behavior
Some path values in validation errors are incorrect.
Steps to reproduce the behavior
The path values in validation errors are incorrect when a data structure contains references to the same object.
Here is a test script:
The Problem seems to be line 436 in JSON::Validator. Cloning the errors and overwritting the path fixes the problem:
Expected behavior
All path values in validation errors are correct.
Actual behavior
Some path values in validation errors are incorrect.