BEGIN {
use_ok(
'Params::Check'
);
Params::Check->
import
(
qw|check last_error allow|
);
}
$Params::Check::VERBOSE
=
$Params::Check::VERBOSE
=
$ARGV
[0] ? 1 : 0;
{ ok( allow( 42,
qr/^\d+$/
),
"Allow based on regex"
);
ok( allow( $0, $0),
" Allow based on string"
);
ok( allow( 42, [0,42] ),
" Allow based on list"
);
ok( allow( 42, [50,
sub
{1}]),
" Allow based on list containing sub"
);
ok( allow( 42, TRUE ),
" Allow based on constant sub"
);
ok(!allow( $0,
qr/^\d+$/
),
"Disallowing based on regex"
);
ok(!allow( 42, $0 ),
" Disallowing based on string"
);
ok(!allow( 42, [0,$0] ),
" Disallowing based on list"
);
ok(!allow( 42, [50,
sub
{0}]),
" Disallowing based on list containing sub"
);
ok(!allow( 42, FALSE ),
" Disallowing based on constant sub"
);
{
my
$sub_called
;
allow( 1, [ 1,
sub
{
$sub_called
++ } ] );
ok( !
$sub_called
,
"Allow short-circuits properly"
);
}
for
my
$thing
(1,
'foo'
,[1]) {
allow(
$thing
,
sub
{ is_deeply(+
shift
,
$thing
,
"Allow coderef gets proper args"
) }
);
}
}
{
my
$tmpl
= {
foo
=> {
default
=> 1 }
};
{
my
$args
= check(
$tmpl
, {} );
ok(
$args
,
"check() call with empty args"
);
is(
$args
->{
'foo'
}, 1,
" got default value"
);
}
{
my
$try
= {
foo
=> 2 };
my
$args
= check(
$tmpl
,
$try
);
ok(
$args
,
"check() call with defined args"
);
is_deeply(
$args
,
$try
,
" found provided value in rv"
);
}
{
my
$try
= {
FOO
=> 2 };
my
$args
= check(
$tmpl
,
$try
);
ok(
$args
,
"check() call with alternate case"
);
is(
$args
->{foo}, 2,
" found provided value in rv"
);
}
{
local
$Params::Check::STRIP_LEADING_DASHES
= 1;
my
$try
= {
-foo
=> 2 };
my
$get
= {
foo
=> 2 };
my
$args
= check(
$tmpl
,
$try
);
ok(
$args
,
"check() call with leading dashes"
);
is_deeply(
$args
,
$get
,
" found provided value in rv"
);
}
}
{
my
$tmpl
= {
Foo
=> {
default
=> 1 } };
for
(1,0) {
local
$Params::Check::PRESERVE_CASE
=
$_
;
my
$expect
=
$_
? {
Foo
=> 42 } : {
Foo
=> 1 };
my
$rv
= check(
$tmpl
, {
Foo
=> 42 } );
ok(
$rv
,
"check() call using PRESERVE_CASE: $_"
);
is_deeply(
$rv
,
$expect
,
" found provided value in rv"
);
}
}
{
{
my
$rv
= check( {}, {
foo
=> 42 } );
is_deeply(
$rv
, {},
"check() call with unknown arguments"
);
like( last_error(),
qr/^Key 'foo' is not a valid key/
,
" warning recorded ok"
);
}
{
local
$Params::Check::ALLOW_UNKNOWN
= 1;
my
$rv
= check( {}, {
foo
=> 42 } );
is_deeply(
$rv
, {
foo
=> 42 },
"check call() with unknown args allowed"
);
}
}
{
my
$foo
;
my
$tmpl
= {
foo
=> {
store
=> \
$foo
}
};
for
( 1, 0 ) {
local
$Params::Check::NO_DUPLICATES
=
$_
;
my
$expect
=
$_
?
undef
: 42;
my
$rv
= check(
$tmpl
, {
foo
=> 42 } );
ok(
$rv
,
"check() call with store key, no_dup: $_"
);
is(
$foo
, 42,
" found provided value in variable"
);
is(
$rv
->{foo},
$expect
,
" found provided value in variable"
);
}
}
{
my
$tmpl
= {
foo
=> {
no_override
=> 1,
default
=> 42 },
};
my
$rv
= check(
$tmpl
, {
foo
=> 13 } );
ok(
$rv
,
"check() call with no_override key"
);
is(
$rv
->{
'foo'
}, 42,
" found default value in rv"
);
like( last_error(),
qr/^You are not allowed to override key/
,
" warning recorded ok"
);
}
{
my
@list
= (
[ {
strict_type
=> 1,
default
=> [] }, 0 ],
[ {
default
=> [] }, 1 ],
);
for
my
$aref
(
@list
) {
my
$tmpl
= {
foo
=>
$aref
->[0] };
local
$Params::Check::STRICT_TYPE
=
$aref
->[1];
{
my
$rv
= check(
$tmpl
, {
foo
=> [] } );
ok(
$rv
,
"check() call with strict_type enabled"
);
is(
ref
$rv
->{foo},
'ARRAY'
,
" found provided value in rv"
);
}
{
my
$rv
= check(
$tmpl
, {
foo
=> {} } );
ok( !
$rv
,
"check() call with strict_type violated"
);
like( last_error(),
qr/^Key 'foo' needs to be of type 'ARRAY'/
,
" warning recorded ok"
);
}
}
}
{
my
$tmpl
= {
foo
=> {
required
=> 1 }
};
{
my
$rv
= check(
$tmpl
, {
foo
=> 42 } );
ok(
$rv
,
"check() call with required key"
);
is(
$rv
->{foo}, 42,
" found provided value in rv"
);
}
{
my
$rv
= check(
$tmpl
, { } );
ok( !
$rv
,
"check() call with required key omitted"
);
like( last_error,
qr/^Required option 'foo' is not provided/
,
" warning recorded ok"
);
}
}
{
my
@list
= (
[ {
defined
=> 1,
default
=> 1 }, 0 ],
[ {
default
=> 1 }, 1 ],
);
for
my
$aref
(
@list
) {
my
$tmpl
= {
foo
=>
$aref
->[0] };
local
$Params::Check::ONLY_ALLOW_DEFINED
=
$aref
->[1];
{
my
$rv
= check(
$tmpl
, {
foo
=> 42 } );
ok(
$rv
,
"check() call with defined key"
);
is(
$rv
->{foo}, 42,
" found provided value in rv"
);
}
{
my
$rv
= check(
$tmpl
, {
foo
=>
undef
} );
ok( !
$rv
,
"check() call with defined key undefined"
);
like( last_error,
qr/^Key 'foo' must be defined when passed/
,
" warning recorded ok"
);
}
}
}
{
for
my
$thing
(1,
'foo'
,[1]) {
my
$tmpl
= {
foo
=> {
allow
=>
sub
{ is_deeply(+
shift
,
$thing
,
" Allow coderef gets proper args"
) }
}
};
my
$rv
= check(
$tmpl
, {
foo
=>
$thing
} );
ok(
$rv
,
"check() call using allow key"
);
}
}
{
my
$tmpl
= {
foo
=> {
allow
=>
sub
{ 0 } } };
for
my
$val
( 1,
'foo'
, [],
bless
({},__PACKAGE__) ) {
my
$rv
= check(
$tmpl
, {
foo
=>
$val
} );
my
$text
=
"Key 'foo' ($val) is of invalid type"
;
my
$re
=
quotemeta
$text
;
ok(!
$rv
,
"check() fails with unallowed value"
);
like(last_error(),
qr/$re/
,
" $text"
);
}
}
{
local
$Params::Check::WARNINGS_FATAL
= 1;
eval
{ check() };
ok( $@,
"Call dies with fatal toggled"
);
like( $@,
qr/expects two arguments/
,
" error stored ok"
);
}
{
my
$tmpl
= {
foo
=> {
allow
=>
sub
{ 0 } } };
local
$Params::Check::WARNINGS_FATAL
= 1;
eval
{ check(
$tmpl
, {
foo
=> 1 } ) };
ok( $@,
"Call dies with fatal toggled"
);
like( $@,
qr/invalid type/
,
" error stored ok"
);
}
{
local
$SIG
{__WARN__} =
sub
{};
my
$tmpl
= {
foo
=> {
store
=>
''
} };
check(
$tmpl
, {} );
my
$re
=
quotemeta
q|Store variable for 'foo' is not a reference!|
;
like(last_error(),
qr/$re/
,
"Caught non-reference 'store' variable"
);
}
{
my
$tmpl
= {
foo
=> {
default
=>
''
} };
my
$rv
= check(
$tmpl
, {} );
ok(
$rv
,
"check() call with default = ''"
);
ok(
exists
$rv
->{foo},
" rv exists"
);
ok(
defined
$rv
->{foo},
" rv defined"
);
ok( !
$rv
->{foo},
" rv false"
);
is(
$rv
->{foo},
''
,
" rv = '' "
);
}
{
my
$lastname
;
my
$tmpl
= {
firstname
=> {
required
=> 1,
defined
=> 1 },
lastname
=> {
required
=> 1,
store
=> \
$lastname
},
gender
=> {
required
=> 1,
allow
=> [
qr/M/
i,
qr/F/
i],
},
married
=> {
allow
=> [0,1] },
age
=> {
default
=> 21,
allow
=>
qr/^\d+$/
,
},
id_list
=> {
default
=> [],
strict_type
=> 1
},
phone
=> {
allow
=>
sub
{ 1
if
+
shift
} },
bureau
=> {
default
=>
'NSA'
,
no_override
=> 1
},
};
my
$try
= {
firstname
=>
'joe'
,
lastname
=>
'jackson'
,
gender
=>
'M'
,
married
=> 1,
age
=> 21,
id_list
=> [1..3],
phone
=>
'555-8844'
,
};
my
$get
= {
%$try
,
bureau
=>
'NSA'
};
my
$rv
= check(
$tmpl
,
$try
);
ok(
$rv
,
"elaborate check() call"
);
is_deeply(
$rv
,
$get
,
" found provided values in rv"
);
is(
$rv
->{lastname},
$lastname
,
" found provided values in rv"
);
}
{
sub
wrapper { check (
@_
) };
sub
inner { wrapper(
@_
) };
sub
outer { inner (
@_
) };
outer( {
dummy
=> {
required
=> 1 }}, {} );
like( last_error,
qr/for .*::wrapper by .*::inner$/
,
"wrong caller without CALLER_DEPTH"
);
local
$Params::Check::CALLER_DEPTH
= 1;
outer( {
dummy
=> {
required
=> 1 }}, {} );
like( last_error,
qr/for .*::inner by .*::outer$/
,
"right caller with CALLER_DEPTH"
);
}
{ ok( 1,
"Test last_error() on recursive check() call"
);
my
$clear
=
sub
{ check( {}, {} )
if
shift
; 1; };
for
my
$recurse
( 0, 1 ) {
check(
{
a
=> {
defined
=> 1 },
b
=> {
allow
=>
sub
{
$clear
->(
$recurse
) } },
},
{
a
=>
undef
,
b
=>
undef
}
);
ok( last_error(),
" last_error() with recurse: $recurse"
);
}
}