File Coverage

inc/Test/Most.pm
Criterion Covered Total %
statement 98 192 51.0
branch 13 42 30.9
condition 3 9 33.3
subroutine 25 40 62.5
pod 10 10 100.0
total 149 293 50.8


line stmt bran cond sub pod time code
1             #line 1
2             package Test::Most;
3 1     1   1058  
  1         2  
  1         25  
4 1     1   6 use warnings;
  1         1  
  1         28  
5             use strict;
6 1     1   1663  
  1         17644  
  1         56  
7             use Test::Most::Exception 'throw_failure';
8              
9 1     1   683 # XXX don't use 'base' as it can override signal handlers
  1         4  
  1         8  
10             use Test::Builder::Module;
11             our ( @ISA, @EXPORT, $DATA_DUMPER_NAMES_INSTALLED );
12             my $HAVE_TIME_HIRES;
13              
14             BEGIN {
15              
16             # There's some strange fiddling around with import(), so this allows us to
17 1     1   827 # be nicely backwards compatible to earlier versions of Test::More.
18 1         6 require Test::More;
  28         43  
19 1         15 @Test::More::EXPORT = grep { $_ ne 'explain' } @Test::More::EXPORT;
20 1     1   93 Test::More->import;
  1         2300  
  1         2386  
  1         6  
21 1 50       148 eval "use Time::HiRes";
22             $HAVE_TIME_HIRES = 1 unless $@;
23             }
24 1     1   9  
  1         3  
  1         44  
25             use Test::Builder;
26             my $OK_FUNC;
27 1     1   87 BEGIN {
28             $OK_FUNC = \&Test::Builder::ok;
29             }
30              
31             #line 38
32              
33             our $VERSION = '0.31';
34             $VERSION = eval $VERSION;
35              
36             #line 437
37              
38             BEGIN {
39             @ISA = qw(Test::Builder::Module);
40             @EXPORT = (
41             @Test::More::EXPORT,
42             qw<
43             all_done
44             bail_on_fail
45             die_on_fail
46             explain
47             always_explain
48             last_test_failed
49             restore_fail
50             set_failure_handler
51             show
52             always_show
53             >
54             );
55             }
56              
57             sub import {
58             my $bail_set = 0;
59              
60             my %modules_to_load = map { $_ => 1 } qw/
61             Test::Differences
62             Test::Exception
63             Test::Deep
64             Test::Warn
65             /;
66             warnings->import;
67             strict->import;
68             eval "use Data::Dumper::Names 0.03";
69             $DATA_DUMPER_NAMES_INSTALLED = !$@;
70              
71             if ( $ENV{BAIL_ON_FAIL} ) {
72             $bail_set = 1;
73             bail_on_fail();
74             }
75             if ( !$bail_set and $ENV{DIE_ON_FAIL} ) {
76             die_on_fail();
77             }
78             for my $i ( 0 .. $#_ ) {
79             if ( 'bail' eq $_[$i] ) {
80             splice @_, $i, 1;
81             bail_on_fail();
82             $bail_set = 1;
83             last;
84             }
85             }
86             my $caller = caller;
87             for my $i ( 0 .. $#_ ) {
88             if ( 'timeit' eq $_[$i] ) {
89             splice @_, $i, 1;
90             no strict;
91             *{"${caller}::timeit"} = \&timeit;
92             last;
93             }
94             }
95              
96             my %exclude_symbol;
97             my $i = 0;
98              
99             if ( grep { $_ eq 'blessed' } @_ ) {
100             @_ = grep { $_ ne 'blessed' } @_;
101             }
102             else {
103             $exclude_symbol{blessed} = 1;
104             }
105             while ($i < @_) {
106             if ( !$bail_set and ( 'die' eq $_[$i] ) ) {
107             splice @_, $i, 1;
108             die_on_fail();
109             $i = 0;
110             next;
111             }
112             if ( $_[$i] =~ /^-(.*)/ ) {
113             my $module = $1;
114             splice @_, $i, 1;
115             unless (exists $modules_to_load{$module}) {
116             require Carp;
117             Carp::croak("Cannot remove non-existent Test::Module ($module)");
118             }
119             delete $modules_to_load{$module};
120             $i = 0;
121             next;
122             }
123             if ( $_[$i] =~ /^!(.*)/ ) {
124             splice @_, $i, 1;
125             $exclude_symbol{$1} = 1;
126             $i = 0;
127             next;
128             }
129             if ( 'defer_plan' eq $_[$i] ) {
130             splice @_, $i, 1;
131              
132             my $builder = Test::Builder->new;
133             $builder->{Have_Plan} = 1
134             ; # don't like setting this directly, but Test::Builder::has_plan doe
135             $builder->{TEST_MOST_deferred_plan} = 1;
136             $builder->{TEST_MOST_all_done} = 0;
137             $i = 0;
138             next;
139             }
140             $i++;
141             }
142             foreach my $module (keys %modules_to_load) {
143             eval "use $module";
144              
145             if ( my $error = $@) {
146             require Carp;
147             Carp::croak($error);
148             }
149             no strict 'refs';
150             # Note: export_to_level would be better here.
151             push @EXPORT => grep { !$exclude_symbol{$_} } @{"${module}::EXPORT"};
152             }
153              
154             # 'magic' goto to avoid updating the callstack
155             goto &Test::Builder::Module::import;
156             }
157              
158             sub explain {
159             _explain(\&Test::More::note, @_);
160             }
161              
162              
163             sub timeit(&;$) {
164             my ( $code, $message ) = @_;
165             unless($HAVE_TIME_HIRES) {
166             Test::Most::diag("timeit: Time::HiRes not installed");
167             $code->();
168             }
169             if ( !$message ) {
170             my ( $package, $filename, $line ) = caller;
171             $message = "$filename line $line";
172             }
173             my $start = [Time::HiRes::gettimeofday()];
174             $code->();
175             explain(
176             sprintf "$message: took %s seconds" => Time::HiRes::tv_interval($start) );
177             }
178              
179             sub always_explain {
180             _explain(\&Test::More::diag, @_);
181             }
182              
183             sub _explain {
184             my $diag = shift;
185             no warnings 'once';
186             $diag->(
187             map {
188             ref $_
189             ? do {
190             require Data::Dumper;
191             local $Data::Dumper::Indent = 1;
192             local $Data::Dumper::Sortkeys = 1;
193             local $Data::Dumper::Terse = 1;
194             Data::Dumper::Dumper($_);
195             }
196             : $_
197             } @_
198             );
199             }
200              
201             sub show {
202             _show(\&Test::More::note, @_);
203             }
204              
205             sub always_show {
206             _show(\&Test::More::diag, @_);
207             }
208              
209             sub _show {
210             unless ( $DATA_DUMPER_NAMES_INSTALLED ) {
211             require Carp;
212             Carp::carp("Data::Dumper::Names 0.03 not found. Use explain() instead of show()");
213             goto &_explain;
214             }
215             my $diag = shift;
216             no warnings 'once';
217             local $Data::Dumper::Indent = 1;
218             local $Data::Dumper::Sortkeys = 1;
219             local $Data::Dumper::Names::UpLevel = $Data::Dumper::Names::UpLevel + 2;
220             $diag->(Data::Dumper::Names::Dumper(@_));
221             }
222              
223             sub die_on_fail {
224             set_failure_handler( sub { throw_failure } );
225             }
226              
227             sub bail_on_fail {
228             set_failure_handler(
229             sub { Test::More::BAIL_OUT("Test failed. BAIL OUT!.\n") } );
230             }
231              
232             sub restore_fail {
233             no warnings 'redefine';
234             *Test::Builder::ok = $OK_FUNC;
235             }
236              
237             sub all_done {
238             my $builder = Test::Builder->new;
239             if ($builder->{TEST_MOST_deferred_plan}) {
240             $builder->{TEST_MOST_all_done} = 1;
241             $builder->expected_tests(@_ ? $_[0] : $builder->current_test);
242             }
243             }
244              
245              
246             sub set_failure_handler {
247             my $action = shift;
248             no warnings 'redefine';
249             Test::Builder->new->{TEST_MOST_failure_action} = $action; # for DESTROY
250             *Test::Builder::ok = sub {
251             local $Test::Builder::Level = $Test::Builder::Level + 1;
252             my $builder = $_[0];
253             if ( $builder->{TEST_MOST_test_failed} ) {
254             $builder->{TEST_MOST_test_failed} = 0;
255             $action->($builder);
256             }
257             $builder->{TEST_MOST_test_failed} = 0;
258             my $result = $OK_FUNC->(@_);
259             $builder->{TEST_MOST_test_failed} = !( $builder->summary )[-1];
260             return $result;
261             };
262             }
263              
264             {
265             no warnings 'redefine';
266              
267             # we need this because if the failure is on the final test, we won't have
268             # a subsequent test triggering the behavior.
269             sub Test::Builder::DESTROY {
270             my $builder = $_[0];
271             if ( $builder->{TEST_MOST_test_failed} ) {
272             $builder->{TEST_MOST_failure_action}->();
273             }
274             }
275             }
276              
277             sub _deferred_plan_handler {
278             my $builder = Test::Builder->new;
279             if ($builder->{TEST_MOST_deferred_plan} and !$builder->{TEST_MOST_all_done})
280             {
281             $builder->expected_tests($builder->current_test + 1);
282             }
283             }
284              
285             # This should work because the END block defined by Test::Builder should be
286             # guaranteed to be run before t one, since we use'd Test::Builder way up top.
287             # The other two alternatives would be either to replace Test::Builder::_ending
288             # similar to how we did Test::Builder::ok, or to call Test::Builder::no_ending
289             # and basically rewrite _ending in our own image. Neither is very palatable,
290             # considering _ending's initial underscore.
291              
292             END {
293             _deferred_plan_handler();
294             }
295              
296             1;
297              
298             #line 806
299              
300             1;