File Coverage

blib/lib/TAP/Parser/SourceHandler/MyTAP.pm
Criterion Covered Total %
statement 32 32 100.0
branch 14 16 87.5
condition 6 7 85.7
subroutine 6 6 100.0
pod 2 2 100.0
total 60 63 95.2


line stmt bran cond sub pod time code
1             package TAP::Parser::SourceHandler::MyTAP;
2              
3 1     1   1230 use strict;
  1         3  
  1         54  
4 1     1   7 use vars qw($VERSION @ISA);
  1         2  
  1         72  
5              
6 1     1   1387 use TAP::Parser::IteratorFactory ();
  1         1656  
  1         23  
7 1     1   1093 use TAP::Parser::Iterator::Process ();
  1         11732  
  1         462  
8              
9             @ISA = qw(TAP::Parser::SourceHandler);
10             TAP::Parser::IteratorFactory->register_handler(__PACKAGE__);
11              
12             our $VERSION = '3.25';
13              
14             =head1 Name
15              
16             TAP::Parser::SourceHandler::MyTAP - Stream TAP from MyTAP test scripts
17              
18             =head1 Synopsis
19              
20             In F for your application with MyTAP tests in F:
21              
22             Module::Build->new(
23             module_name => 'MyApp',
24             test_file_exts => [qw(.t .my)],
25             use_tap_harness => 1,
26             tap_harness_args => {
27             sources => {
28             Perl => undef,
29             MyTAP => {
30             database => 'try',
31             user => 'root',
32             suffix => '.my',
33             },
34             }
35             },
36             build_requires => {
37             'Module::Build' => '0.30',
38             'TAP::Parser::SourceHandler::MyTAP' => '3.22',
39             },
40             )->create_build_script;
41              
42             If you're using L|prove>:
43              
44             prove --source Perl \
45             --ext .t --ext .my \
46             --source MyTAP --mytap-option database=try \
47             --mytap-option user=root \
48             --mytap-option suffix=.my
49              
50             If you have only MyTAP tests, just use C:
51              
52             my_prove --database try --user root
53              
54             Direct use:
55              
56             use TAP::Parser::Source;
57             use TAP::Parser::SourceHandler::MyTAP;
58              
59             my $source = TAP::Parser::Source->new->raw(\'mytest.my');
60             $source->config({ MyTAP => {
61             database => 'testing',
62             user => 'root',
63             suffix => '.my',
64             }});
65             $source->assemble_meta;
66              
67             my $class = 'TAP::Parser::SourceHandler::MyTAP';
68             my $vote = $class->can_handle( $source );
69             my $iter = $class->make_iterator( $source );
70              
71             =head1 Description
72              
73             This source handler executes MyTAP MySQL tests. It does two things:
74              
75             =over
76              
77             =item 1.
78              
79             Looks at the L passed to it to determine whether or not
80             the source in question is in fact a MyTAP test (L).
81              
82             =item 2.
83              
84             Creates an iterator that will call C to run the MyTAP tests
85             (L).
86              
87             =back
88              
89             Unless you're writing a plugin or subclassing L, you probably
90             won't need to use this module directly.
91              
92             =head2 Testing with MyTAP
93              
94             If you just want to write tests with L,
95             here's how:
96              
97             =over
98              
99             =item *
100              
101             Download L and install it into your
102             MySQL server:
103              
104             mysql -u root < mytap.sql
105              
106             =item *
107              
108             Write your tests in files ending in F<.my> in the F directory, right
109             alongside your normal Perl F<.t> tests. Here's a simple MyTAP test to get you
110             started:
111              
112             BEGIN;
113              
114             SELECT tap.plan(1);
115              
116             SELECT tap.pass('This should pass!');
117              
118             CALL tap.finish();
119             ROLLBACK;
120              
121             Note how the MyTAP functions are being called from the C database.
122              
123             =begin comment
124              
125             Add this if a MyTAP site comes up with docs.
126              
127             Consult the extensive L
128             documentation|http://mytap.org/documentation.html> for a comprehensive list of
129             test functions.
130              
131             =end comment
132              
133             =item *
134              
135             Run your tests with C like so:
136              
137             my_prove --database try --user root t/
138              
139             Or, if you have Perl F<.t> and MyTAP F<.my> tests, run them all together with
140             C:
141              
142             --ext .t --ext .my \
143             --source MyTAP --mytap-option database=try \
144             --mytap-option user=root \
145             --mytap-option suffix=.my
146             =item *
147              
148             Once you're sure that you've got the MyTAP tests working, modify your
149             F script to allow F<./Build test> to run both the Perl and the MyTAP
150             tests, like so:
151              
152             Module::Build->new(
153             module_name => 'MyApp',
154             test_file_exts => [qw(.t .my)],
155             use_tap_harness => 1,
156             configure_requires => { 'Module::Build' => '0.30', },
157             tap_harness_args => {
158             sources => {
159             Perl => undef,
160             MyTAP => {
161             database => 'try',
162             user => 'root',
163             suffix => '.my',
164             },
165             }
166             },
167             build_requires => {
168             'Module::Build' => '0.30',
169             'TAP::Parser::SourceHandler::MyTAP' => '3.22',
170             },
171             )->create_build_script;
172              
173             The C parameter is optional, since it's implicitly set by the
174             use of the C parameter. All the other parameters are
175             required as you see here. See the documentation for C for a
176             complete list of options to the C key under C.
177              
178             And that's it. Now get testing!
179              
180             =back
181              
182             =head1 Methods
183              
184             =head2 Class Methods
185              
186             =head3 C
187              
188             my $vote = $class->can_handle( $source );
189              
190             Looks at the source to determine whether or not it's a MyTAP test file and
191             returns a score for how likely it is in fact a MyTAP test file. The scores are
192             as follows:
193              
194             1 if it has a suffix equal to that in the "suffix" config
195             1 if its suffix is ".my"
196             0.8 if its suffix is ".sql"
197             0.75 if its suffix is ".s"
198              
199             The latter two scores are subject to change, so try to name your MyTAP tests
200             ending in ".my" or specify a suffix in the configuration to be sure.
201              
202             =cut
203              
204             sub can_handle {
205 6     6 1 3173 my ( $class, $source ) = @_;
206 6         16 my $meta = $source->meta;
207              
208 6 100       50 return 0 unless $meta->{is_file};
209              
210 4         12 my $suf = $meta->{file}{lc_ext};
211              
212             # If the config specifies a suffix, it's required.
213 4 100       14 if ( my $config = $source->config_for('MyTAP') ) {
214 1 50       19 if ( defined $config->{suffix} ) {
215 1 50       9 return $suf eq $config->{suffix} ? 1 : 0;
216             }
217             }
218              
219             # Otherwise, return a score for our supported suffixes.
220 3         65 my %score_for = (
221             '.my' => 0.9,
222             '.sql' => 0.8,
223             '.s' => 0.75,
224             );
225 3   50     20 return $score_for{$suf} || 0;
226             }
227              
228             =head3 C
229              
230             my $iterator = $class->make_iterator( $source );
231              
232             Returns a new L for the source.
233             C<< $source->raw >> must be either a file name or a scalar reference to the
234             file name.
235              
236             The MyTAP tests are run by executing C, the MySQL command-line utility.
237             A number of arguments are passed to it, many of which you can affect by
238             setting up the source source configuration. The configuration must be a hash
239             reference, and supports the following keys:
240              
241             =over
242              
243             =item C
244              
245             The path to the C command. Defaults to simply "mysql", which should work
246             well enough if it's in your path.
247              
248             =item C
249              
250             The database to which to connect to run the tests. Defaults to the system
251             username.
252              
253             =item C
254              
255             The MySQL user to use to connect to MySQL. If not specified, no user will be
256             used, in which case C will fall back on the system username.
257              
258             =item C
259              
260             The password to use to connect to MySQL. If not specified, no password will be
261             used.
262              
263             =item C
264              
265             Specifies the host name of the machine to which to connect to the MySQL
266             server. Defaults to the local host.
267              
268             =item C
269              
270             Specifies the TCP port or the local Unix-domain socket file extension on which
271             the server is listening for connections. Defaults to the port specified at the
272             time C was compiled, usually 3306.
273              
274             =back
275              
276             =cut
277              
278             sub make_iterator {
279 4     4 1 78904 my ( $class, $source ) = @_;
280 4         22 my $config = $source->config_for('MyTAP');
281              
282 4   100     178 my @command = ( $config->{mysql} || 'mysql' );
283 4         13 push @command, qw(
284             --disable-pager
285             --batch
286             --raw
287             --skip-column-names
288             --unbuffered
289             );
290              
291 4         12 for (qw(user password host port database)) {
292 20 100       61 push @command, "--$_" => $config->{$_} if defined $config->{$_};
293             }
294              
295 4 100       13 my $fn = ref $source->raw ? ${ $source->raw } : $source->raw;
  1         10  
296 4 100 100     186 $class->_croak(
    100          
297             'No such file or directory: ' . ( defined $fn ? $fn : '' ) )
298             unless $fn && -e $fn;
299              
300 2         8 push @command, '--execute', "source $fn";
301              
302 2         15 return TAP::Parser::Iterator::Process->new({
303             command => \@command,
304             merge => $source->merge
305             });
306             }
307              
308             =head1 See Also
309              
310             =over
311              
312             =item * L
313              
314             =item * L
315              
316             =item * L
317              
318             =item * L
319              
320             =item * L
321              
322             =item * L
323              
324             =item * L
325              
326             =item * L
327              
328             =item * L
329              
330             =item * L
331              
332             =back
333              
334             =head1 Support
335              
336             This module is managed in an open L
337             repository|http://github.com/theory/tap-parser-sourcehandler-mytap/>. Feel
338             free to fork and contribute, or to clone
339             C and send
340             patches!
341              
342             Found a bug? Please
343             L or
344             L a report!
345              
346             =head1 Author
347              
348             David E. Wheeler
349              
350             =head1 Copyright and License
351              
352             Copyright (c) 2010-2013 David E. Wheeler. Some Rights Reserved.
353              
354             This module is free software; you can redistribute it and/or modify it under
355             the same terms as Perl itself.
356              
357             =cut