Rework hash vs array derreference

This commit is contained in:
Alberto Simões
2023-03-11 16:15:06 +00:00
parent 513039dd53
commit 1ac6bb9050
3 changed files with 34 additions and 17 deletions

View File

@@ -1,3 +1,6 @@
0.13
o rework commit 495fcbc
0.12 0.12
o revert commit 495fcbc, see #7: breaks backwards o revert commit 495fcbc, see #7: breaks backwards
compatibility. compatibility.

View File

@@ -196,21 +196,30 @@ sub _traverse {
foreach my $key (keys %{$reference}) { foreach my $key (keys %{$reference}) {
if (ref($reference->{$key}) eq 'ARRAY') { if (ref($reference->{$key}) eq 'ARRAY') {
# just use the 1st one, more elements in array are expected to be the same
foreach my $item (@{$hash->{$key}}) { # either it is undefined (optional values)
if (ref($item) eq q(HASH)) { # or it should be an array, so we can derreference it.
# traverse the structure pushing our key to the @tree if (!defined($hash->{$key}) || ref($hash->{$key}) eq "ARRAY") {
$self->_traverse($reference->{$key}->[0], $item, @tree, $key);
} # just use the 1st one, more elements in array are expected to be the same
else { foreach my $item (@{$hash->{$key}}) {
# a value, this is tricky if (ref($item) eq q(HASH)) {
$self->_traverse( # traverse the structure pushing our key to the @tree
{ item => $reference->{$key}->[0] }, $self->_traverse($reference->{$key}->[0], $item, @tree, $key);
{ item => $item }, }
@tree, $key else {
); # a value, this is tricky
$self->_traverse(
{ item => $reference->{$key}->[0] },
{ item => $item },
@tree, $key
);
}
} }
} }
else {
push @{$self->{errors}}, "$key is not an array";
}
} }
elsif (ref($reference->{$key}) eq 'HASH') { elsif (ref($reference->{$key}) eq 'HASH') {
$self->_traverse($reference->{$key}, $hash->{$key}, @tree, $key); $self->_traverse($reference->{$key}, $hash->{$key}, @tree, $key);

13
t/run.t
View File

@@ -409,14 +409,14 @@ ok($v4->validate({age => 8}), "cache check second run, no error");
# optional array, see: # optional array, see:
# https://github.com/TLINDEN/Data-Validate-Struct/issues/7 # https://github.com/TLINDEN/Data-Validate-Struct/issues/7
my $ref4 = { my $ref5 = {
routers => [ { routers => [ {
stubs => [ { stubs => [ {
network => 'ipv4', network => 'ipv4',
}, {} ], }, {} ],
}, {}, ], }, {}, ],
}; };
my $test4 = { my $test5 = {
'routers' => [ 'routers' => [
{ {
'stubs' => [ 'stubs' => [
@@ -431,6 +431,11 @@ my $test4 = {
}, },
], ],
}; };
my $v4 = Data::Validate::Struct->new($ref4); my $v5 = Data::Validate::Struct->new($ref5);
ok($v4->validate($test4), "check optional " . $Data::Validate::Struct::VERSION); ok($v5->validate($test5), "check optional " . $Data::Validate::Struct::VERSION);
# different references
my $v6 = Data::Validate::Struct->new({ foo => [{bar => 'int'}]});
ok(!$v6->validate({foo=>{bar=>10}}));
done_testing(); done_testing();