Subject: | Mutually-recursive types don't work |
Date: | Thu, 15 Sep 2011 14:19:04 +0200 |
To: | bug-MooseX-Types [...] rt.cpan.org |
From: | ilmari [...] ilmari.org (Dagfinn Ilmari Mannsåker) |
Defining a set of mutually-recursive types (e.g. to validate an
arbitrary-depth plain data structure) only correctly validates the
top-level and fails when actually recursing. Attached is a test script
that demonstrates this.
--
ilmari
"A disappointingly low fraction of the human race is,
at any given time, on fire." - Stig Sandbeck Mathisen
BEGIN {
package MooseX::Types::Test::MutualRecursion;
use Moose;
use Moose::Util::TypeConstraints;
use MooseX::Types::Moose qw(Value HashRef ArrayRef);
use MooseX::Types -declare => [qw(
RecursiveHashRef
RecursiveArrayRef
RecursiveStruct
)];
## Define a recursive subtype and Cthulhu save us.
subtype RecursiveHashRef()
=> as HashRef[RecursiveStruct()];
subtype RecursiveArrayRef()
=> as ArrayRef[RecursiveStruct()];
subtype RecursiveStruct()
=> as RecursiveArrayRef() | RecursiveHashRef() | Value();
}
{
package MooseX::Types::Test::Recursion::TestRunner;
BEGIN {
use Test::More;
## Grab the newly created test type constraint
MooseX::Types::Test::MutualRecursion->import(':all');
};
ok RecursiveStruct->check("value")
=> 'properly validated "value"';
ok RecursiveStruct->check([])
=> 'properly validated []';
ok RecursiveStruct->check({})
=> 'properly validated {}';
ok RecursiveStruct->check(["value"])
=> 'properly validated ["value"]';
ok RecursiveStruct->check(["value", ["subvalue"]])
=> 'properly validated ["value", ["subvalue"]]';
ok RecursiveStruct->check({key=>"value"})
=> 'properly validated {key=>"value"}';
ok RecursiveStruct->check({key=>{subkey=>"value"}})
=> 'properly validated {key=>{subkey=>"value"}}';
ok RecursiveStruct->check({
key=>{
subkey=>"value",
subkey2=>{
ssubkey1=>["value3"],
ssubkey2=>["value4", { sssubkey1 => "value" } ],
}
}
}) => 'properly validated deeper recursive values';
ok RecursiveStruct->check([{
key=>{
subkey=>"value",
subkey2=>{
ssubkey1=>["value3"],
ssubkey2=>["value4", { sssubkey1 => "value" } ],
}
}
}]) => 'properly validated deeper recursive values';
ok !RecursiveStruct->check(undef)
=> 'properly invalidated undef';
ok !RecursiveStruct->check([undef])
=> 'properly invalidated [undef]';
ok !RecursiveStruct->check({ key => undef })
=> 'properly invalidated { key => undef }';
done_testing;
}