File Coverage

blib/lib/Test/Effects.pm
Criterion Covered Total %
statement 256 320 80.0
branch 88 144 61.1
condition 25 65 38.4
subroutine 38 43 88.3
pod 4 5 80.0
total 411 577 71.2


line stmt bran cond sub pod time code
1             package Test::Effects;
2              
3 22     22   144777 use warnings;
  22         139  
  22         863  
4 22     22   11789 no if $] >= 5.018, 'warnings', "experimental::smartmatch";
  22         269  
  22         106  
5 22     22   1603 use strict;
  22         41  
  22         348  
6 22     22   419 use 5.014;
  22         66  
7              
8             our $VERSION = '0.001005';
9              
10 22     22   10702 use Test::More;
  22         2931816  
  22         162  
11 22     22   15557 use Test::Trap;
  22         814358  
  22         134  
12 22     22   2420 use base 'Test::Builder::Module';
  22         47  
  22         6188  
13              
14             # Export the modules interface (and that of Test::More)...
15             our @EXPORT = (
16             qw( effects_ok ),
17             qw( ONLY VERBOSE TIME ),
18             @Test::More::EXPORT,
19             );
20              
21             our @EXPORT_OK = (
22             @Test::More::Export_OK,
23             );
24              
25             our %EXPORT_TAGS = (
26             'minimal' => [ 'effects_ok' ],
27             'more' => [ 'effects_ok', @Test::More::EXPORT],
28             );
29              
30             # Magic number tells Test::More how many stack levels to go up when reporting errors
31             # (Unfortunately, this depends on the internals of Test::More)
32             # [TODO: Send a patch for Test::More that autoskips a named class when reporting]
33             my $LEVEL_OFFSET = 6;
34             my $LEVEL_OFFSET_NESTED = 2 * $LEVEL_OFFSET + 1;
35              
36              
37             # Adjust tests used in the module to account for nesting...
38             sub _subtest {
39 44     44   119 my ($desc) = @_;
40              
41             # Report problems as being in the appropriate place...
42 44         100 local $Test::Builder::Level = $Test::Builder::Level + $LEVEL_OFFSET;
43              
44 44         189 &subtest(@_);
45             }
46              
47             sub _fail {
48             # Report problems as being in the appropriate place...
49 0     0   0 local $Test::Builder::Level = $Test::Builder::Level + $LEVEL_OFFSET_NESTED;
50              
51 0         0 &fail(@_);
52             }
53              
54 22     22   155 use Scalar::Util 'looks_like_number';
  22         38  
  22         2516  
55              
56 4     4 0 54 sub is_num { Test::Effects->builder->is_num(@_) }
57              
58             sub _is_or_like {
59 186     186   942 my ($got, $expected, $desc) = @_;
60              
61             # Report problems as being in the appropriate place...
62 186         304 local $Test::Builder::Level = $Test::Builder::Level + $LEVEL_OFFSET_NESTED;
63              
64 186         327 given (ref $expected) {
65 186         369 when ('CODE') {
66 22     22   142 no warnings;
  22         42  
  22         4521  
67 0         0 my $ok = \&Test::Builder::ok;
68 0 0   0   0 local *Test::Builder::ok = sub { $_[2] = $desc unless defined $_[2]; $ok->(@_); };
  0         0  
  0         0  
69 0         0 ok($expected->($got, $desc), $desc);
70             }
71 186         283 when ('Regexp') { &like(@_); }
  72         208  
72 114         301 when (looks_like_number($expected)) { &is_num(@_); }
  0         0  
73 114         174 default { &is(@_); }
  114         341  
74             }
75             }
76              
77             sub _is_deeply {
78 5     5   22 my ($got, $expected, $desc) = @_;
79              
80             # Report problems as being in the appropriate place...
81 5         15 local $Test::Builder::Level = $Test::Builder::Level + $LEVEL_OFFSET_NESTED;
82              
83 5         19 given (ref $expected) {
84 5         29 when ('CODE') {
85 22     22   172 no warnings;
  22         52  
  22         3396  
86 0         0 my $ok = \&Test::Builder::ok;
87 0 0   0   0 local *Test::Builder::ok = sub { $_[2] = $desc unless defined $_[2]; $ok->(@_); };
  0         0  
  0         0  
88 0         0 ok($expected->($got, $desc), $desc);
89             }
90 5         12 default { &is_deeply(@_) }
  5         34  
91             }
92             }
93              
94             sub _is_like_or_deeply {
95 9     9   34 my ($got, $expected, $desc) = @_;
96              
97             # Report problems as being in the appropriate place...
98 9         29 local $Test::Builder::Level = $Test::Builder::Level + $LEVEL_OFFSET_NESTED;
99              
100 9         25 given (ref $expected) {
101 9         40 when ('CODE') {
102 22     22   160 no warnings;
  22         45  
  22         4949  
103 4         11 my $ok = \&Test::Builder::ok;
104 4 50   4   26 local *Test::Builder::ok = sub { $_[2] = $desc unless defined $_[2]; $ok->(@_); };
  4         116  
  4         16  
105 4         14 ok($expected->($got, $desc), $desc);
106             }
107 5 0 0     14 when ('Regexp') { my $got_val = ref($got) eq 'ARRAY' && @{$got} == 1
  0         0  
108             ? $got->[0]
109             : $got;
110 0         0 like($got_val, $expected, $desc);
111             }
112 5         14 when (q{}) {
113 5 100       26 if (looks_like_number($expected)) { &is_num(@_) }
  4         19  
114 1         4 else { &is(@_) }
115             }
116 0         0 default { &is_deeply(@_) }
  0         0  
117             }
118             }
119              
120             sub _is_like_or_list {
121 42     42   372 my ($got, $expected, $desc) = @_;
122              
123             # Report problems as being in the appropriate place...
124 42         93 local $Test::Builder::Level = $Test::Builder::Level + $LEVEL_OFFSET_NESTED;
125              
126 42         110 given (ref $expected) {
127 42         147 when ('CODE') {
128 22     22   178 no warnings;
  22         48  
  22         5137  
129 0         0 my $ok = \&Test::Builder::ok;
130 0 0   0   0 local *Test::Builder::ok = sub { $_[2] = $desc unless defined $_[2]; $ok->(@_); };
  0         0  
  0         0  
131 0         0 ok($expected->($got, $desc), $desc);
132             }
133 42 0 0     89 when ('Regexp') { my $got_val = ref($got) eq 'ARRAY' && @{$got} == 1
  0         0  
134             ? $got->[0]
135             : $got;
136 0         0 like($got_val, $expected, $desc);
137             }
138 42         88 when (q{} && looks_like_number($expected)) { &is_num(@_); }
  0         0  
139 42         120 when (q{}) { &is(@_); }
  0         0  
140 42         90 when (q{ARRAY}) {
141 42         102 for my $n (0..$#{$expected}) {
  42         212  
142 22         109 _is_or_like($got->[$n], $expected->[$n], "$desc [warning $n]");
143             }
144             }
145 0         0 default { &is_deeply(@_) }
  0         0  
146             }
147             }
148              
149              
150             # Utility sub: dump values...
151              
152             sub _explain {
153 22     22   12469 use Data::Dumper 'Dumper';
  22         115848  
  22         7798  
154 0     0   0 local $Data::Dumper::Terse = 1;
155 0         0 local $Data::Dumper::Indent = 0;
156 0         0 return Dumper(shift) =~ s/\s+/ /gr
157             =~ s/\s+$//gr;
158             }
159              
160              
161             # Utility subs: build subs that append the right verb, when requested....
162              
163             sub _was_were_sub {
164 88     88   182 my ($desc) = @_;
165              
166             return sub {
167 164     164   344 my (undef, $was_were) = @_;
168              
169 164 100       502 return $desc if !$was_were;
170 71         284 return "$desc was";
171 88         29453 };
172             }
173              
174             sub _was_were_warn_sub {
175             return sub {
176 42     42   153 my ($expected, $was_were) = @_;
177              
178 42   50     88 my $count = eval{ @{$expected} } // 1;
  42         68  
  42         157  
179              
180 42 50       259 return $count == 1 ? 'warning' . ($was_were ? ' was' : q{})
    50          
    100          
181             : 'warnings' . ($was_were ? ' were' : q{});
182             }
183 22     22   178 }
184              
185              
186             # Utility sub: load carp() and croak() only on demand...
187             sub _croak {
188 4 50   4   11 if (eval{ require Carp }) { Carp::croak(@_); }
  4         32  
  4         723  
189 0         0 else { die @_; }
190             }
191              
192              
193             # Module is largely table-driven (from these tables)...
194              
195             my (%TEST_FOR, %NULL_VALUE_FOR, %BAD_NULL_VALUE_FOR, %DESCRIBE);
196              
197             BEGIN {
198 22     22   149 %TEST_FOR = (
199             'stdout' => \&_is_or_like,
200             'stderr' => \&_is_or_like,
201             'warn' => \&_is_like_or_list,
202             'die' => \&_is_or_like,
203             'exit' => \&_is_or_like,
204             );
205              
206 22         109 %NULL_VALUE_FOR = (
207             'stdout' => q{},
208             'stderr' => q{},
209             'warn' => [],
210             'die' => undef,
211             'exit' => undef,
212             );
213              
214 22         70 %BAD_NULL_VALUE_FOR = (
215             'stdout' => undef,
216             'stderr' => undef,
217             'warn' => undef,
218             'die' => q{},
219             'exit' => q{},
220             );
221              
222 22         67 %DESCRIBE = (
223             'stdout' => _was_were_sub( 'output to STDOUT' ),
224             'stderr' => _was_were_sub( 'output to STDERR' ),
225             'warn' => _was_were_warn_sub(),
226             'die' => _was_were_sub( 'exception' ),
227             'exit' => _was_were_sub( 'call to exit()' ),
228             );
229             }
230              
231              
232             # Make a copy of a hash with an appropriate flag added...
233 5     5 1 3275 sub ONLY (+) { return { ONLY => 1, %{shift()} } }
  5         30  
234 18     18 1 3360 sub VERBOSE (+) { return { VERBOSE => 1, %{shift()} } }
  18         138  
235 9     9 1 3284 sub TIME (+) { return { TIME => 1, %{shift()} } }
  9         67  
236              
237             my $MS_THRESHHOLD = 0.1; # seconds (anything less reported in ms)
238              
239             # Test all trapped info, as requested...
240             sub effects_ok (&;+$) {
241 46     46 1 10487 my ($block, $expected, $desc) = @_;
242 46         116 my $expected_ref = ref $expected;
243              
244             # Handle case where hash is missing, but description isn't...
245 46 50 33     214 if (@_ == 2 && !$expected_ref) {
246 0         0 $desc = "$expected";
247 0         0 $expected = undef;
248             }
249              
250             # Expectations are passed in a hash...
251 46   50     133 $expected //= {};
252 46 100       145 if (ref($expected) ne 'HASH') {
253 1   50     10 _croak 'Second argument to effects_ok() must be hash or hash reference, not '
254             . lc(ref($expected) || 'scalar value');
255             }
256              
257             # If there's a timing request, the value has to make sense...
258 45         71 my $timing;
259 45 100       141 if (exists $expected->{'timing'}) {
260 1         2 my $spec = $expected->{'timing'};
261 1   33     10 my $valid_time = ref($spec) =~ m{ \A (?: HASH | ARRAY ) \Z}xms
262             || !ref($spec) && looks_like_number($spec);
263 1 50       2 if (!$valid_time) {
264 1         4 _croak("Invalid timing specification: timing => '$spec'");
265             }
266             }
267              
268             # Get lexical hints...
269 44   100     76 my %lexical_hint = %{ (caller 0)[10] // {} };
  44         458  
270              
271             # Fill in default tests, unless requested not to...
272             my $is_only
273             = exists $expected->{'ONLY'} ? $expected->{'ONLY'}
274 44 100       192 : $lexical_hint{'Test::Effects::ONLY'};
275              
276             # Time the test, if requested
277             my $timed_test
278             = exists $expected->{'TIME'} ? $expected->{'TIME'}
279 44 100       139 : $lexical_hint{'Test::Effects::TIME'};
280              
281 44 100       126 if (!$is_only) {
282 37         64 my $warn = $expected->{'warn'};
283             $expected = {
284             %NULL_VALUE_FOR,
285 17         50 'stderr' => (ref $warn eq 'ARRAY' ? join(q{}, @{$warn}) : $warn),
286 37 100       166 %{$expected},
  37         210  
287             };
288             }
289              
290             # Correct common mispecifications...
291 44         193 for my $option (keys %BAD_NULL_VALUE_FOR) {
292 220 100       370 next if !exists $expected->{$option};
293 206 100       461 if ($expected->{$option} ~~ $BAD_NULL_VALUE_FOR{$option}) {
294 20         44 $expected->{$option} = $NULL_VALUE_FOR{$option};
295             }
296             }
297              
298             # Ensure there's a description...
299 44   33     139 $desc //= sprintf "Testing effects_ok() at %s line %d", (caller)[1,2];
300              
301             # Are we echoing this test???
302             my $is_terse
303             = exists $expected->{'VERBOSE'} ? !$expected->{'VERBOSE'}
304 44 100       148 : !$lexical_hint{'Test::Effects::VERBOSE'};
305              
306             # Show the description...
307 44   66     152 my $preview_desc = !$is_terse || exists $expected->{'timing'};
308 44 100       128 if ($preview_desc) {
309 25         167 note '_' x (3 + length $desc);
310 25 50       12821 note exists $expected->{'timing'}
311             ? "$desc (being timed)..."
312             : "$desc...";
313             }
314              
315             # Redirect test output, so we can retrospectively de-terse on errors...
316 44         13548 my $tests_output;
317 44         169 given (Test::Builder->new()) {
318 44         379 $_->output(\$tests_output);
319 44         8401 $_->failure_output(\$tests_output);
320 44         6769 $_->todo_output(\$tests_output);
321             }
322              
323             # Preview description under terse too, in case of failures...
324 44 100       6539 if (!$preview_desc) {
325 19         129 note '_' x (3 + length $desc);
326 19         8438 note "$desc...";
327             }
328              
329             # Are we WITHOUT any modules in this test???
330 44         7102 my @real_INC = @INC;
331 44         209 local @INC = @INC;
332 44         7324 local %INC = %INC;
333 44 100       423 if (exists $expected->{'WITHOUT'}) {
334 4         10 my $without_list = $expected->{'WITHOUT'};
335              
336             # Normalize list...
337 4 50       14 if (ref $without_list ne 'ARRAY') {
338 4         11 $without_list = [ $without_list ];
339             }
340              
341             # Translate list to filepaths...
342 4         8 for my $module_name ( @{$without_list} ) {
  4         20  
343             # Classify the argument...
344 4         10 my $is_pattern = ref $module_name eq 'Regexp';
345 4         15 my $is_libpath = $module_name =~ m{/};
346              
347             # Modules get translated to paths...
348 4 100 66     23 if (!$is_libpath) {
    100          
349 2 50       14 if (not $module_name =~ s{::}{/}gxms) {
350 0 0       0 diag "WARNING: ambiguous WITHOUT => "
    0          
    0          
351             . ($is_pattern ? "qr{$module_name}" : "'$module_name'")
352             . "\ntreated as module name (not library path)"
353             . "\n(use "
354             . ($is_pattern ? "qr{::$module_name}" : "'::$module_name'")
355             . " or "
356             . ($is_pattern ? "qr{$module_name/}" : "'$module_name/'")
357             . " to silence this warning)";
358             }
359 2 100       13 if (!$is_pattern) {
360 1         4 $module_name .= '.pm';
361             }
362             else {
363 1         17 $module_name = qr{$module_name};
364             }
365             }
366             # Libpaths winnow @INC directly...
367             elsif (!$is_pattern && $is_libpath) {
368 1         6 $module_name =~ s{/\Z}{}xms;
369 1 50       5 if ($module_name =~ m{\A /}x) {
370 0         0 @INC = grep { !m{\A $module_name /? \Z}x } @INC;
  0         0  
371             }
372             else {
373 1         3 @INC = grep { !m{\A (?: [.]/ )? $module_name /? \Z}x } @INC;
  10         54  
374             }
375             }
376             else { # Pattern spec for libpath
377 1         4 @INC = grep { !m{$module_name} } @INC;
  11         31  
378             }
379              
380             # Libpaths then don't need to be checked with @INC...
381 4 100       16 if ($is_libpath) {
382 2         6 $module_name = undef;
383             }
384             }
385              
386             # Put an interceptor sub at the start of @INC...
387             unshift @INC, sub {
388 4     4   56 my ($self, $target) = @_;
389              
390             # If what you're looking for is WITHOUT'd, pretend to fail...
391 4 100 66     37 if ($target ~~ $without_list || "/$target" ~~ $without_list) {
392 2         37 _croak "Can't locate $target in \@INC (\@INC contains: @real_INC)";
393             }
394 2         196 return;
395 4         31 };
396             }
397              
398             # Test in a subtest...
399             my $failed = _subtest $desc => sub {
400             # Find the specified return value (if any)...
401 44     44   40757 my @return_specs = grep /return/, keys %{$expected};
  44         336  
402 44 50       170 if (@return_specs > 1) {
403 0         0 _fail "Ambiguous specification for testing of return value.";
404             diag "ERROR: Found request for " . scalar(@return_specs),
405             " mutually exclusive tests:\n",
406             " {\n",
407 0         0 (map { " '$_' => " . _explain($expected->{$_}) . ",\n" } @return_specs),
  0         0  
408             " }\n",
409             " Call to effects_ok() terminated without testing anything.";
410 0         0 return;
411             }
412              
413             # Infer context, if necessary...
414 44 100       157 if (exists $expected->{'return'}) {
415 1         2 given (ref $expected->{'return'}) {
416 1         3 when ('ARRAY') { $expected->{'list_return'} = delete $expected->{'return'} }
  0         0  
417 1         2 default { $expected->{'scalar_return'} = delete $expected->{'return'} }
  1         3  
418             }
419             }
420              
421             # Call the block and test the return value in the appropriate context...
422             # 1. Explicit void context...
423 44 100       227 if (exists $expected->{'void_return'}) {
    100          
    100          
424 5 50       10 if (defined $expected->{'void_return'}) {
425 0         0 note "WARNING: Meaningless option {void_return => '$expected->{void_return}'} ignored.\n"
426             . " To silence this warning, either remove the option entirely\n"
427             . " or replace it with: {void_return => undef})";
428             }
429 5 50       11 if ($timed_test) {
430 5         15 _time_calls_to($block, $timed_test => $timing);
431             }
432             else {
433 0         0 trap { $block->() };
  0         0  
434             }
435 5         35 pass 'Tested in void context, so ignored return value'
436             }
437             # 2. Explicit scalar context...
438             elsif (exists $expected->{'scalar_return'}) {
439 9         17 my $return_val = do {
440 9 100       51 if ($timed_test) {
441 4         13 _time_calls_to($block, $timed_test => $timing);
442             }
443             else {
444 5         51 trap { $block->() };
  5         7522  
445             }
446             };
447 9         1761 _is_like_or_deeply $return_val, $expected->{'scalar_return'}
448             => 'Scalar context return value was as expected';
449             }
450             # 3. Explicit list context...
451             elsif (exists $expected->{'list_return'}) {
452 5         7 my @return_vals = do {
453 5 50       15 if ($timed_test) {
454 5         16 _time_calls_to($block, $timed_test => $timing);
455             }
456             else {
457 0         0 trap { $block->() };
  0         0  
458             }
459             };
460 5         34 _is_deeply \@return_vals, $expected->{'list_return'}
461             => 'List context return value was as expected';
462             }
463             # 4. Implied void context...
464             else {
465 25 100       141 if ($timed_test) {
466 3         22 _time_calls_to($block, $timed_test => $timing);
467             }
468             else {
469 22         158 trap { $block->() };
  22         32795  
470             }
471 25         3029193 pass 'No return value specified, so tested in void context';
472             }
473              
474             # Test side-effects...
475 44         23667 for my $info (qw< stdout stderr warn die exit>) {
476 220 100       86988 if (exists $expected->{$info}) {
477 22     22   189 no strict 'refs';
  22         55  
  22         13733  
478             my $desc = $expected->{$info} ~~ $NULL_VALUE_FOR{$info}
479             ? 'No ' . $DESCRIBE{$info}->($expected->{$info}) . ' (as expected)'
480 206 100       1132 : ucfirst $DESCRIBE{$info}->($expected->{$info},'was') . ' as expected';
481              
482 206         1016 $TEST_FOR{$info}->($trap->$info, $expected->{$info}, $desc);
483             }
484             }
485              
486             # Do timing, if requested...
487              
488 44 50       14360 if (exists $expected->{'timing'}) {
489              
490             # Work out the parameters...
491 0         0 my $time_spec = $expected->{'timing'};
492 0         0 my $spec_type = ref $time_spec;
493              
494 0 0 0     0 my $min = $spec_type eq 'HASH' ? $time_spec->{'min'} // 0
    0 0        
495             : $spec_type eq 'ARRAY' ? $time_spec->[0] // 0
496             : 0;
497              
498 0         0 state $INF = 0 + 'inf';
499 0 0 0     0 my $max = $spec_type eq 'HASH' ? $time_spec->{'max'} // $INF
    0 0        
500             : $spec_type eq 'ARRAY' ? $time_spec->[-1] // $INF
501             : 0+$time_spec;
502              
503             # Run the test...
504 0         0 my $duration = _time_calls_to($block);
505              
506             # Compute a handy alternate measure of performance...
507 0 0       0 my $speed = $duration ? 1/$duration : 0;
508 0 0       0 $speed = $speed > 1 ? sprintf('(%1.0lf/sec)', $speed)
    0          
509             : $speed > 0 ? sprintf('(%0.4g/sec)', $speed)
510             : '(unmeasurably fast)';
511              
512             # Was the result acceptable???
513 0   0     0 my $in_range = $min <= $duration && $duration <= $max;
514              
515             # Report outcome...
516 0 0       0 ok $in_range => $duration > $MS_THRESHHOLD
517             ? sprintf('Ran in %0.3f sec %s', $duration, $speed)
518             : sprintf('Ran in %dms %s', 1000*$duration, $speed);
519              
520             # Clean up report...
521 0 0       0 if (!$in_range) {
522 0         0 $tests_output =~ s{\N*\n\N*\n\z}{}xms;
523             }
524              
525             # Report any problems (as being in the appropriate place)...
526 0         0 local $Test::Builder::Level = $Test::Builder::Level + $LEVEL_OFFSET_NESTED - 1;
527 0 0       0 if (!$in_range) {
528 0         0 diag sprintf " Expected to run in: $min to $max sec", $min, $max;
529             }
530             }
531              
532 44         469 };
533              
534             # Clean up...
535 44         76519 my $builder = Test::Builder->new;
536 44         451 $builder->reset_outputs;
537              
538             # Report outcomes...
539 44         6203 my $passed = ($builder->summary)[-1];
540             # If passed in terse mode, just print the summary (i.e. last line)...
541 44 100 66     5900 if ( $is_terse && $passed ) {
    50          
542 19         151 $tests_output =~ s{ .* \n (?= .*\n )}{}xms;
543             }
544             # Otherwise print the probems...
545             elsif ( $is_terse ) {
546 0         0 $tests_output =~ s{^ \s*+ (?! not | [#] ) [^\n]* \n}{}gxms;
547             }
548              
549             # Add the timing info, if requested...
550 44 100       156 if ($timed_test) {
551 17         208 $tests_output =~ s{^ ( (?:not|ok) \s \N*) }{$1\t$timing}xms;
552             }
553              
554 44         101 print {$builder->output} $tests_output;
  44         265  
555              
556 44         16252 return $passed;
557             }
558              
559              
560 22 50   22   84 BEGIN { eval{ require Time::HiRes and Time::HiRes->import('time') } }
  22         10438  
561              
562             sub _time_calls_to {
563 17     17   50 my ($block, $time_one_call) = @_;
564              
565 17         30 state $MAX_CPU_TIME = 1;
566 17         31 state $MIN_CREDIBLE_UTILIZATION = 0.1;
567              
568 17         40 my ($cpu_time, $wall_time) = (0,0);
569 17         34 my $count = 0;
570              
571 17         30 my (@start, @end);
572 17         47 my $wantarray = wantarray;
573 17         23 my (@result, $result);
574              
575 17         24 while (1) {
576 17 100 66     109 if ($time_one_call && $wantarray) {
    100 66        
577 5         63 @start = (time, times);
578 5     5   44 @result = trap { $block->() };
  5         6902  
579 5         1254711 @end = (time, times);
580             }
581             elsif ($time_one_call && defined $wantarray) {
582 4         57 @start = (time, times);
583 4     4   36 $result = trap { $block->() };
  4         5642  
584 4         1003918 @end = (time, times);
585             }
586             else {
587 8         109 @start = (time, times);
588 8     8   75 trap { $block->() };
  8         11680  
589 8         3256860 @end = (time, times);
590             }
591              
592 17         110 $wall_time += $end[0] - $start[0];
593 17         145 $cpu_time += $end[$_] - $start[$_] for 1..4;
594              
595 17         47 $count++;
596              
597 17 50 33     221 last if $cpu_time > $MAX_CPU_TIME
      33        
598             || $wall_time > 2 * $MAX_CPU_TIME
599             || $time_one_call;
600             }
601              
602 17   50     113 my $utilization = $cpu_time / ($wall_time||1);
603 17 50 66     95 my $timing = !$cpu_time || $utilization < $MIN_CREDIBLE_UTILIZATION
604             ? $wall_time / $count
605             : $cpu_time / $count;
606              
607 17 50       52 if ($time_one_call) {
608 17 100       55 if ($timing < $MS_THRESHHOLD) {
609 1         5 $_[2] = '[' . int($timing * 1000) . 'ms]';
610             }
611             else {
612 16         300 $_[2] = sprintf '[%0.2lf sec]', $timing;
613             }
614 17 100       101 return $wantarray ? @result : $result;
615             }
616             else {
617 0           return $timing;
618             }
619             }
620              
621              
622             1; # Magic true value required at end of module
623             __END__
624              
625             =head1 NAME
626              
627             Test::Effects - Test all effects at once (return value, I/O, warnings, exceptions, etc.)
628              
629              
630             =head1 VERSION
631              
632             This document describes Test::Effects version 0.001005
633              
634              
635             =head1 SYNOPSIS
636              
637             =for test-synopsis
638             my $expected_scalar_context_return_value;
639             my @expected_list_context_return_values;
640              
641             use Test::Effects;
642              
643             # Test all possible detectable side-effects of some code...
644             effects_ok { your_code_here() }
645             {
646             return => $expected_scalar_context_return_value,
647             warn => qr/match expected warning text/,
648             stdout => '', # i.e. Doesn't print anything.
649             }
650             => 'Description of test';
651              
652              
653             # Test only specifically requested side-effects of some code...
654             effects_ok { your_code_here() }
655             ONLY {
656             return => \@expected_list_context_return_values,
657             stderr => 'Expected output to STDERR',
658             die => undef, # i.e. Doesn't die.
659             exit => undef, # i.e. Doesn't exit either.
660             }
661             => 'Description of test';
662              
663              
664             # Test that some code has no detectable side-effects...
665             effects_ok { your_code_here() };
666              
667              
668             =head1 DESCRIPTION
669              
670             Test::Effects provides a single exported subroutine: C<effects_ok>
671              
672             This sub expects a block of code (or sub ref) as its first argument,
673             followed by an optional hash ref as its second, and an optional string
674             as its third.
675              
676             The first argument specifies some code to be tested. This code is run in
677             void context by default, but may instead be called in either list or
678             scalar context, depending on the test specification provided by the
679             second argument. The block is run within a call to C<Test::Trap::trap()>,
680             so all warnings, exceptions, output, and exit attempts are trapped.
681             The block may contain calls to other Test::Builder-based testing
682             modules; these are handled correctly within the overall test.
683              
684             The second argument is a hash reference, whose entries specify the
685             expected side-effects of executing the block. You specify the name of
686             the side-effect you're interested in as the key, and the "effect" you
687             expected as the value. Side-effects that are not explicitly specified
688             are automatically tested for default behaviour (e.g. no warnings,
689             no exceptions, no output, not call to C<exit()>, etc. If the entire
690             hash is omitted, all possible side-effects are tested for default
691             behaviour (in other words, did the block of code have I<no> side-effects
692             whatsoever?)
693              
694             The third argument is the overall description of the test (i.e. the
695             usual final argument for Perl tests). If omitted, C<effects_ok()>
696             generates a description based on the line number at which it was called.
697              
698              
699             =head1 INTERFACE
700              
701             =head2 C<use Test::Effects;>
702              
703             Loads the module, and exports the C<effects_ok()>, C<VERBOSE()>,
704             C<ONLY()>, and C<TIME()> subroutines (see below). Also exports the
705             standard interface from the Test::More module.
706              
707             =head2 C<< use Test::Effects tests => $N; >>
708              
709             Exactly the same as:
710              
711             use Test::More tests => $N;
712              
713             In fact, S<C<use Test::Effects>> can take all the same arguments as
714             S<C<use Test::More>>.
715              
716              
717             =head2 C<< use Test::Effects import => [':minimal']; >>
718              
719             Only export the C<effects_ok()> subroutine.
720              
721             Do not export C<VERBOSE()>, C<ONLY()>, C<TIME()>,
722             or any of the Test::More interface.
723              
724              
725             =head2 C<< use Test::Effects import => [':more']; >>
726              
727             Only export the C<effects_ok()> subroutine and the Test::More interface
728              
729             Do not export C<VERBOSE()>, C<ONLY()>, or C<TIME()>.
730              
731              
732             =head2 C<< effects_ok {BLOCK} {EFFECTS_HASH} => 'TEST_DESCRIPTION'; >>
733              
734             Test the code in the block, ensuring that the side-effects named by the
735             keys of the hash match the corresponding hash values. Both the hash
736             and the description arguments are optional.
737              
738             The effects that can be specified as key/value pairs
739             in the hash are:
740              
741             =over
742              
743             =item C<< void_return => undef >>
744              
745             Call the block in void context.
746              
747              
748             =item C<< return => $ARRAY_REFERENCE >>
749              
750             =item C<< list_return => $ANY_SCALAR_VALUE >>
751              
752             Call the block in list context. The final value evaluated in the
753             block should (deeply) match the specified array ref or scalar value
754             of the option.
755              
756              
757             =item C<< return => $NON_ARRAYREF >>
758              
759             =item C<< scalar_return => $ANY_SCALAR_VALUE >>
760              
761             Call the block in scalar context. The final value evaluated in block
762             should match the specified scalar value of the option.
763              
764              
765             =item C<< stdout => $STRING >>
766              
767             What the block wrote to C<STDOUT> should be C<eq> to $STRING.
768              
769             =item C<< stdout => $REGEX >>
770              
771             What the block wrote to C<STDOUT> should be match $REGEX.
772              
773             =item C<< stdout => $CODE_REF >>
774              
775             The subroutine specified by the code ref should return true when passed
776             what the block wrote to C<STDOUT>.
777              
778             The subroutine can call nested tests (such as Test::More's C<is>) or
779             Test::Tolerant's C<is_tol>) and these will be correctly handled.
780              
781              
782             =item C<< stderr => $STRING >>
783              
784             =item C<< stderr => $REGEX >>
785              
786             =item C<< stderr => $CODE_REF >>
787              
788             What the block writes to C<STDERR> should "match" the specified value
789             (either C<eq>, or C<=~>, or return true when passed as an argument).
790              
791             Note that, if this option is not specified, but the C<'warn'> option
792             (see below) I<is> specified, then this option defaults to the value of
793             the C<'warn'> option.
794              
795              
796             =item C<< warn => $STRING >>
797              
798             =item C<< warn => $REGEX >>
799              
800             =item C<< warn => $CODE_REF >>
801              
802             =item C<< warn => [ $STRING1, $REGEX2, $CODE_REF3, $ETC ] >>
803              
804             The block should issue the specified number of warnings, and each
805             of these warnings should match the corresponding value specified,
806             in the order specified.
807              
808              
809             =item C<< die => $STRING >>
810              
811             =item C<< die => $REGEX >>
812              
813             =item C<< die => $CODE_REF >>
814              
815             The block should raise an exception, which should match the value
816             specified.
817              
818             Note: when using OO exceptions, use a code ref to test them:
819              
820             die => sub { shift->isa('X::BadData') }
821              
822             You can also use Test::More-ish tests, if you prefer:
823              
824             die => sub { isa_ok(shift, 'X::BadData') }
825              
826              
827             =item C<< exit => $NUMBER >>
828              
829             =item C<< exit => $REGEX >>
830              
831             =item C<< exit => $CODE_REF >>
832              
833             The block should call C<exit()> and the exit code should match the
834             value specified.
835              
836              
837             =item C<< timing => { min => $MIN_SEC, max => $MAX_SEC } >>
838              
839             =item C<< timing => [$MIN_SEC, $MAX_SEC] >>
840              
841             =item C<< timing => $MAX_SEC >>
842              
843             This option performs a separate timing measurment for the block, by
844             running it multiple times over at least 1 cpu-second and averaging the
845             times required for each run (i.e. like the Benchmark module does).
846              
847             When passed a hash reference, the C<'min'> and C<'max'> entries
848             specify the range of allowable timings (in seconds) for the block.
849             For example:
850              
851             # Test our new snooze() function...
852             effects_ok { snooze(1.5, plus_or_minus=>0.2); }
853             {
854             timing => { min => 1.3, max => 1.7 },
855             }
856             => 'snooze() slept about the right amount of time';
857              
858             The default for C<'min'> is zero seconds;
859             the default for C<'max'> is eternity.
860              
861             If you use an array reference instead of a hash reference, the first
862             value in the array is taken as the minimum time, and the final value is
863             taken as the maximum allowed time. Hence the above time specification
864             could also be written:
865              
866             timing => [ 1.3, 1.7 ],
867              
868             But don't write:
869              
870             timing => [ 1.3 .. 1.7 ],
871              
872             (unless your limits are integers),
873             because Perl truncates the bounds of a range,
874             so it treats C<[1.3 .. 1.7]> as C<[1 .. 1]>.
875              
876             If you use a number instead of a reference, then
877             number is taken as the maximum time allowed:
878              
879             timing => 3.2, # Same as: timing => { min => 0, max => 3.2 }
880              
881             If you do not specify either time limit:
882              
883             timing => {},
884              
885             or:
886              
887             timing => [],
888              
889             then the "zero-to-eternity" defaults are used and C<effects_ok()> simply
890             times the block and reports the timing (as a success).
891              
892             Note that the timings measured using this option are considerably more
893             accurate than those produced by the C<< TIME => 1 >> option (see below),
894             but also take significantly longer to measure.
895              
896             =back
897              
898              
899             Other configuration options that can be specified as key/value pairs in
900             the hash are:
901              
902             =over
903              
904             =item C<< VERBOSE => $BOOLEAN >>
905              
906             If the value is true, all side-effect tests are reported individually
907             (running them in a subtest).
908              
909             When this option is false (or omitted) only the overall result, plus any
910             individual failures, are reported.
911              
912              
913             =item C<< ONLY => $BOOLEAN >>
914              
915             If the value is true, only the effects explicitly requested by the other
916             keys of this hash are tested for. In other words, this option causes
917             C<effects_ok()> to omit the "default" tests for unnamed side-effects.
918              
919             When this option is false (or omitted) unspecified options are tested
920             for their expected default behaviour.
921              
922              
923             =item C<< TIME => $BOOLEAN >>
924              
925             If the value is true, the block is timed as it is executed.
926             The timing is reported in the final TAP line.
927              
928             Note that this option is entirely independent of the C<'timing'> option
929             (which times the block repeatedly and then tests it against specified
930             limits).
931              
932             In contrast, the C<'TIME'> option merely times the block once, while it
933             is being evaluated for the other tests. This is much less accurate, but
934             also much faster and much less intrusive, when you merely want an rough
935             indication of performance.
936              
937              
938             =item C<< WITHOUT => 'Module::Name' >>
939              
940             =item C<< WITHOUT => qr/Module::.*/ >>
941              
942             Execute the block as if the specified module (or all modules matching
943             the specified pattern) were not installed.
944              
945              
946             =item C<< WITHOUT => 'lib/path/' >>
947              
948             =item C<< WITHOUT => qr{lib/*} >>
949              
950             Execute the block as if the specified library directory (or all
951             directories matching the specified pattern) were not accessible.
952              
953             The specified patch I<must> include at least one slash (C</>), otherwise
954             it will be interpreted as a module name (see above). You can always add
955             a redundant slash at the end of the path, if necessary:
956              
957             WITHOUT => 'lib', # Test without the C<lib.pm> module
958              
959             WITHOUT => 'lib/', # Test without the C<lib> directory
960              
961             =back
962              
963             =head2 C<< VERBOSE I<$HASH_REF> >>
964              
965             A call to:
966              
967             effects_ok { BLOCK }
968             VERBOSE { return => 0, stdout => 'ok' }
969              
970             is just a shorthand for:
971              
972             effects_ok { BLOCK }
973             { return => 0, stdout => 'ok', VERBOSE => 1 }
974              
975              
976             =head2 C<< ONLY I<$HASH_REF> >>
977              
978             A call such as:
979              
980             effects_ok { BLOCK }
981             ONLY { return => 0, stdout => 'ok' }
982              
983             is just a shorthand for:
984              
985             effects_ok { BLOCK }
986             { return => 0, stdout => 'ok', ONLY => 1 }
987              
988              
989             =head2 C<< TIME I<$HASH_REF> >>
990              
991             A call such as:
992              
993             effects_ok { BLOCK }
994             TIME { return => 0, stdout => 'ok' }
995              
996             is just a shorthand for:
997              
998             effects_ok { BLOCK }
999             { return => 0, stdout => 'ok', TIME => 1 }
1000              
1001             Note that the C<VERBOSE>, C<ONLY>, and C<TIME> subs can be "stacked"
1002             (in any combination and order):
1003              
1004             effects_ok { BLOCK }
1005             TIME ONLY VERBOSE { return => 0, stdout => 'ok' }
1006              
1007             effects_ok { BLOCK }
1008             VERBOSE ONLY { return => 0, stdout => 'ok' }
1009              
1010              
1011             =head2 C<< use Test::Effects::VERBOSE; >>
1012              
1013             This causes every subsequent call to C<effects_ok()>
1014             in the current lexical scope to act as if it had a
1015             S<< C<< VERBOSE => 1 >> >> option set.
1016              
1017             Note, however, that an explicit S<< C<< VERBOSE => 0 >> >> in
1018             any call in the scope overrides this default.
1019              
1020             =head2 C<< no Test::Effects::VERBOSE; >>
1021              
1022             This causes every subsequent call to C<effects_ok()>
1023             in the current lexical scope to act as if it had a
1024             S<< C<< VERBOSE => 0 >> >> option set. Again, however,
1025             an explicit S<< C<< VERBOSE => 1 >> >> in
1026             any call in the scope overrides this default.
1027              
1028              
1029             =head2 C<< use Test::Effects::ONLY; >>
1030              
1031             This causes every subsequent call to C<effects_ok()>
1032             in the current lexical scope to act as if it had a
1033             S<< C<< ONLY => 1 >> >> option set.
1034              
1035             Note, however, that an explicit S<< C<< ONLY => 0 >> >> in
1036             any call in the scope overrides this default.
1037              
1038             =head2 C<< no Test::Effects::ONLY; >>
1039              
1040             This causes every subsequent call to C<effects_ok()>
1041             in the current lexical scope to act as if it had a
1042             S<< C<< ONLY => 0 >> >> option set. Again, however,
1043             an explicit S<< C<< ONLY => 1 >> >> in
1044             any call in the scope overrides this default.
1045              
1046              
1047             =head2 C<< use Test::Effects::TIME; >>
1048              
1049             This causes every subsequent call to C<effects_ok()>
1050             in the current lexical scope to act as if it had a
1051             S<< C<< TIME => 1 >> >> option set.
1052              
1053             Note, however, that an explicit S<< C<< TIME => 0 >> >> in
1054             any call in the scope overrides this default.
1055              
1056             =head2 C<< no Test::Effects::TIME; >>
1057              
1058             This causes every subsequent call to C<effects_ok()>
1059             in the current lexical scope to act as if it had I<no>
1060             S<< C<< TIME => 0 >> >> option set. Again, however,
1061             an explicit S<< C<< TIME => 1 >> >> in
1062             any call in the scope overrides this default.
1063              
1064              
1065             =head1 DIAGNOSTICS
1066              
1067             =over
1068              
1069             =item C<< Second argument to effects_ok() must be hash or hash reference, not %s >>
1070              
1071             C<effects_ok()> expects a hash as its second argument, but you passed
1072             something else. This can happen if you forget to put braces around a
1073             single option, such as:
1074              
1075             effects_ok { test_code() }
1076             warn => qr/Missing arg/;
1077              
1078             That needs to be:
1079              
1080             effects_ok { test_code() }
1081             { warn => qr/Missing arg };
1082              
1083             Or you may have accidentally used an array instead of a hash:
1084              
1085             effects_ok { test_code() }
1086             [ warn => qr/Missing arg ];
1087              
1088             That is not supported, as it is being reserved for a
1089             future feature.
1090              
1091             =item C<< "Invalid timing specification: timing => %s" >>
1092              
1093             The C<'timing'> option expects a hash reference, array reference,
1094             or a single number as its value. You specified some value that
1095             was something else (and which C<effects_ok()> therefore didn't
1096             understand).
1097              
1098             =back
1099              
1100              
1101             =head1 CONFIGURATION AND ENVIRONMENT
1102              
1103             Test::Effects requires no configuration files or environment variables.
1104              
1105              
1106             =head1 DEPENDENCIES
1107              
1108             Requires Perl 5.14 (or better).
1109              
1110             Requires the Test::Trap module, v0.2.1 (or better).
1111              
1112              
1113             =head1 INCOMPATIBILITIES
1114              
1115             None reported.
1116              
1117              
1118             =head1 BUGS AND LIMITATIONS
1119              
1120             Ironically, the test suite for this module is as yet unsatisfactory.
1121             (T.D.D. Barbie says: "Testing test modules is B<I<HARD!>>")
1122              
1123             No other bugs have been reported.
1124              
1125             Please report any bugs or feature requests to
1126             C<bug-test-effects@rt.cpan.org>, or through the web interface at
1127             L<http://rt.cpan.org>.
1128              
1129              
1130             =head1 AUTHOR
1131              
1132             Damian Conway C<< <DCONWAY@CPAN.org> >>
1133              
1134              
1135             =head1 LICENCE AND COPYRIGHT
1136              
1137             Copyright (c) 2012, Damian Conway C<< <DCONWAY@CPAN.org> >>. All rights reserved.
1138              
1139             This module is free software; you can redistribute it and/or
1140             modify it under the same terms as Perl itself. See L<perlartistic>.
1141              
1142              
1143             =head1 DISCLAIMER OF WARRANTY
1144              
1145             BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
1146             FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
1147             OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
1148             PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
1149             EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1150             WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
1151             ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
1152             YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
1153             NECESSARY SERVICING, REPAIR, OR CORRECTION.
1154              
1155             IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
1156             WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
1157             REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE
1158             LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,
1159             OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
1160             THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
1161             RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
1162             FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
1163             SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
1164             SUCH DAMAGES.