line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# $Id: BonDigi.pm 16 2008-01-13 14:22:02Z Cosimo $
|
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
package Test::Games::BonDigi;
|
4
|
|
|
|
|
|
|
|
5
|
2
|
|
|
2
|
|
4538
|
use strict;
|
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
68
|
|
6
|
2
|
|
|
2
|
|
17
|
use warnings;
|
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
62
|
|
7
|
2
|
|
|
2
|
|
10
|
use base qw(Test::Class);
|
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
2465
|
|
8
|
2
|
|
|
2
|
|
60074
|
use Test::More;
|
|
2
|
|
|
|
|
7674
|
|
|
2
|
|
|
|
|
21
|
|
9
|
2
|
|
|
2
|
|
1200
|
use Games::BonDigi;
|
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
876
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
our $VERSION = '0.02';
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
sub iterator_default : Test(114)
|
14
|
|
|
|
|
|
|
{
|
15
|
|
|
|
|
|
|
|
16
|
1
|
|
|
1
|
1
|
218
|
my $obj = Games::BonDigi->new();
|
17
|
1
|
|
|
|
|
5
|
isa_ok($obj, 'Games::BonDigi', 'class constructor');
|
18
|
|
|
|
|
|
|
|
19
|
1
|
|
|
|
|
446
|
can_ok($obj, 'sequence');
|
20
|
1
|
|
|
|
|
485
|
my $iter = $obj->sequence();
|
21
|
1
|
|
|
|
|
5
|
ok(ref $iter eq 'CODE', 'Iterator with object');
|
22
|
|
|
|
|
|
|
|
23
|
1
|
|
|
|
|
388
|
my $iter2 = Games::BonDigi->sequence();
|
24
|
1
|
|
|
|
|
6
|
ok(ref $iter2 eq 'CODE', 'Iterator with class');
|
25
|
|
|
|
|
|
|
|
26
|
1
|
|
|
|
|
381
|
my $word = $iter->();
|
27
|
1
|
|
|
|
|
4
|
is($iter2->(), $word, 'class/object iterators are equivalent');
|
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
# Test iterator fixed part
|
30
|
1
|
|
|
|
|
507
|
is($word, 'bon', 'Header: first word is "bon"');
|
31
|
1
|
|
|
|
|
442
|
is($iter->(), 'digi', 'Header: then "digi"');
|
32
|
1
|
|
|
|
|
469
|
is($iter->(), 'bon', 'Header: then "bon" again');
|
33
|
1
|
|
|
|
|
450
|
is($iter->(), 'digi', 'Header: then "digi" again');
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# Payload
|
36
|
1
|
|
|
|
|
405
|
is($iter->(), 'bon', 'Payload: "bon"');
|
37
|
1
|
|
|
|
|
383
|
is($iter->(), 'bon', 'Payload: "bon" again');
|
38
|
1
|
|
|
|
|
383
|
is($iter->(), 'digi', 'Payload: "digi"');
|
39
|
1
|
|
|
|
|
405
|
is($iter->(), 'digi', 'Payload: "digi" again');
|
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
# Restart
|
42
|
1
|
|
|
|
|
423
|
is($iter->(), 'bon', 'Restart of sequence: "bon"');
|
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
# Sequence must be uninterrupted
|
45
|
1
|
|
|
|
|
406
|
my $words_re = qr/bon|digi/;
|
46
|
1
|
|
|
|
|
4
|
for(1 .. 100)
|
47
|
|
|
|
|
|
|
{
|
48
|
100
|
|
|
|
|
40915
|
like($iter->(), $words_re, 'next ' . $_ . ' word is correct');
|
49
|
|
|
|
|
|
|
}
|
50
|
|
|
|
|
|
|
|
51
|
1
|
|
|
|
|
412
|
return;
|
52
|
2
|
|
|
2
|
|
13
|
}
|
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
20
|
|
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub iterator_custom : Test(16)
|
55
|
|
|
|
|
|
|
{
|
56
|
1
|
|
|
1
|
1
|
1910
|
my $obj = Games::BonDigi->new();
|
57
|
1
|
|
|
|
|
6
|
isa_ok($obj, 'Games::BonDigi', 'class constructor');
|
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
# Start with 2 repeats, end at 5, words are: x, y
|
60
|
1
|
|
|
|
|
737
|
my $iter = $obj->sequence(2, 5, qw(x y));
|
61
|
1
|
|
|
|
|
6
|
ok(ref $iter eq 'CODE', 'Custom iterator with object');
|
62
|
|
|
|
|
|
|
|
63
|
1
|
|
|
|
|
411
|
my $iter2 = Games::BonDigi->sequence(2, 5, qw(x y));
|
64
|
1
|
|
|
|
|
5
|
ok(ref $iter2 eq 'CODE', 'Custom iterator with class');
|
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
# Iterator sequence must stop at 5
|
67
|
1
|
|
|
|
|
379
|
my @seq = ();
|
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
# Detect infinite loops (broken iterator)
|
70
|
|
|
|
|
|
|
eval
|
71
|
1
|
|
|
|
|
2
|
{
|
72
|
1
|
|
|
0
|
|
33
|
local $SIG{ALRM} = sub { die 'Endless loop' };
|
|
0
|
|
|
|
|
0
|
|
73
|
1
|
|
|
|
|
15
|
alarm 5;
|
74
|
1
|
|
|
|
|
4
|
while(my $word = $iter->())
|
75
|
|
|
|
|
|
|
{
|
76
|
44
|
|
|
|
|
110
|
push @seq, $word;
|
77
|
|
|
|
|
|
|
}
|
78
|
1
|
|
|
|
|
14
|
alarm 0;
|
79
|
|
|
|
|
|
|
};
|
80
|
|
|
|
|
|
|
|
81
|
1
|
|
|
|
|
9
|
unlike($@, qr/Endless loop/, 'iterator correctly stops at given endpoint');
|
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
# Test iterator fixed part
|
84
|
1
|
|
|
|
|
403
|
is($seq[0], 'x', 'first word is "x"');
|
85
|
1
|
|
|
|
|
393
|
is($seq[1], 'y', 'then "y"');
|
86
|
1
|
|
|
|
|
428
|
is($seq[2], 'x', 'then "x" again');
|
87
|
1
|
|
|
|
|
402
|
is($seq[3], 'y', 'then "y" again');
|
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
# Payload
|
90
|
1
|
|
|
|
|
419
|
is($seq[4], 'x', 'Payload: "x"');
|
91
|
1
|
|
|
|
|
437
|
is($seq[5], 'x', '"x" again');
|
92
|
1
|
|
|
|
|
432
|
is($seq[6], 'y', 'Payload: "y"');
|
93
|
1
|
|
|
|
|
437
|
is($seq[7], 'y', '"y" again');
|
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
# Sanity tests on generated sequence
|
96
|
1
|
|
|
|
|
439
|
is(scalar(@seq), 4 * 4 + (2 + 3 + 4 + 5) * 2, 'sequence was generated exactly, no less and no more');
|
97
|
1
|
|
|
|
|
419
|
is($seq[$#seq], 'y', 'last element must be "y"');
|
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
# Same number of 'x' and 'y' must have been generated
|
100
|
1
|
|
|
|
|
427
|
my $num_x = 0;
|
101
|
1
|
|
|
|
|
3
|
my $num_y = 0;
|
102
|
|
|
|
|
|
|
|
103
|
1
|
|
|
|
|
3
|
for(@seq)
|
104
|
|
|
|
|
|
|
{
|
105
|
44
|
100
|
|
|
|
79
|
if($_ eq 'x') { $num_x++ }
|
|
22
|
50
|
|
|
|
26
|
|
106
|
22
|
|
|
|
|
27
|
elsif($_ eq 'y') { $num_y++ }
|
107
|
|
|
|
|
|
|
}
|
108
|
|
|
|
|
|
|
|
109
|
1
|
|
|
|
|
4
|
is($num_x, $num_y, '"x" elements == "y" elements');
|
110
|
1
|
|
|
|
|
449
|
is($num_x + $num_y, scalar(@seq), 'only "x" and "y" have been generated');
|
111
|
|
|
|
|
|
|
|
112
|
1
|
|
|
|
|
420
|
return;
|
113
|
2
|
|
|
2
|
|
1550
|
}
|
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
12
|
|
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
1;
|
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
__END__
|