#!/usr/bin/perl
BEGIN
{
our
$DEBUG
=
exists
(
$ENV
{AUTHOR_TESTING} ) ?
$ENV
{AUTHOR_TESTING} : 0;
};
BEGIN
{
use_ok(
'Module::Generic::Array'
) || BAIL_OUT(
"Unable to load Module::Generic::Array"
);
use_ok(
'Module::Generic::Scalar'
) || BAIL_OUT(
"Unable to load Module::Generic::Scalar"
);
}
my
$s
= Module::Generic::Scalar->new(
'I disapprove of what you say, but I will defend to the death your right to say it'
);
my
$a
=
$s
->
split
(
qr/[[:blank:]]+/
);
isa_ok(
$a
,
'Module::Generic::Array'
);
is(
$a
->
length
, 18,
'length'
);
my
$h
= \
%$a
;
isa_ok(
$h
,
'Module::Generic::Hash'
);
is( CORE::
exists
(
$a
->{disapprove} ), 1,
'array to hash'
);
is(
"@$a"
,
'I disapprove of what you say, but I will defend to the death your right to say it'
,
'array as string'
);
no
warnings
'Module::Generic::Array'
;
is(
$a
->
delete
(
'not-integer'
),
$a
,
'delete with non-integer offset'
);
my
$a2
=
$a
->clone;
is(
$a2
->
delete
( 2 )->as_string,
'of'
,
'delete with offset'
);
is(
"@$a2"
,
'I disapprove what you say, but I will defend to the death your right to say it'
,
'array after delete'
);
$a2
->
delete
( 2, 3 );
is(
"@$a2"
,
'I disapprove but I will defend to the death your right to say it'
,
'delete with offset and length'
);
$a2
->
delete
( 3,
$a2
->
length
);
is(
"@$a2"
,
'I disapprove but'
,
'delete till the end'
);
$a
->
each
(
sub
{
my
(
$i
,
$v
) =
@_
;
return
( 1 )
unless
(
$i
== 9 );
is(
$v
,
'defend'
,
'each'
);
return
( 0 );
});
ok(
$a
->
exists
(
'defend'
),
'exists with bare word'
);
ok(
$a
->
exists
(
qr/DefEnd/
i ),
'exists with regular expression'
);
ok( !
$a
->
exists
(
'DefEnd'
),
'not exist'
);
my
$res
=
$a
->
exists
(
qr/you/
);
isa_ok(
$res
,
'Module::Generic::Number'
,
'Result object class'
);
$a
->
for
(
sub
{
my
(
$i
,
$v
) =
@_
;
return
( 1 )
unless
(
$i
== 14 );
is(
$v
,
'right'
,
'for'
);
return
( 0 );
});
my
$word
=
$a2
->first;
ok( !
ref
(
$word
),
'first in void context returns a simple string'
);
is(
$word
,
'I'
);
my
$word_obj
=
$a2
->first->clone;
isa_ok(
$word_obj
,
'Module::Generic::Scalar'
,
'first in object context returns a Module::Generic::Scalar object'
);
$res
=
''
;
$a
->
foreach
(
sub
{
my
(
$v
) =
@_
;
$res
.=
$v
;
});
my
$s_no_sp
=
$s
->clone;
$s_no_sp
->replace(
qr/[[:blank:]]+/
,
''
);
is(
$res
,
$s_no_sp
,
'foreach'
);
is(
$a
->get(14),
'right'
,
'get'
);
$word_obj
=
$a
->get(14)->clone;
isa_ok(
$word_obj
,
'Module::Generic::Scalar'
,
'get in object context'
);
is(
$word_obj
,
'right'
,
'get returned value'
);
$res
=
$a
->
grep
(
'say'
);
isa_ok(
$res
,
'Module::Generic::Array'
,
'grep'
);
is(
$res
->
length
, 2,
'grep result total'
);
$res
=
$a
->
grep
(
qr/^you[r]?$/
);
is(
$res
->
length
, 2,
'gre with regexp'
);
is( (
$a
->list)[14],
'right'
,
'list'
);
$res
=
$a
->
grep
(
sub
{
$_
[0] =~ /(of|to|the)/i;
});
is(
"@$res"
,
'of to the to'
,
'grep using code'
);
ok(
$a
->
has
(
'say'
),
'has'
);
is(
$a
->
index
(14),
'right'
,
'index'
);
$word_obj
=
$a
->
index
(14)->clone;
isa_ok(
$word_obj
,
'Module::Generic::Scalar'
,
'index in object context'
);
is(
$word_obj
,
'right'
,
'index returned value'
);
my
$join
=
$a2
->
join
(
','
);
isa_ok(
$join
,
'Module::Generic::Scalar'
,
'join produces scalar object'
);
is(
$join
,
'I,disapprove,but'
,
'join'
);
isa_ok(
$a
->
keys
,
'Module::Generic::Array'
,
'keys to array object class'
);
is(
$a
->
keys
->
length
, 18,
'length'
);
ok(
$a
->
keys
->
length
==
$a
->
length
,
'length (bis)'
);
$word
=
$a2
->
last
;
ok( !
ref
(
$word
),
'last in void context returns a simple string'
);
is(
$word
,
'but'
);
$word_obj
=
$a2
->
last
->clone;
isa_ok(
$word_obj
,
'Module::Generic::Scalar'
,
'last in object context returns a Module::Generic::Scalar object'
);
is(
$word_obj
,
'but'
);
my
$map
=
$a
->
map
(
sub
{
return
(
length
(
$_
[0] ) <= 3 ?
$_
[0] : () );
});
is(
"@$map"
,
'I of you but I to the to say it'
,
'map'
);
my
$a_temp
= Module::Generic::Array->new( [
qw( Trying local variable )
] );
my
$map2
=
$a_temp
->
map
(
sub
{
return
(
"_${_}_"
);
})->
join
(
'-'
);
is(
$map2
,
'_Trying_-_local_-_variable_'
,
'map with local variable'
);
my
@list
=
$a
->
map
(
sub
{
return
(
length
(
$_
[0] ) <= 3 ?
$_
[0] : () );
});
is(
join
(
','
,
@list
),
'I,of,you,but,I,to,the,to,say,it'
,
'map as list'
);
is(
$map
->
pop
,
'it'
,
'pop'
);
my
$a_pop
= Module::Generic::Array->new( [
qw( hello world )
] );
$word
=
$a_pop
->
pop
->clone;
isa_ok(
$word
,
'Module::Generic::Scalar'
,
'pop in object context'
);
is(
$word
,
'world'
,
'pop value in object context'
);
is(
$map
->
push
(
qw( again and again )
)->
length
, 12,
'push'
);
is(
$a2
->clone->push_arrayref(
$map
)->
length
, 15,
'push_arrayref'
);
is(
$a2
->clone->
reset
->
length
, 0,
'reset'
);
is(
$a2
->
reverse
->as_string,
'but disapprove I'
,
'reverse'
);
$a2
->set( [
qw( this has been set )
] );
is(
"@$a2"
,
'this has been set'
,
'set'
);
is(
$a2
->
shift
,
'this'
,
'shift'
);
$a_pop
= Module::Generic::Array->new( [
qw( hello world )
] );
$word
=
$a_pop
->
shift
->clone;
isa_ok(
$word
,
'Module::Generic::Scalar'
,
'shift in object context'
);
is(
$word
,
'hello'
,
'shift value in object context'
);
is(
$a2
->size, 2,
'size'
);
ok(
$a2
->
length
->is_positive,
'Accessing number object method'
);
is(
$a
->
sort
->as_string,
'I I but death defend disapprove it of right say say, the to to what will you your'
,
'sort'
);
is(
$a
->
sort
(
sub
{
$_
[1] cmp
$_
[0];
})->as_string,
'your you will what to to the say, say right of it disapprove defend death but I I'
,
'sort with code'
);
is(
$a2
->clone->
splice
->
length
, 0,
'splice with no argument remove everything'
);
is(
$a2
->
unshift
(
'This'
)->as_string,
'This has been set'
,
'unshift'
);
is(
$a2
->
splice
( 1, 1,
qw( should have )
)->as_string,
'This should have been set'
,
'splice with replacement'
);
my
$a_splice
= Module::Generic::Array->new( [CORE::
split
( /[[:blank:]]+/,
$s
)] );
my
$splice_ret
=
$a_splice
->
splice
( 7, 3 )->clone;
isa_ok(
$splice_ret
,
'Module::Generic::Array'
,
'splice in object context'
);
is(
"@$splice_ret"
,
'I will defend'
,
'splice returned value in object context'
);
$a_splice
= Module::Generic::Array->new( [CORE::
split
( /[[:blank:]]+/,
$s
)] );
$splice_ret
=
$a_splice
->
splice
( 7 )->clone;
isa_ok(
$splice_ret
,
'Module::Generic::Array'
,
'splice in object context'
);
is(
"@$splice_ret"
,
'I will defend to the death your right to say it'
,
'splice returned value in object context'
);
my
$ar_split
= Module::Generic::Array->new->
split
(
qr/[[:blank:]\h]+/
,
"I disapprove of what you say, but I will defend to the death your right to say it"
);
isa_ok(
$ar_split
,
'Module::Generic::Array'
,
'split returns an Module::Generic::Array'
);
is(
$ar_split
->
length
, 18,
'split array size'
);
my
@split_words
= Module::Generic::Array->
split
(
qr/[[:blank:]\h]+/
,
"I disapprove of what you say, but I will defend to the death your right to say it"
);
is(
scalar
(
@split_words
), 18,
'split array size in list context'
);
is(
$a2
->clone->
undef
->
length
, 0,
'undef'
);
is(
$a2
->
values
->as_string,
'This should have been set'
,
'values'
);
my
$array1
= [
qw( John Paul )
];
my
$array2
= Module::Generic::Array->new;
my
$array3
= Module::Generic::Array->new;
@$array2
=
@$array1
;
isa_ok(
$array2
,
'Module::Generic::Array'
,
'Array keeps class'
);
is(
$array2
->
join
(
' '
),
'John Paul'
,
'Assigned array'
);
$array3
=
$array2
;
my
$a3
= Module::Generic::Array->new( [
qw( Jack John Peter Gabriel Raphael Emmanuel )
] );
is(
$a3
->offset( 2, 3 )->
join
(
' '
)->
scalar
,
'Peter Gabriel Raphael'
,
'offset'
);
is(
$a3
->offset( 2, -3 )->
join
(
' '
)->
scalar
,
'Emmanuel Jack John Peter'
,
'offset'
);
is(
$a3
->offset( 2, -1 )->
join
(
' '
)->
scalar
,
'John Peter'
,
'offset'
);
is(
$a3
->offset( -2, 3 )->
join
(
' '
)->
scalar
,
'Raphael Emmanuel Jack'
,
'offset'
);
is(
$a3
->offset( 3 )->
join
(
' '
)->
scalar
,
'Gabriel Raphael Emmanuel'
,
'offset'
);
my
$a4
= Module::Generic::Array->new( [
qw( Jack John Peter )
] );
my
$a5
= Module::Generic::Array->new( [
qw( Gabriel Raphael Emmanuel )
] );
$a4
->merge(
$a5
);
is(
$a4
->
join
(
' '
)->
scalar
,
'Jack John Peter Gabriel Raphael Emmanuel'
,
'merge'
);
ok(
"@$a4"
,
'Jack John Peter Gabriel Raphael Emmanuel'
);
$a4
->
for
(
sub
{
my
(
$i
,
$v
) =
@_
;
if
(
$v
eq
'Peter'
)
{
$a4
->
splice
(
$i
, 1 );
}
return
( 1 );
});
is(
"@$a4"
,
'Jack John Gabriel Raphael Emmanuel'
,
'for changing offset position'
);
my
$a6
= Module::Generic::Array->new( [
qw( Jack John Peter Peter Gabriel Raphael Emmanuel )
] );
$a6
->
for
(
sub
{
my
(
$i
,
$v
) =
@_
;
if
(
$v
eq
'Peter'
)
{
$a6
->
splice
(
$i
, 1 );
return
( \-1 );
}
return
( 1 );
});
is(
"@$a6"
,
'Jack John Gabriel Raphael Emmanuel'
,
'for changing offset position'
);
my
$a7
= Module::Generic::Array->new( [
qw( Jack John Peter Gabriel Raphael Peter Emmanuel )
] );
$a7
->
for
(
sub
{
my
(
$i
,
$v
) =
@_
;
if
(
$v
eq
'Peter'
)
{
$a7
->
splice
(
$i
, 1 );
}
return
(1);
});
is(
"@$a7"
,
'Jack John Gabriel Raphael Emmanuel'
,
'for changing offset position'
);
my
$a8
= Module::Generic::Array->new( [ 1..10 ] );
my
$a9
= Module::Generic::Array->new( [ 21..30 ] );
my
$pos
;
$a8
->
for
(
sub
{
my
(
$i
,
$n
) =
@_
;
$pos
=
$n
;
$a9
->
for
(
sub
{
my
(
$j
,
$v
) =
@_
;
$a8
->break
if
(
$n
== 7 &&
$v
== 27 );
});
});
is(
$pos
, 7,
'return undef'
);
is(
scalar
(
keys
(
%$Module::Generic::Array::RETURN
) ), 0,
'return registry cleanup'
);
my
$a10
= Module::Generic::Array->new( [
qw( Jack John Peter Paul Gabriel Raphael Emmanuel )
] );
my
$a11
= Module::Generic::Array->new;
$a10
->
for
(
sub
{
my
(
$i
,
$n
) =
@_
;
$a11
->
push
(
$n
);
$a10
->
return
(+1)
if
(
$n
eq
'John'
);
return
(1);
});
is(
"@$a11"
,
'Jack John Paul Gabriel Raphael Emmanuel'
,
'return skip 1'
);
$a11
->
reset
;
$pos
= 0;
$a8
->
for
(
sub
{
my
(
$i
,
$n
) =
@_
;
$pos
=
$n
;
$a9
->
for
(
sub
{
my
(
$j
,
$v
) =
@_
;
$a10
->break
if
(
$n
== 7 &&
$v
== 27 );
});
});
is(
$pos
, 10,
'ineffective return'
);
$a10
->
for
(
sub
{
my
(
$i
,
$n
) =
@_
;
$a11
->
push
(
$n
);
$_
[0]++
if
(
$n
eq
'John'
);
return
(1);
});
is(
"@$a11"
,
'Jack John Paul Gabriel Raphael Emmanuel'
,
'modying $i directly'
);
my
$dummy
= {
class
=>
'Coucou'
};
my
$a12
= Module::Generic::Array->new( [
'Jack'
,
'John'
,
$dummy
,
'Paul'
,
'Peter'
,
'Gabriel'
,
$dummy
,
'Peter'
,
'Raphael'
,
'Emmanuel'
] );
my
$res12
=
$a12
->unique;
my
$expect12
= Module::Generic::Array->new( [
'Jack'
,
'John'
,
$dummy
,
'Paul'
,
'Peter'
,
'Gabriel'
,
'Raphael'
,
'Emmanuel'
] );
ok(
$res12
eq
$expect12
,
'unique'
);
$a12
->unique(1);
ok(
$a12
eq
$expect12
,
'unique in-place'
);
$a12
->remove(
$dummy
,
qw( John Paul Peter Emmanuel )
);
is(
"@$a12"
,
'Jack Gabriel Raphael'
,
'remove'
);
my
$a13
= Module::Generic::Array->new( [
qw( 1 2 3 4 5 6 7 8 9 10 )
] );
my
$even
=
$a13
->even;
is(
"@$even"
,
'1 3 5 7 9'
,
'even'
);
my
$odd
=
$a13
->odd;
is(
"@$odd"
,
'2 4 6 8 10'
,
'odd'
);
my
$a14
= Module::Generic::Array->new( [
qw( Jack John Paul Peter )
] );
my
$j
= JSON->new->convert_blessed;
eval
{
my
$json
=
$j
->encode(
$a14
);
is(
$json
,
'["Jack","John","Paul","Peter"]'
,
'TO_JSON'
);
};
if
( $@ )
{
fail(
'TO_JSON'
);
}
my
$cardinals
= [
qw( first second third fourth fifth sixth seventh eighth ninth tenth )
];
for
( 0..
$#$cardinals
)
{
my
$method
=
$cardinals
->[
$_
];
is(
$a13
->
$method
, (
$_
+ 1),
$cardinals
->[
$_
] );
}
my
$val
=
$a14
->get_null(1);
is(
$val
,
'John'
,
'get_null(1) in scalar context'
);
$val
=
$a14
->get_null(1)->
length
;
is(
$val
, 4,
'get_null(1) in object context'
);
$val
=
$a14
->get_null(4);
ok( !
defined
(
$val
),
'get_null(4) out of bound returns undef'
);
$val
=
$a14
->get_null(4)->dummy;
is(
$val
=>
''
,
'get_null(4)->dummy (using Module::Generic::Null) out of bound returns empty string'
);
$a
= Module::Generic::Array->new( 30..39 );
is(
$a
->
length
, 10,
'array allocation for pack'
);
$s
=
$a
->
pack
(
'H2'
x 10 );
isa_ok(
$s
,
'Module::Generic::Scalar'
,
'pack returns a Module::Generic::Scalar object'
);
is(
$s
->
scalar
,
'0123456789'
,
'pack'
);
my
$intersec1
= [
qw( Jack John Paul Peter )
];
my
$intersec2
= [
qw( Emmanuel Gabriel Raphael Peter Michel )
];
my
$intersec
= Module::Generic::Array->new(
$intersec1
)->intersection(
$intersec2
);
isa_ok(
$intersec
,
'Module::Generic::Array'
,
'intersection returns an Module::Generic::Array object'
);
is_deeply(
$intersec
, [
qw( Peter )
],
'intersection'
);
is(
$intersec
->
length
, 1,
'intersection size'
);
is(
$intersec
->first,
'Peter'
,
'intersection value'
);
$intersec
= Module::Generic::Array->new(
$intersec1
)->intersection( Module::Generic::Array->new(
$intersec2
) );
is_deeply(
$intersec
, [
qw( Peter )
],
'intersection using array objects'
);
my
$values
= Module::Generic::Array->new( [
qw( 9 5 12 3 7 )
] );
my
$max
=
$values
->max;
isa_ok(
$max
,
'Module::Generic::Scalar'
,
'max return a Module::Generic::Scalar object'
);
is(
"$max"
, 12,
'max'
);
my
$max_list
= Module::Generic::Array->new;
my
$max_val
=
$max_list
->max;
ok( !
$max_val
->
defined
,
'max on empty list returns undef as an object'
);
my
$min
=
$values
->min;
is(
"$min"
, 3,
'min'
);
my
$ex1
= Module::Generic::Array->new( [
qw( Jack John Paul Peter )
] );
my
$other
= Module::Generic::Array->new( [
qw( Emmanuel Gabriel Paul Peter Raphael )
] );
my
$ex2
=
$ex1
->except(
$other
);
is(
"@$ex2"
,
"Jack John"
);
my
$a2h
= Module::Generic::Array->new( [
qw( Jack John Peter Gabriel Raphael Emmanuel )
] );
my
$hashified
=
$a2h
->as_hash;
isa_ok(
$hashified
=>
'Module::Generic::Hash'
);
is_deeply(
$hashified
=> {
Jack
=> 0,
John
=> 1,
Peter
=> 2,
Gabriel
=> 3,
Raphael
=> 4,
Emmanuel
=> 5 },
'as_hash'
);
subtest
'callback'
=>
sub
{
$Module::Generic::Array::DEBUG
=
$DEBUG
;
diag(
"Setting \$Module::Generic::Array::DEBUG to '$Module::Generic::Array::DEBUG'"
)
if
(
$DEBUG
);
my
$test
= Module::Generic::Array->new(
qw( John Peter Paul )
);
is(
$test
->
length
, 3,
'init'
);
ok( !
tied
(
@$test
),
'not tied'
);
$test
->callback(
add
=>
sub
{
my
$this
=
shift
(
@_
);
my
(
$pos
,
$ref
) =
@$this
{
qw( start added )
};
diag(
"Adding "
,
scalar
(
@$ref
),
" element ('"
,
join
(
"', '"
,
@$ref
),
"') at offset $pos"
)
if
(
$DEBUG
);
is(
$pos
, 3,
'push'
);
return
(1);
});
$test
->
push
(
'Gabriel'
);
diag(
"Elements are: '"
,
$test
->
join
(
"', '"
),
"'"
)
if
(
$DEBUG
);
is(
$test
->
last
,
'Gabriel'
,
'push (2)'
);
$test
->callback(
add
=>
sub
{
my
$this
=
shift
(
@_
);
my
(
$pos
,
$ref
) =
@$this
{
qw( start added )
};
diag(
"Adding "
,
scalar
(
@$ref
),
" element ('"
,
join
(
"', '"
,
@$ref
),
"') at offset $pos"
)
if
(
$DEBUG
);
is(
$pos
, 0,
'unshift'
);
return
(1);
});
$test
->
unshift
(
'Emmanuel'
);
is(
$test
->first,
'Emmanuel'
,
'unshift (2)'
);
$test
->callback(
add
=>
sub
{
my
$this
=
shift
(
@_
);
my
(
$pos
,
$ref
) =
@$this
{
qw( start added )
};
diag(
"Adding "
,
scalar
(
@$ref
),
" element ('"
,
join
(
"', '"
,
@$ref
),
"') at offset $pos"
)
if
(
$DEBUG
);
is(
$pos
, 2,
'splice'
);
return
(1);
});
$test
->
splice
( 2, 0,
'Raphael'
);
is(
$test
->
index
(2),
'Raphael'
,
'splice (2)'
);
diag(
"Now do removing tests"
)
if
(
$DEBUG
);
diag(
"Elements are: '"
,
$test
->
join
(
"', '"
),
"'"
)
if
(
$DEBUG
);
$test
->callback(
remove
=>
sub
{
my
$this
=
shift
(
@_
);
my
(
$from
,
$to
) =
@$this
{
qw( start end )
};
diag(
"Removing data from position $from to $to: '"
,
$test
->offset(
$from
, (
$to
-
$from
) )->
join
(
"', '"
),
"'"
)
if
(
$DEBUG
);
is(
$from
, 5,
'pop'
);
is(
$to
, 5,
'pop (1)'
);
return
(1);
});
my
$removed
=
$test
->
pop
;
is(
$removed
,
'Gabriel'
,
'pop (2)'
);
$test
->callback(
remove
=>
sub
{
my
$this
=
shift
(
@_
);
my
(
$from
,
$to
) =
@$this
{
qw( start end )
};
diag(
"Removing data from position $from to $to: '"
,
$test
->offset(
$from
, (
$to
-
$from
) )->
join
(
"', '"
),
"'"
)
if
(
$DEBUG
);
is(
$from
, 0,
'shift (start position)'
);
is(
$to
, 0,
'shift (end position)'
);
return
(1);
});
$removed
=
$test
->
shift
;
is(
$removed
,
'Emmanuel'
,
'shift (2)'
);
$test
->callback(
remove
=>
sub
{
my
$this
=
shift
(
@_
);
my
(
$from
,
$to
) =
@$this
{
qw( start end )
};
diag(
"Removing data from position $from to $to: '"
,
$test
->offset(
$from
, (
$to
-
$from
) )->
join
(
"', '"
),
"'"
)
if
(
$DEBUG
);
is(
$from
, 1,
'splice (start position)'
);
is(
$to
, 2,
'splice (end position)'
);
is(
join
(
' '
,
@$test
[ 1, 2 ] ),
'Raphael Peter'
,
'splice (1)'
);
return
(1);
});
my
@removed
=
$test
->
splice
( 1, 2 );
is(
scalar
(
@removed
), 2,
'splice (2)'
);
is(
"@removed"
,
'Raphael Peter'
,
'splice (3)'
);
diag(
"Elements are: '"
,
$test
->
join
(
"', '"
),
"'"
)
if
(
$DEBUG
);
$test
->callback(
remove
=>
sub
{
my
$this
=
shift
(
@_
);
my
(
$from
,
$to
) =
@$this
{
qw( start end )
};
my
$caller
= [
caller
];
diag(
"Removing data from position $from to $to: '"
,
$test
->offset(
$from
, (
$to
-
$from
) )->
join
(
"', '"
),
"' called from package "
,
$caller
->[0],
" at line "
,
$caller
->[2] )
if
(
$DEBUG
);
is(
$from
, 1,
'delete (start position)'
);
is(
$to
, 1,
'delete (end position)'
);
return
(1);
});
$removed
=
delete
(
$test
->[1] );
is(
$removed
,
'Paul'
,
'delete (2)'
);
diag(
"No check blocking addition."
)
if
(
$DEBUG
);
diag(
"Elements are: '"
,
$test
->
join
(
"', '"
),
"'"
)
if
(
$DEBUG
);
$test
->callback(
add
=>
sub
{
my
$this
=
shift
(
@_
);
my
(
$pos
,
$ref
) =
@$this
{
qw( start added )
};
diag(
"Attempting to add "
,
scalar
(
@$ref
),
" element ('"
,
join
(
"', '"
,
@$ref
),
"') at offset $pos"
)
if
(
$DEBUG
);
is(
$pos
, 1,
'push'
);
return
;
});
$test
->
push
(
qw( Madeleine Isabelle Gabrielle )
);
is(
$test
->
length
, 1,
'push rejected'
);
$test
->callback(
add
=>
sub
{
my
$this
=
shift
(
@_
);
my
(
$pos
,
$ref
) =
@$this
{
qw( start added )
};
diag(
"Attempting to add "
,
scalar
(
@$ref
),
" element ('"
,
join
(
"', '"
,
@$ref
),
"') at offset $pos"
)
if
(
$DEBUG
);
is(
$pos
, 0,
'unshift'
);
return
;
});
$test
->
unshift
(
qw( Madeleine )
);
is(
$test
->
length
, 1,
'unshift rejected'
);
diag(
"Elements are: '"
,
$test
->
join
(
"', '"
),
"'"
)
if
(
$DEBUG
);
$test
->callback(
add
=>
sub
{
my
$this
=
shift
(
@_
);
my
(
$pos
,
$ref
) =
@$this
{
qw( start added )
};
diag(
"Attempting to add "
,
scalar
(
@$ref
),
" element ('"
,
join
(
"', '"
,
@$ref
),
"') at offset $pos"
)
if
(
$DEBUG
);
is(
$pos
, 2,
'direct insertion'
);
return
;
});
$test
->[2] =
'Samuel'
;
is(
$test
->
length
, 1,
'direct insertion rejected'
);
$test
->callback(
add
=>
sub
{
my
$this
=
shift
(
@_
);
my
(
$pos
,
$ref
) =
@$this
{
qw( start added )
};
diag(
"Attempting to add "
,
scalar
(
@$ref
),
" element ('"
,
join
(
"', '"
,
@$ref
),
"') at offset $pos"
)
if
(
$DEBUG
);
is(
$pos
, 2,
'splice insertion rejected'
);
return
;
});
$test
->
splice
( 2, 0,
qw( Marie Madeleine )
);
is(
$test
->
length
, 1,
'splice insertion rejected (2)'
);
diag(
"Elements are: '"
,
$test
->
join
(
"', '"
),
"'"
)
if
(
$DEBUG
);
$test
->callback(
remove
=>
sub
{
my
$this
=
shift
(
@_
);
my
(
$from
,
$to
) =
@$this
{
qw( start end )
};
my
$caller
= [
caller
];
diag(
"Removing data from position $from to $to: '"
,
$test
->offset(
$from
, (
$to
-
$from
) )->
join
(
"', '"
),
"' called from package "
,
$caller
->[0],
" at line "
,
$caller
->[2] )
if
(
$DEBUG
);
is(
$from
, 0,
'shift rejected (start position)'
);
is(
$to
, 0,
'shift rejected (end position)'
);
return
;
});
$removed
=
$test
->
shift
;
is(
$removed
,
undef
,
'shift rejected'
);
is(
$test
->
length
, 1,
'shift rejected'
);
$test
->callback(
add
=>
undef
);
$test
->
push
(
qw( Madeleine Isabelle Gabrielle )
);
is(
$test
->
length
, 4,
'remove callback'
);
diag(
"Elements are: '"
,
$test
->
join
(
"', '"
),
"'"
)
if
(
$DEBUG
);
$test
->callback(
remove
=>
sub
{
my
$this
=
shift
(
@_
);
my
(
$from
,
$to
) =
@$this
{
qw( start end )
};
my
$caller
= [
caller
];
diag(
"Removing data from position $from to $to: '"
,
$test
->offset(
$from
, (
$to
-
$from
) )->
join
(
"', '"
),
"' called from package "
,
$caller
->[0],
" at line "
,
$caller
->[2] )
if
(
$DEBUG
);
is(
$from
, 3,
'shift rejected (start position)'
);
is(
$to
, 3,
'shift rejected (end position)'
);
return
;
});
$removed
=
$test
->
pop
;
is(
$removed
,
undef
,
'pop rejected'
);
is(
$test
->
length
, 4,
'pop rejected'
);
$test
->callback(
remove
=>
sub
{
my
$this
=
shift
(
@_
);
my
(
$from
,
$to
) =
@$this
{
qw( start end )
};
my
$caller
= [
caller
];
diag(
"Removing data from position $from to $to: '"
,
$test
->offset(
$from
, (
$to
-
$from
) )->
join
(
"', '"
),
"' called from package "
,
$caller
->[0],
" at line "
,
$caller
->[2] )
if
(
$DEBUG
);
is(
$from
, 2,
'direct removal rejected (start position)'
);
is(
$to
, 2,
'direct removal rejected (end position)'
);
return
;
});
$removed
=
delete
(
$test
->[2] );
is(
$removed
,
undef
,
'direct removal'
);
is(
$test
->
length
, 4,
'direct removal'
);
$test
->callback(
remove
=>
sub
{
my
$this
=
shift
(
@_
);
my
(
$from
,
$to
) =
@$this
{
qw( start end )
};
my
$caller
= [
caller
];
diag(
"Removing data from position $from to $to: '"
,
$test
->offset(
$from
, (
$to
-
$from
) )->
join
(
"', '"
),
"' called from package "
,
$caller
->[0],
" at line "
,
$caller
->[2] )
if
(
$DEBUG
);
is(
$from
, 1,
'splice removal rejected (start position)'
);
is(
$to
, 2,
'splice removal rejected (end position)'
);
return
;
});
@removed
=
$test
->
splice
( 1, 2 );
is(
scalar
(
@removed
), 0,
'splice removed rejected'
);
diag(
"Removing callbacks"
)
if
(
$DEBUG
);
$test
->callback(
add
=>
undef
);
$test
->callback(
remove
=>
undef
);
ok( !
tied
(
@$test
),
'callbacks removed'
);
};
subtest
'filter'
=>
sub
{
my
$a
= Module::Generic::Array->new( [
qw( John Jack Peter Gabriel Samuel )
] );
my
$n
= -1;
my
$new
=
$a
->filter(
sub
{
is(
$_
[0],
$a
->[ ++
$n
],
"value at index $n"
);
is(
$n
,
$_
[1],
"value at index $n"
);
is(
ref
(
$_
[2] ),
ref
(
$a
),
'array object'
);
substr
(
$_
, 0, 1 ) ne
'J'
;
});
is(
$new
->
length
, 3 );
is(
"@$new"
,
'Peter Gabriel Samuel'
);
$n
= -1;
$new
=
$a
->filter(
sub
{
isa_ok(
$_
[0],
'Module::Generic::Array'
,
"'this' additional value pass"
);
is(
$_
[1],
$a
->[ ++
$n
],
"value at index $n"
);
is(
$n
,
$_
[2],
"value at index $n"
);
is(
ref
(
$_
[3] ),
ref
(
$a
),
'array object'
);
substr
(
$_
, 0, 1 ) ne
'J'
;
},
$a
);
};
done_testing();