File Coverage

blib/lib/Test/Exception/LessClever.pm
Criterion Covered Total %
statement 50 51 98.0
branch 17 18 94.4
condition 2 2 100.0
subroutine 10 10 100.0
pod 5 5 100.0
total 84 86 97.6


line stmt bran cond sub pod time code
1             package Test::Exception::LessClever;
2 1     1   53455 use strict;
  1         1  
  1         27  
3 1     1   3 use warnings;
  1         2  
  1         24  
4              
5 1     1   4 use base 'Exporter';
  1         5  
  1         73  
6 1     1   740 use Test::Builder;
  1         2  
  1         25  
7 1     1   3 use Carp qw/carp/;
  1         1  
  1         559  
8              
9             #{{{ POD
10              
11             =head1 NAME
12              
13             Test::Exception::LessClever - (DEPRECATED) Test::Exception simplified
14              
15             =head1 DEPRECATION NOTICE
16              
17             *** This module is deprecated: please do not use it! ***
18              
19             An alternative to L that is much simpler. This alternative
20             does not use fancy stack tricks to hide itself. The idea here is to keep it
21             simple. This also solves the Test::Exception bug where some dies will be hidden
22             when a DESTROY method calls eval. If a DESTROY method masks $@ a warning will
23             be generated as well.
24              
25             =head1 WHY REWRITE TEST-EXCEPTION
26              
27             Here is an IRC log.
28              
29             wtf? Bizarre copy of HASH in sassign at /usr/lib64/perl5/5.10.1/Carp/Heavy.pm line 104
30             hmm, it doesn't happen when I step through the debugger, that sure is helpful yessir
31             hmm, throws_ok or dies_ok { stuff that croaks in a package used by the one being tested }, at least in this case causes that error. If I change it to eval {}; ok( $@ ); like( $@, qr// ); it works fine
32             Ah-Ha, earlier when I mentioned I stopped using throws_ok because of something I could not remember, this was it, I stumbled on it again!
33             probably because throws_ok tries to do clever things to fiddle with the call stack to make it appear as though its guts are not being called
34             less clever would be more useful
35              
36             =head1 SYNOPSIS
37              
38             Pretty much a clone of L Refer to those docs for more details.
39              
40             use Test::More;
41             use Test::Exception;
42              
43             dies_ok { die( 'xxx' )} "Should die";
44             lives_ok { 1 } "Should live";
45             throws_ok { die( 'xxx' )} qr/xxx/, "Throws 'xxx'";
46             lives_and { ok( 1, "We did not die" )} "Ooops we died";
47              
48             done_testing;
49              
50             =head1 EXPORTABLE FUNCTIONS
51              
52             =over 4
53              
54             =cut
55              
56             #}}}
57              
58             our @EXPORT_OK = qw/live_or_die/;
59             our @EXPORT = qw/lives_ok dies_ok throws_ok lives_and/;
60             our @CARP_NOT = ( __PACKAGE__ );
61             our $TB = Test::Builder->new;
62             our $VERSION = "0.009";
63              
64             warnings::warnif('deprecated', '!!! Test::Exception::LessClever is deprecated');
65              
66             =item $status = live_or_die( sub { ... }, $name )
67              
68             =item ($status, $msg) = live_or_die( sub { ... }, $name )
69              
70             Check if the code lives or dies. In scalar context returns true or false. In
71             array context returns the same true or false with the error message. If the
72             return is true the error message will be something along the lines of 'did not
73             die' but this may change in the future.
74              
75             Will generate a warning if the test dies, $@ is empty AND called in array
76             context. This usually occurs when an objects DESTROY method calls eval and
77             masks $@.
78              
79             *NOT EXPORTED BY DEFAULT*
80              
81             =cut
82              
83             sub live_or_die {
84 13     13 1 3122 my ( $code ) = @_;
85 13   100     23 my $return = eval { $code->(); 'did not die' } || "died";
86 13         104 my $msg = $@;
87              
88 13 100       35 if ( $return eq 'did not die' ) {
89 6 100       24 return ( 1, $return ) if wantarray;
90 3         10 return 1;
91             }
92             else {
93 7 100       22 return 0 unless wantarray;
94              
95 4 50       22 if ( !$msg ) {
96 0         0 carp "code died as expected, however the error is masked. This"
97             . " can occur when an object's DESTROY() method calls eval";
98             }
99              
100 4         15 return ( 0, $msg );
101             }
102             }
103              
104             =item lives_ok( sub { ... }, $name )
105              
106             Test passes if the sub does not die, false if it does.
107              
108             =cut
109              
110             sub lives_ok(&;$) {
111 2     2 1 1279 my ( $code, $name ) = @_;
112 2         8 my $ok = live_or_die( $code );
113 2         11 $TB->ok( $ok, $name );
114 2         974 return $ok;
115             }
116              
117             =item dies_ok( sub { ... }, $name )
118              
119             Test passes if the sub dies, false if it does not.
120              
121             =cut
122              
123             sub dies_ok(&;$) {
124 2     2 1 166 my ( $code, $name ) = @_;
125 2         8 my $ok = live_or_die( $code );
126 2         10 $TB->ok( !$ok, $name );
127 2         1189 return !$ok;
128             }
129              
130             =item throws_ok( sub { ... }, qr/message/, $name )
131              
132             Check that the sub dies, and that it throws an error that matches the regex.
133              
134             Test fails is the sub does not die, or if the message does not match the regex.
135              
136             =cut
137              
138             sub throws_ok(&$;$) {
139 3     3 1 905 my ( $code, $reg, $name ) = @_;
140 3         8 my ( $ok, $msg ) = live_or_die( $code );
141 3         10 my ( $pkg, $file, $number ) = caller;
142              
143             # If we lived
144 3 100       12 if ( $ok ) {
145 1         10 $TB->diag( "Test did not die as expected at $file line $number." );
146 1         97 return $TB->ok( !$ok, $name );
147             }
148              
149 2 100       17 my $match = $msg =~ $reg ? 1 : 0;
150 2         9 $TB->ok( $match, $name );
151              
152 2 100       1120 $TB->diag( "$file line $number:\n Wanted: $reg\n Got: $msg" )
153             unless( $match );
154              
155 2         104 return $match;
156             }
157              
158             =item lives_and( sub {...}, $name )
159              
160             Fails with $name if the sub dies, otherwise is passive. This is useful for
161             running a test that could die. If it dies there is a failure, if it lives it is
162             responsible for itself.
163              
164             =cut
165              
166             sub lives_and(&;$) {
167 2     2 1 128 my ( $code, $name ) = @_;
168 2         5 my ( $ok, $msg )= live_or_die( $code );
169 2         8 my ( $pkg, $file, $number ) = caller;
170 2         6 chomp( $msg );
171 2         6 $msg =~ s/\n/ /g;
172 2 100       15 $TB->diag( "Test unexpectedly died: '$msg' at $file line $number." ) unless $ok;
173 2 100       100 $TB->ok( $ok, $name ) if !$ok;
174 2         581 return $ok;
175             }
176              
177             1;
178              
179             __END__