The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

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.