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 [[0,'a'],[1,'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.