#!/usr/bin/perl
use strict;
use warnings;
use Test::More tests => 48;
use Test::Exception;
BEGIN {
use_ok('Array::Iterator::BiDirectional')
};
my @control = (1 .. 5);
can_ok("Array::Iterator::BiDirectional", 'new');
my $iterator = Array::Iterator::BiDirectional->new(@control);
isa_ok($iterator, 'Array::Iterator::BiDirectional');
isa_ok($iterator, 'Array::Iterator');
# check out public methods
can_ok($iterator, 'hasPrevious');
can_ok($iterator, 'has_previous');
can_ok($iterator, 'previous');
can_ok($iterator, 'lookBack');
can_ok($iterator, 'look_back');
can_ok($iterator, 'getPrevious');
can_ok($iterator, 'get_previous');
# now check the behavior
# move our counter to the end
$iterator->next() while $iterator->hasNext();
for (my $i = $#control; $i > 0; $i--) {
# we should still have another one
ok($iterator->hasPrevious(), '... we have some previous items');
# and out iterator peek should match our control + 1
unless (($i - 1) <= 0) {
cmp_ok($iterator->lookBack(), '==', $control[$i - 1],
'... our control should match our iterator->lookBack');
}
else {
ok(!defined($iterator->lookBack()), '... this should return undef now');
}
# and out iterator should match our control
cmp_ok($iterator->previous(), '==', $control[$i],
'... our control should match our iterator->previous');
}
# we should have no more
ok(!$iterator->hasPrevious(), '... we should have no more');
# now use an array ref in the constructor
# and try using it in this style loop
my $iterator2 = Array::Iterator::BiDirectional->new(\@control);
isa_ok($iterator2, 'Array::Iterator::BiDirectional');
isa_ok($iterator2, 'Array::Iterator');
# move our iterator to the end
$iterator2->next() while $iterator2->hasNext();
for (my $i = $iterator2; $i->hasPrevious(); $i->getPrevious()) {
cmp_ok($i->current(), '==', $control[$i->currentIndex()], '... these should be equal');
}
ok(!defined($iterator2->getPrevious()), '... this should return undef');
throws_ok {
$iterator2->previous();
} qr/Out Of Bounds \: no more elements/, '... this should die if i try again';
my $iterator3 = Array::Iterator::BiDirectional->new(@control);
# when not iterated()
ok(!$iterator3->has_previous(1), '... should be the same as has_previous()');
ok(!$iterator3->has_previous(2), '... should not have 2nd previous element');
ok(!$iterator3->has_previous(3), '... should not have 3rd previous element');
ok(!defined($iterator3->look_back(1)), '... should be the same as look_back()');
ok(!defined($iterator3->look_back(2)), '... look_back() outside of the bounds should return undef');
ok(!defined($iterator3->look_back(5)), '... look_back() outside of the bounds should return undef');
$iterator3->next while $iterator3->has_next;
# when iterated()
ok($iterator3->has_previous(1), '... should be the same as has_previous() after iterating');
ok($iterator3->has_previous(2), '... should have 2nd previous element');
cmp_ok($iterator3->look_back(1), '==', $iterator3->look_back, '... should be the same as look_back() after iterating');
cmp_ok($iterator3->look_back(2), '==', 3, '... should get 2nd previous element after iterating');
cmp_ok($iterator3->look_back(3), '==', 2, '... should get 3rd previous element after iterating');
ok(!defined($iterator3->look_back(6)), '... look_back() outside of the bounds should return undef after iterating');
# check arbitrary lookup edge cases
throws_ok {
$iterator3->has_previous(0)
} qr/\Qhas_previous(0) doesn't make sense/, '... should not be able to call has_previous() with zero argument';
throws_ok {
$iterator3->has_previous(-1)
} qr/\Qhas_previous() with negative argument doesn't make sense/, '... should not be able to call has_previous() with negative argument';
throws_ok {
$iterator3->look_back(0)
} qr/\Qlook_back(0) doesn't make sense/, '... should not be able to call look_back() with zero argument';
throws_ok {
$iterator3->look_back(-1)
} qr/\Qlook_back() with negative argument doesn't make sense/, '... should not be able to call look_back() with negative argument';