# $Id: BonDigi.pm 16 2008-01-13 14:22:02Z Cosimo $ package Test::Games::BonDigi; use strict; use warnings; use base qw(Test::Class); use Test::More; use Games::BonDigi; our $VERSION = '0.02'; sub iterator_default : Test(114) { my $obj = Games::BonDigi->new(); isa_ok($obj, 'Games::BonDigi', 'class constructor'); can_ok($obj, 'sequence'); my $iter = $obj->sequence(); ok(ref $iter eq 'CODE', 'Iterator with object'); my $iter2 = Games::BonDigi->sequence(); ok(ref $iter2 eq 'CODE', 'Iterator with class'); my $word = $iter->(); is($iter2->(), $word, 'class/object iterators are equivalent'); # Test iterator fixed part is($word, 'bon', 'Header: first word is "bon"'); is($iter->(), 'digi', 'Header: then "digi"'); is($iter->(), 'bon', 'Header: then "bon" again'); is($iter->(), 'digi', 'Header: then "digi" again'); # Payload is($iter->(), 'bon', 'Payload: "bon"'); is($iter->(), 'bon', 'Payload: "bon" again'); is($iter->(), 'digi', 'Payload: "digi"'); is($iter->(), 'digi', 'Payload: "digi" again'); # Restart is($iter->(), 'bon', 'Restart of sequence: "bon"'); # Sequence must be uninterrupted my $words_re = qr/bon|digi/; for(1 .. 100) { like($iter->(), $words_re, 'next ' . $_ . ' word is correct'); } return; } sub iterator_custom : Test(16) { my $obj = Games::BonDigi->new(); isa_ok($obj, 'Games::BonDigi', 'class constructor'); # Start with 2 repeats, end at 5, words are: x, y my $iter = $obj->sequence(2, 5, qw(x y)); ok(ref $iter eq 'CODE', 'Custom iterator with object'); my $iter2 = Games::BonDigi->sequence(2, 5, qw(x y)); ok(ref $iter2 eq 'CODE', 'Custom iterator with class'); # Iterator sequence must stop at 5 my @seq = (); # Detect infinite loops (broken iterator) eval { local $SIG{ALRM} = sub { die 'Endless loop' }; alarm 5; while(my $word = $iter->()) { push @seq, $word; } alarm 0; }; unlike($@, qr/Endless loop/, 'iterator correctly stops at given endpoint'); # Test iterator fixed part is($seq[0], 'x', 'first word is "x"'); is($seq[1], 'y', 'then "y"'); is($seq[2], 'x', 'then "x" again'); is($seq[3], 'y', 'then "y" again'); # Payload is($seq[4], 'x', 'Payload: "x"'); is($seq[5], 'x', '"x" again'); is($seq[6], 'y', 'Payload: "y"'); is($seq[7], 'y', '"y" again'); # Sanity tests on generated sequence is(scalar(@seq), 4 * 4 + (2 + 3 + 4 + 5) * 2, 'sequence was generated exactly, no less and no more'); is($seq[$#seq], 'y', 'last element must be "y"'); # Same number of 'x' and 'y' must have been generated my $num_x = 0; my $num_y = 0; for(@seq) { if($_ eq 'x') { $num_x++ } elsif($_ eq 'y') { $num_y++ } } is($num_x, $num_y, '"x" elements == "y" elements'); is($num_x + $num_y, scalar(@seq), 'only "x" and "y" have been generated'); return; } 1; __END__ =head1 NAME Test::Games::BonDigi =head1 ABSTRACT Testing class for Games::BonDigi. Uses Test::Class. =head1 SYNOPSIS Don't use that. =head1 DESCRIPTION Testing class for Games::BonDigi. Uses Test::Class framework. =head1 DEDICATION To Q&A Departments in all the planet. =head1 METHODS =over =item C Tests iterator behaviour in default case, when no parameters are passed to the C method. =item C Tests customized iterator behaviour, when you pass your parameters to the C method. Check out C class documentation for the C method. =back =head1 AUTHOR Cosimo Streppone =head1 COPYRIGHT AND LICENSE Copyright (C) 2008 Cosimo Streppone. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. The full text of the licenses can be found in the F and F files included with this module, or in L and L in Perl 5.8.1 or later. =cut