File Coverage

support/Test/Builder/Module.pm
Criterion Covered Total %
statement 28 31 90.3
branch 1 2 50.0
condition 1 3 33.3
subroutine 6 6 100.0
pod 2 2 100.0
total 38 44 86.3


line stmt bran cond sub pod time code
1             package Test::Builder::Module;
2              
3 14     14   7442 use Test::Builder;
  14         47  
  14         743  
4              
5             require Exporter;
6             @ISA = qw(Exporter);
7              
8             $VERSION = '0.03';
9              
10 14     14   103 use strict;
  14         27  
  14         4845  
11              
12             # 5.004's Exporter doesn't have export_to_level.
13             my $_export_to_level = sub {
14             my $pkg = shift;
15             my $level = shift;
16             (undef) = shift; # redundant arg
17             my $callpkg = caller($level);
18             $pkg->export($callpkg, @_);
19             };
20              
21              
22             =head1 NAME
23              
24             Test::Builder::Module - Base class for test modules
25              
26             =head1 SYNOPSIS
27              
28             # Emulates Test::Simple
29             package Your::Module;
30              
31             my $CLASS = __PACKAGE__;
32              
33             use base 'Test::Builder::Module';
34             @EXPORT = qw(ok);
35              
36             sub ok ($;$) {
37             my $tb = $CLASS->builder;
38             return $tb->ok(@_);
39             }
40            
41             1;
42              
43              
44             =head1 DESCRIPTION
45              
46             This is a superclass for Test::Builder-based modules. It provides a
47             handful of common functionality and a method of getting at the underlying
48             Test::Builder object.
49              
50              
51             =head2 Importing
52              
53             Test::Builder::Module is a subclass of Exporter which means your
54             module is also a subclass of Exporter. @EXPORT, @EXPORT_OK, etc...
55             all act normally.
56              
57             A few methods are provided to do the C 23> part
58             for you.
59              
60             =head3 import
61              
62             Test::Builder::Module provides an import() method which acts in the
63             same basic way as Test::More's, setting the plan and controling
64             exporting of functions and variables. This allows your module to set
65             the plan independent of Test::More.
66              
67             All arguments passed to import() are passed onto
68             C<< Your::Module->builder->plan() >> with the exception of
69             C[qw(things to import)]>.
70              
71             use Your::Module import => [qw(this that)], tests => 23;
72              
73             says to import the functions this() and that() as well as set the plan
74             to be 23 tests.
75              
76             import() also sets the exported_to() attribute of your builder to be
77             the caller of the import() function.
78              
79             Additional behaviors can be added to your import() method by overriding
80             import_extra().
81              
82             =cut
83              
84             sub import {
85 28     28   201 my($class) = shift;
86              
87 28         92 my $test = $class->builder;
88              
89 28         75 my $caller = caller;
90              
91 28         99 $test->exported_to($caller);
92              
93 28         96 $class->import_extra(\@_);
94 28         103 my(@imports) = $class->_strip_imports(\@_);
95              
96 28         105 $test->plan(@_);
97              
98 28         77 $class->$_export_to_level(1, $class, @imports);
99             }
100              
101              
102             sub _strip_imports {
103 28     28   50 my $class = shift;
104 28         47 my $list = shift;
105              
106 28         48 my @imports = ();
107 28         44 my @other = ();
108 28         47 my $idx = 0;
109 28         43 while( $idx <= $#{$list} ) {
  52         133  
110 24         46 my $item = $list->[$idx];
111              
112 24 50 33     94 if( defined $item and $item eq 'import' ) {
113 0         0 push @imports, @{$list->[$idx+1]};
  0         0  
114 0         0 $idx++;
115             }
116             else {
117 24         42 push @other, $item;
118             }
119              
120 24         41 $idx++;
121             }
122              
123 28         59 @$list = @other;
124              
125 28         61 return @imports;
126             }
127              
128              
129             =head3 import_extra
130              
131             Your::Module->import_extra(\@import_args);
132              
133             import_extra() is called by import(). It provides an opportunity for you
134             to add behaviors to your module based on its import list.
135              
136             Any extra arguments which shouldn't be passed on to plan() should be
137             stripped off by this method.
138              
139             See Test::More for an example of its use.
140              
141             B This mechanism is I as it
142             feels like a bit of an ugly hack in its current form.
143              
144             =cut
145              
146       14 1   sub import_extra {}
147              
148              
149             =head2 Builder
150              
151             Test::Builder::Module provides some methods of getting at the underlying
152             Test::Builder object.
153              
154             =head3 builder
155              
156             my $builder = Your::Class->builder;
157              
158             This method returns the Test::Builder object associated with Your::Class.
159             It is not a constructor so you can call it as often as you like.
160              
161             This is the preferred way to get the Test::Builder object. You should
162             I get it via C<< Test::Builder->new >> as was previously
163             recommended.
164              
165             The object returned by builder() may change at runtime so you should
166             call builder() inside each function rather than store it in a global.
167              
168             sub ok {
169             my $builder = Your::Class->builder;
170              
171             return $builder->ok(@_);
172             }
173              
174              
175             =cut
176              
177             sub builder {
178 48096     48096 1 131611 return Test::Builder->new;
179             }
180              
181              
182             1;