Commit | Line | Data |
---|---|---|
b1ddf169 RGS |
1 | package Test::Builder::Module; |
2 | ||
705e6672 SP |
3 | use strict; |
4 | ||
b1ddf169 RGS |
5 | use Test::Builder; |
6 | ||
7 | require Exporter; | |
705e6672 | 8 | our @ISA = qw(Exporter); |
b1ddf169 | 9 | |
bdff39c7 | 10 | our $VERSION = '0.80'; |
b1ddf169 RGS |
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<use Your::Module tests => 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<import =>[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 | my($class) = shift; | |
04955c14 SP |
86 | |
87 | # Don't run all this when loading ourself. | |
88 | return 1 if $class eq 'Test::Builder::Module'; | |
b1ddf169 RGS |
89 | |
90 | my $test = $class->builder; | |
91 | ||
92 | my $caller = caller; | |
93 | ||
94 | $test->exported_to($caller); | |
95 | ||
96 | $class->import_extra(\@_); | |
97 | my(@imports) = $class->_strip_imports(\@_); | |
98 | ||
99 | $test->plan(@_); | |
100 | ||
101 | $class->$_export_to_level(1, $class, @imports); | |
102 | } | |
103 | ||
104 | ||
105 | sub _strip_imports { | |
106 | my $class = shift; | |
107 | my $list = shift; | |
108 | ||
109 | my @imports = (); | |
110 | my @other = (); | |
111 | my $idx = 0; | |
112 | while( $idx <= $#{$list} ) { | |
113 | my $item = $list->[$idx]; | |
114 | ||
115 | if( defined $item and $item eq 'import' ) { | |
116 | push @imports, @{$list->[$idx+1]}; | |
117 | $idx++; | |
118 | } | |
119 | else { | |
120 | push @other, $item; | |
121 | } | |
122 | ||
123 | $idx++; | |
124 | } | |
125 | ||
126 | @$list = @other; | |
127 | ||
128 | return @imports; | |
129 | } | |
130 | ||
131 | ||
132 | =head3 import_extra | |
133 | ||
134 | Your::Module->import_extra(\@import_args); | |
135 | ||
136 | import_extra() is called by import(). It provides an opportunity for you | |
137 | to add behaviors to your module based on its import list. | |
138 | ||
139 | Any extra arguments which shouldn't be passed on to plan() should be | |
140 | stripped off by this method. | |
141 | ||
142 | See Test::More for an example of its use. | |
143 | ||
144 | B<NOTE> This mechanism is I<VERY ALPHA AND LIKELY TO CHANGE> as it | |
145 | feels like a bit of an ugly hack in its current form. | |
146 | ||
147 | =cut | |
148 | ||
149 | sub import_extra {} | |
150 | ||
151 | ||
152 | =head2 Builder | |
153 | ||
154 | Test::Builder::Module provides some methods of getting at the underlying | |
155 | Test::Builder object. | |
156 | ||
157 | =head3 builder | |
158 | ||
159 | my $builder = Your::Class->builder; | |
160 | ||
161 | This method returns the Test::Builder object associated with Your::Class. | |
162 | It is not a constructor so you can call it as often as you like. | |
163 | ||
164 | This is the preferred way to get the Test::Builder object. You should | |
165 | I<not> get it via C<< Test::Builder->new >> as was previously | |
166 | recommended. | |
167 | ||
168 | The object returned by builder() may change at runtime so you should | |
169 | call builder() inside each function rather than store it in a global. | |
170 | ||
171 | sub ok { | |
172 | my $builder = Your::Class->builder; | |
173 | ||
174 | return $builder->ok(@_); | |
175 | } | |
176 | ||
177 | ||
178 | =cut | |
179 | ||
180 | sub builder { | |
181 | return Test::Builder->new; | |
182 | } | |
183 | ||
184 | ||
185 | 1; |