File Coverage

blib/lib/Test/RandomResults.pm
Criterion Covered Total %
statement 31 31 100.0
branch 2 2 100.0
condition 14 21 66.6
subroutine 12 12 100.0
pod 7 7 100.0
total 66 73 90.4


line stmt bran cond sub pod time code
1             package Test::RandomResults;
2              
3 5     5   187280 use warnings;
  5         13  
  5         183  
4 5     5   26 use strict;
  5         9  
  5         178  
5              
6 5     5   24 use base 'Exporter';
  5         13  
  5         1299  
7              
8             our @EXPORT = qw(is_in in_between length_lt length_le length_eq length_ge length_gt);
9              
10             =head1 NAME
11              
12             Test::RandomResults - Test non-deterministic functions
13              
14             =cut
15              
16             our $VERSION = '0.03';
17              
18 5     5   43 use Test::Builder;
  5         9  
  5         20842  
19             my $Test = Test::Builder->new();
20             my $seed = int( 100000 * rand() ); # yes, I know this is stupid :-)
21             srand( $seed );
22             $Test->diag( "(SEED $seed)" );
23              
24             =head1 DESCRIPTION
25              
26             This module aims to provide ways of testing functions that are meant
27             to return results that are random; that is, non-deterministic
28             functions.
29              
30             Some of the tests provided here might be easily achieved with other
31             testing modules. The reason why they're here is that this way users
32             become aware of how to test their non-deterministic functions.
33              
34             =head1 NOTICE
35              
36             This is a work in progress. Comments are welcome.
37              
38             =head1 SYNOPSIS
39              
40             use Test::More plan => $Num_Tests;
41             use Test::RandomResults;
42              
43             is_in( my_function, [ $list, $of, $items ], "result is inside list" );
44              
45             in_between( my_function, sub { $_[0] cmp $_[1] }, 1, 10, "result between 1 and 10");
46              
47             length_lt( my_function, $limit, "length less than $limit");
48              
49             length_le( my_function, $limit, "length less or equal to $limit");
50              
51             length_eq( my_function, $limit, "length equal to $limit");
52              
53             length_ge( my_function, $limit, "length greater of equal to $limit");
54              
55             length_gt( my_function, $limit, "length greater than $limit");
56              
57             =head1 SPECIAL FEATURES
58              
59             Whenever C is invoked, a new seed is generated
60             and outputed as diagnostics. This is done so that you can use it to
61             debug your code, if needed.
62              
63             =head1 FUNCTIONS
64              
65             =head2 is_in
66              
67             Tests if an element belongs to an array.
68              
69             is_in( my_function, [1, 2, 3], 'either 1, 2 or 3');
70              
71             =cut
72              
73             sub is_in ($@;$) {
74 2     2 1 1788 my ($item, $list, $desc) = @_;
75              
76             return (
77 2   66     6 $Test->ok( scalar (grep { $item eq $_ } @$list) , $desc ) ||
78             $Test->diag( " $item is not in (@$list)" )
79             );
80             }
81              
82             =head2 in_between
83              
84             Tests if an element is within two boundaries.
85              
86             The second parameter to this function is what it uses to do the
87             comparisons.
88              
89             To compare strings:
90              
91             in_between( my_function, { $_[0] cmp $_[1] }, "aaa", "zzz",
92             'result is between "aaa" and "zzz"' );
93              
94             To compare numbers:
95              
96             in_between( my_function, { $_[0] <=> $_[1] }, 1, 10, 'result is between 1 and 10' );
97              
98             To compare something else:
99              
100             in_between( my_function, &your_function_here, $lower_boundary, $upper_boundary,
101             'result is between boundaries' );
102              
103             As you can see, the function should use $_[0] and $_[1] to do the comparison.
104             As with <=> and cmp, the function should return 1, 0 or -1 depending on whether
105             the first argument ($_[0]) is greater, equal to, or less than the second one
106             ($_[1]).
107              
108             C swaps the lower and upper limits, if need be (this means
109             that checking whether a value is between 1 and 10 is the same as
110             checking between 10 and 1).
111              
112             =cut
113              
114             sub in_between ($$$$;$) {
115 36     36 1 41251 my ($item, $function, $lower, $upper, $desc) = @_;
116              
117 36 100       102 if ( $function->( $lower, $upper ) > 0 ) {
118 16         92 ($lower, $upper) = ($upper, $lower);
119             }
120              
121             return (
122 36   66     177 $Test->ok( ( $function->($item,$lower) > -1 and
123             $function->($item,$upper) < 1 ) , $desc ) ||
124             $Test->diag( " $item not between $lower and $upper" )
125             );
126             }
127              
128             =head2 length_lt
129              
130             Tests if length is less than a limit.
131              
132             length_lt( my_function, $limit, "length less than $limit");
133              
134             =cut
135              
136             sub length_lt ($$;$) {
137 2     2 1 1964 my ($item, $limit, $desc) = @_;
138              
139             return (
140 2   66     8 $Test->ok( _length('<', $item, $limit), $desc ) ||
141             $Test->diag( " length of $item not less than $limit" )
142             );
143             }
144              
145             =head2 length_le
146              
147             Tests if length is less or equal to a limit.
148              
149             length_le( my_function, $limit, "length less or equal to $limit");
150              
151             =cut
152              
153             sub length_le ($$;$) {
154 3     3 1 3872 my ($item, $limit, $desc) = @_;
155              
156             return (
157 3   66     10 $Test->ok( _length('<=', $item, $limit), $desc ) ||
158             $Test->diag( " length of $item not less than or equal to $limit" )
159             );
160             }
161              
162             =head2 length_eq
163              
164             Tests if length is equal to a limit.
165              
166             length_eq( my_function, $limit, "length equal to $limit");
167              
168             =cut
169              
170             sub length_eq ($$;$) {
171 2     2 1 2613 my ($item, $limit, $desc) = @_;
172              
173             return (
174 2   66     6 $Test->ok( _length('==', $item, $limit), $desc ) ||
175             $Test->diag( " length of $item not equal to $limit" )
176             );
177             }
178              
179             =head2 length_ge
180              
181             Tests if length is greater of equal to a limit.
182              
183             length_ge( my_function, $limit, "length greater of equal to $limit");
184              
185             =cut
186              
187             sub length_ge ($$;$) {
188 3     3 1 3469 my ($item, $limit, $desc) = @_;
189              
190             return (
191 3   66     11 $Test->ok( _length('>=', $item, $limit), $desc ) ||
192             $Test->diag( " length of $item not greater than or equal to $limit" )
193             );
194             }
195              
196             =head2 length_gt
197              
198             Tests if length is greater than a limit.
199              
200             length_gt( my_function, $limit, "length greater than $limit");
201              
202             =cut
203              
204             sub length_gt ($$;$) {
205 2     2 1 2770 my ($item, $limit, $desc) = @_;
206              
207             return (
208 2   66     6 $Test->ok( _length('>', $item, $limit), $desc ) ||
209             $Test->diag( " length of $item not greater than $limit" )
210             );
211             }
212              
213             #
214              
215             sub _length ($$$) {
216 12     12   22 my ($op, $item, $limit) = @_;
217              
218 12         21 my $length = length $item;
219              
220 12         944 return eval "$length $op $limit";
221             }
222              
223             =head1 TO DO
224              
225             * Check if N results of a function are evenly_distributed
226              
227             * Allow the user to choose the seed when invoking C
228              
229             =head1 AUTHOR
230              
231             Jose Castro, C<< >>
232              
233             =head1 BUGS
234              
235             Please report any bugs or feature requests to
236             C, or through the web interface at
237             L. I will be notified, and then you'll automatically
238             be notified of progress on your bug as I make changes.
239              
240             =head1 COPYRIGHT & LICENSE
241              
242             Copyright 2005 Jose Castro, All Rights Reserved.
243              
244             This program is free software; you can redistribute it and/or modify it
245             under the same terms as Perl itself.
246              
247             =cut
248              
249             1; # End of Test::RandomResults