NAME
Test::Proto::Role::ArrayRef - Role containing test case methods for array refs.
SYNOPSIS
package MyProtoClass;
use Moo;
with 'Test::Proto::Role::ArrayRef';
This Moo Role provides methods to Test::Proto::ArrayRef for test case methods that apply to arrayrefs such as map
. It can also be used for objects which use overload or otherwise respond to arrayref syntax.
METHODS
map
pArray->map(sub { uc shift }, ['A','B'])->ok(['a','b']);
Applies the first argument (a coderef) onto each member of the array. The resulting array is compared to the second argument.
grep
pArray->grep(sub { $_[0] eq uc $_[0] }, ['A'])->ok(['A','b']); # passes
pArray->grep(sub { $_[0] eq uc $_[0] }, [])->ok(['a','b']); # passes
pArray->grep(sub { $_[0] eq uc $_[0] })->ok(['a','b']); # fails - 'boolean' grep behaves like array_any
Applies the first argument (a prototype) onto each member of the array; if it returns true, the member is added to the resulting array. The resulting array is compared to the second argument.
array_any
pArray->array_any(sub { $_[0] eq uc $_[0] })->ok(['A','b']); # passes
pArray->array_any(sub { $_[0] eq uc $_[0] })->ok(['a','b']); # fails
Applies the first argument (a prototype) onto each member of the array; if any member returns true, the test case succeeds.
array_none
pArray->array_none(sub { $_[0] eq uc $_[0] })->ok(['a','b']); # passes
pArray->array_none(sub { $_[0] eq uc $_[0] })->ok(['A','b']); # fails
Applies the first argument (a prototype) onto each member of the array; if any member returns true, the test case fails.
array_all
pArray->array_all(sub { $_[0] eq uc $_[0] })->ok(['A','B']); # passes
pArray->array_all(sub { $_[0] eq uc $_[0] })->ok(['A','b']); # fails
Applies the first argument (a prototype) onto each member of the array; if any member returns false, the test case fails.
reduce
pArray->reduce(sub { $_[0] + $_[1] }, 6 )->ok([1,2,3]);
Applies the first argument (a coderef) onto the first two elements of the array, and thereafter the next element and the return value of the previous calculation. Similar to List::Util::reduce.
nth
pArray->nth(1,'b')->ok(['a','b']);
Finds the nth item (where n is the first argument) and compares the result to the prototype provided in the second argument.
count_items
pArray->count_items(2)->ok(['a','b']);
Finds the length of the array (i.e. the number of items) and compares the result to the prototype provided in the argument.
enumerated
pArray->enumerated($tests_enumerated)->ok(['a','b']);
Produces the indices and values of the subject as an array reference, and tests them against the prototype provided in the argument.
In the above example, the prototype $tests_enumerated
should return a pass for [[1,'a'],[2,'b']]
.
in_groups
pArray->in_groups(2,[['a','b'],['c','d'],['e']])->ok(['a','b','c','d','e']);
Bundles the contents in groups of n (where n is the first argument), puts each group in an arrayref, and compares the resulting arrayref to the prototype provided in the second argument.
group_when
pArray->group_when(sub {$_[eq uc $_[0]}, [['A'],['B','c','d'],['E']])->ok(['A','B','c','d','E']);
pArray->group_when(sub {$_[0] eq $_[0]}, [['a','b','c','d','e']])->ok(['a','b','c','d','e']);
Bundles the contents of the test subject in groups; a new group is created when the member matches the first argument (a prototype). The resulting arrayref is compared to the second argument.
group_when_index
pArray->group_when_index(p(0)|p(1)|p(4), [['A'],['B','c','d'],['E']])->ok(['A','B','c','d','E']);
pArray->group_when_index(p->num_gt(2), [['a','b','c','d','e']])->ok(['a','b','c','d','e']);
Bundles the contents of the test subject in groups; a new group is created when the index matches the first argument (a prototype). The resulting arrayref is compared to the second argument.
indexes_of
pArray->indexes_of('a', [0,2])->ok(['a','b','a']);
Finds the indexes which match the first argument, and compares that list as an arrayref with the second list.
array_eq
pArray->array_eq(['a','b'])->ok(['a','b']);
Compares the elements of the test subject with the elements of the first argument, using the upgrade
feature.
range
pArray->range('1,3..4',[9,7,6,5])->ok([10..1]);
Finds the range specified in the first element, and compares them to the second element.
reverse
pArray->reverse([10..1])->ok([1..10]);
Reverses the order of elements and compares the result to the prototype given.
array_before
pArray->array_before('b',['a'])->ok(['a','b']); # passes
Applies the first argument (a prototype) onto each member of the array; if any member returns true, the second argument is validated against a new arrayref containing all the preceding members of the array.
array_before_inclusive
pArray->array_before_inclusive('b',['a', 'b'])->ok(['a','b', 'c']); # passes
Applies the first argument (a prototype) onto each member of the array; if any member returns true, the second argument is validated against a new arrayref containing all the preceding members of the array, plus the element matched.
array_after
pArray->array_after('a',['b'])->ok(['a','b']); # passes
Applies the first argument (a prototype) onto each member of the array; if any member returns true, the second argument is validated against a new arrayref containing all the following members of the array.
array_after_inclusive
pArray->array_after_inclusive('b',['b','c'])->ok(['a','b','c']); # passes
Applies the first argument (a prototype) onto each member of the array; if any member returns true, the second argument is validated against a new arrayref containing the element matched, plus all the following members of the array.
sorted
pArray->sorted(['a','c','e'])->ok(['a','e','c']); # passes
pArray->sorted([2,10,11], cNumeric)->ok([11,2,10]); # passes
This will sort the subject and compare the result against the protoype.
ascending
pArray->ascending->ok(['a','c','e']); # passes
pArray->ascending->ok(['a','c','c','e']); # passes
pArray->ascending(cNumeric)->ok([2,10,11]); # passes
This will return true if the elements are already in ascending order. Elements which compare as equal as the previous element are permitted.
descending
pArray->descending->ok(['e','c','a']); # passes
pArray->descending->ok(['e','c','c','a']); # passes
pArray->descending(cNumeric)->ok([11,10,2]); # passes
This will return true if the elements are already in descending order. Elements which compare as equal as the previous element are permitted.
array_max
pArray->array_max('e')->ok(['a','e','c']); # passes
pArray->array_max(p->num_gt(10), cNumeric)->ok(['2','11','10']); # passes
This will find the maximum value using the optional comparator in the second argument, and check it against the first argument.
array_min
pArray->array_min('a')->ok(['a','e','c']); # passes
pArray->array_min(p->num_lt(10), cNumeric)->ok(['2','11','10']); # passes
This will find the minimum value using the optional comparator in the second argument, and check it against the first argument.
array_index_of_max
pArray->array_index_of_max(1)->ok(['a','e','c']); # passes
pArray->array_index_of_max(1, cNumeric)->ok(['2','11','10']); # passes
This will find the index of the maximum value using the optional comparator in the second argument, and check it against the first argument.
array_index_of_min
pArray->array_index_of_min(0)->ok(['a','e','c']); # passes
pArray->array_index_of_min(0, cNumeric)->ok(['2','11','10']); # passes
This will find the index of the minimum value using the optional comparator in the second argument, and check it against the first argument.
array_all_unique
pArray->array_all_unique->ok(['a','b','c']); # passes
pArray->array_all_unique(cNumeric)->ok(['0','0e0','0.0']); # fails
This will pass if all of the members of the array are unique, using the comparison provided (or cmp).
array_all_same
pArray->array_all_same->ok(['a','a']); # passes
pArray->array_all_same(cNumeric)->ok(['0','0e0','0.0']); # passes
pArray->array_all_same->ok(['0','0e0','0.0']); # fails
This will pass if all of the members of the array are the same, using the comparison provided (or cmp).
Unordered Comparisons
These methods are useful for when you know what the array should contain but do not know what order the elements are in, for example when testing the keys of a hash.
The principle is similar to the set
and bag
tests documented List::Util, but does not use the same implementation and does not suffer from the known bug documented there.
set_of
pArray->set_of(['a','b','c'])->ok(['a','c','a','b']); # passes
Checks that all of the elements in the test subject match at least one element in the first argument, and vice versa. Members of the test subject may be 'reused'.
bag_of
pArray->bag_of(['a','b','c'])->ok(['c','a','b']); # passes
Checks that all of the elements in the test subject match at least one element in the first argument, and vice versa. Members may not be 'reused'.
subset_of
pArray->subset_of(['a','b','c'])->ok(['a','a','b']); # passes
Checks that all of the elements in the test subject match at least one element in the first argument. Members of the test subject may be 'reused'.
superset_of
pArray->superset_of(['a','b','a'])->ok(['a','b','c']); # passes
Checks that all of the elements in the first argument can validate at least one element in the test subject. Members of the test subject may be 'reused'.
subbag_of
pArray->subbag_of(['a','b','c'])->ok(['a','b']); # passes
Checks that all of the elements in the test subject match at least one element in the first argument. Members of the test subject may not be 'reused'.
superbag_of
pArray->superbag_of(['a','b'])->ok(['a','b','c']); # passes
Checks that all of the elements in the first argument can validate at least one element in the test subject. Members of the test subject may not be 'reused'.
Series Validation
Sometimes you need to check an array matches a certain complex 'pattern' including multiple units of variable length, like in a regular expression or an XML DTD or Schema. Using Test::Proto::Series, Test::Proto::Repeatable, and Test::Proto::Alternation, you can describe these units, and the methods below can be used to iterate over such a structure.
contains_only
pArray->contains_only(pSeries(pRepeatable(pAlternation('a', 'b'))->max(5)))->ok(['a','a','a']); # passes
This passes if the series expected matches exactly the test subject, i.e. the series can legally stop at the point where the subject ends.
begins_with
pArray->begins_with(pSeries('a','a',pRepeatable('a')->max(2)))->ok(['a','a','a']); # passes
This passes if the full value of the series expected matches the test subject with some elements of the test subject optionally left over at the end.
ends_with
pArray->ends_with(pSeries('b','c')->ok(['a','b','c']); # passes
This passes if the full value of the series expected matches the final items of the test subject with some elements of the test subject optionally preceding.