File Coverage

blib/lib/Test/Aggregate/Base.pm
Criterion Covered Total %
statement 103 115 89.5
branch 33 44 75.0
condition 9 11 81.8
subroutine 35 35 100.0
pod 0 1 0.0
total 180 206 87.3


line stmt bran cond sub pod time code
1             package Test::Aggregate::Base;
2              
3 14     14   77 use strict;
  14         24  
  14         374  
4 13     13   68 use warnings;
  13         20  
  13         375  
5              
6 13     13   64 use Carp 'croak';
  13         21  
  13         685  
7 13     13   70 use Test::Builder::Module;
  13         22  
  13         99  
8 13     13   296 use Test::More;
  13         20  
  13         152  
9 13     13   3121 use File::Find;
  13         25  
  13         1123  
10              
11 13     13   68 use vars qw(@ISA @EXPORT @EXPORT_OK);
  13         21  
  13         2833  
12             @ISA = qw(Test::Builder::Module);
13              
14             our $VERSION = '0.373';
15             $VERSION = eval $VERSION;
16              
17             our $_pid = $$;
18              
19             BEGIN {
20 13     13   99 $ENV{TEST_AGGREGATE} = 1;
21             *CORE::GLOBAL::exit = sub {
22 2     2   2526 my ($package, $filename, $line) = caller;
23              
24             # Warn about exit being called unless there's been a fork()
25             # (in which case some form of exit is expected).
26 2 50       76 if( $_pid == $$ ){
27              
28 0         0 print STDERR <<" END_EXIT_WARNING";
29             ********
30             WARNING!
31             exit called under Test::Aggregate at:
32             File: $filename
33             Package: $package
34             Line: $line
35             WARNING!
36             ********
37             END_EXIT_WARNING
38              
39             }
40              
41 2         1258 exit(@_);
42 13         14112 };
43             };
44              
45             END { # for VMS
46 13     13   9303 delete $ENV{TEST_AGGREGATE};
47             }
48              
49             sub _code_attributes {
50 43     43   520 qw/
51             setup
52             teardown
53             startup
54             shutdown
55             /;
56             }
57              
58             sub new {
59 17     17 0 37 my ( $class, $arg_for ) = @_;
60              
61 17 50 66     148 unless ( exists $arg_for->{dirs} || exists $arg_for->{tests} ) {
62 0         0 Test::More::BAIL_OUT("You must supply 'dirs' or 'tests'");
63             }
64 17 50 66     153 if ( exists $arg_for->{tests} && 'ARRAY' ne ref $arg_for->{tests} ) {
65 0         0 Test::More::BAIL_OUT(
66             "Argument for Test::Aggregate 'tests' key must be an array reference"
67             );
68             }
69            
70 17 100       75 $arg_for->{test_nowarnings} = 1 unless exists $arg_for->{test_nowarnings};
71 17 100       70 $arg_for->{set_filenames} = 1 unless exists $arg_for->{set_filenames};
72 17 100       66 $arg_for->{findbin} = 1 unless exists $arg_for->{findbin};
73 17         40 my $dirs = delete $arg_for->{dirs};
74 17 100       62 if ( defined $dirs ) {
75 6 100       30 $dirs = [$dirs] if 'ARRAY' ne ref $dirs;
76             }
77             else {
78 11         23 $dirs = [];
79             }
80              
81 17         87 my $matching = qr//;
82 17 100       60 if ( $arg_for->{matching} ) {
83 1         2 $matching = delete $arg_for->{matching};
84 1 50       6 unless ( 'Regexp' eq ref $matching ) {
85 0         0 croak("Argument for 'matching' must be a pre-compiled regex");
86             }
87             }
88              
89 17         26 my $has_code_attributes;
90 17         129 foreach my $attribute ( $class->_code_attributes ) {
91 68 100       176 if ( my $ref = $arg_for->{$attribute} ) {
92 14 50       32 if ( 'CODE' ne ref $ref ) {
93 0         0 croak("Attribute ($attribute) must be a code reference");
94             }
95             else {
96 14         24 $has_code_attributes++;
97             }
98             }
99             }
100              
101 17         129 my $self = bless {
102             dirs => $dirs,
103             matching => $matching,
104             _no_streamer => 0,
105             _packages => [],
106             aggregate_program => $0,
107             } => $class;
108              
109 17 50       61 if ( delete $arg_for->{check_plan} ) {
110 0         0 Carp::carp("'check_plan' is now deprecated and a no-op.");
111             }
112 17         79 $self->{$_} = delete $arg_for->{$_} foreach (
113             qw/
114             dry
115             dump
116             findbin
117             no_generate_plan
118             set_filenames
119             shuffle
120             test_nowarnings
121             tests
122             tidy
123             verbose
124             /,
125             $class->_code_attributes
126             );
127 17   100     85 $self->{tests} ||= [];
128              
129 17 50       85 if ( my @keys = keys %$arg_for ) {
130 0         0 local $" = ', ';
131 0         0 croak("Unknown keys to &new: (@keys)");
132             }
133              
134 17 100       45 if ($has_code_attributes) {
135 8     5   514 eval "use Data::Dump::Streamer";
  5     2   6700  
  5         316660  
  5         42  
  2         11  
  2         2  
  2         16  
136 8 50       960 if ( my $error = $@ ) {
137 0         0 $self->{_no_streamer} = 1;
138 0 0       0 if ( my $dump = $self->_dump ) {
139 0         0 warn <<" END_WARNING";
140             Dump file ($dump) cannot be generated. A code attributes was requested but
141             we cannot load Data::Dump::Streamer: $error.
142             END_WARNING
143 0         0 $self->{dump} = '';
144             }
145             }
146             }
147              
148 17         79 return $self;
149             }
150              
151             # set from user data
152              
153 15 50   15   112 sub _dump { shift->{dump} || '' }
154 8     8   44 sub _dry { shift->{dry} }
155 17     17   68 sub _should_shuffle { shift->{shuffle} }
156 17     17   48 sub _matching { shift->{matching} }
157 23     23   99 sub _set_filenames { shift->{set_filenames} }
158 47     47   605 sub _findbin { shift->{findbin} }
159 23     23   35 sub _dirs { @{ shift->{dirs} } }
  23         812  
160 25     25   261 sub _startup { shift->{startup} }
161 24     24   339 sub _shutdown { shift->{shutdown} }
162 50     50   264 sub _setup { shift->{setup} }
163 48     48   283 sub _teardown { shift->{teardown} }
164 17     17   31 sub _tests { @{ shift->{tests} } }
  17         69  
165 7     7   62 sub _tidy { shift->{tidy} }
166 8     8   47 sub _test_nowarnings { shift->{test_nowarnings} }
167              
168             sub _verbose {
169 55     55   89 my $self = shift;
170 55 100       332 $self->{verbose} ? $self->{verbose} : 0;
171             }
172              
173             # set from internal data
174 32     32   108 sub _no_streamer { shift->{_no_streamer} }
175 7     7   23 sub _packages { @{ shift->{_packages} } }
  7         59  
176              
177             sub _get_tests {
178 17     17   39 my $self = shift;
179 17         26 my @tests;
180 17         117 my $matching = $self->_matching;
181 17 100       96 if ( $self->_dirs ) {
182             find( {
183             no_chdir => 1,
184             wanted => sub {
185 66 100 100 66   1486 push @tests => $File::Find::name if /\.t\z/ && /$matching/;
186             }
187 6         51 }, $self->_dirs );
188             }
189 17         148 push @tests => $self->_tests;
190            
191 17 100       98 if ( $self->_should_shuffle ) {
192 3         18 $self->_shuffle(@tests);
193             }
194             else {
195 14         48 @tests = sort @tests;
196             }
197 17         78 return @tests;
198             }
199              
200             sub _shuffle {
201 3     3   6 my $self = shift;
202              
203             # Fisher-Yates shuffle
204 3         9 my $i = @_;
205 3         11 while ($i) {
206 31         131 my $j = rand $i--;
207 31         87 @_[ $i, $j ] = @_[ $j, $i ];
208             }
209 3         8 return;
210             }
211              
212             sub _get_package {
213 62     62   122 my ( $class, $file ) = @_;
214 62         360 $file =~ s/\W//g;
215 62         173 return $file;
216             }
217              
218             1;
219              
220             __END__
221              
222             =encoding utf-8
223              
224             =head1 NAME
225              
226             Test::Aggregate::Base - Base class for aggregated tests.
227              
228             =head1 VERSION
229              
230             Version 0.373
231              
232             =head1 SYNOPSIS
233              
234             use base 'Test::Aggregate::base';
235              
236             sub run { ... }
237              
238              
239             =head1 DESCRIPTION
240              
241             This module is for internal use only.
242              
243             =head1 AUTHOR
244              
245             Curtis Poe, C<< <ovid at cpan.org> >>
246              
247             =head1 BUGS
248              
249             Please report any bugs or feature requests to
250             C<bug-test-aggregate at rt.cpan.org>, or through the web interface at
251             L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-Aggregate>.
252             I will be notified, and then you'll automatically be notified of progress on
253             your bug as I make changes.
254              
255             =head1 SUPPORT
256              
257             You can find documentation for this module with the perldoc command.
258              
259             perldoc Test::Aggregate::Base
260              
261             You can also find information oneline:
262              
263             L<http://metacpan.org/release/Test-Aggregate>
264              
265             =head1 ACKNOWLEDGEMENTS
266              
267             Many thanks to mauzo (L<http://use.perl.org/~mauzo/> for helping me find the
268             'skip_all' bug.
269              
270             Thanks to Johan Lindström for pointing me to Apache::Registry.
271              
272             =head1 COPYRIGHT & LICENSE
273              
274             Copyright 2007 Curtis "Ovid" Poe, all rights reserved.
275              
276             This program is free software; you can redistribute it and/or modify it
277             under the same terms as Perl itself.
278              
279             =cut