File Coverage

blib/lib/TAP/Parser/SourceHandler/MyTAP.pm
Criterion Covered Total %
statement 37 38 97.3
branch 18 22 81.8
condition 6 7 85.7
subroutine 6 6 100.0
pod 2 2 100.0
total 69 75 92.0


line stmt bran cond sub pod time code
1             package TAP::Parser::SourceHandler::MyTAP;
2              
3 1     1   576 use strict;
  1         1  
  1         27  
4 1     1   3 use vars qw($VERSION @ISA);
  1         1  
  1         42  
5              
6 1     1   431 use TAP::Parser::IteratorFactory ();
  1         874  
  1         15  
7 1     1   429 use TAP::Parser::Iterator::Process ();
  1         6251  
  1         323  
8              
9             @ISA = qw(TAP::Parser::SourceHandler);
10             TAP::Parser::IteratorFactory->register_handler(__PACKAGE__);
11              
12             our $VERSION = '3.27';
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 a "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 7     7 1 2930 my ( $class, $source ) = @_;
206 7         18 my $meta = $source->meta;
207              
208 7 100       47 return 0 unless $meta->{is_file};
209              
210 5         10 my $suf = $meta->{file}{lc_ext};
211              
212             # If the config specifies a suffix, it's required.
213 5 100       15 if ( my $config = $source->config_for('MyTAP') ) {
214 2 50       31 if ( my $suffix = $config->{suffix} ) {
215 2 100       6 if (ref $suffix) {
216 1 50       2 return (grep { $suf eq $_ } @{ $suffix }) ? 1 : 0;
  2         9  
  1         3  
217             }
218 1 50       7 return $suf eq $config->{suffix} ? 1 : 0;
219             }
220             }
221              
222             # Otherwise, return a score for our supported suffixes.
223 3         61 my %score_for = (
224             '.my' => 0.9,
225             '.sql' => 0.8,
226             '.s' => 0.75,
227             );
228 3   50     19 return $score_for{$suf} || 0;
229             }
230              
231             =head3 C
232              
233             my $iterator = $class->make_iterator( $source );
234              
235             Returns a new L for the source.
236             C<< $source->raw >> must be either a file name or a scalar reference to the
237             file name.
238              
239             The MyTAP tests are run by executing C, the MySQL command-line utility.
240             A number of arguments are passed to it, many of which you can affect by
241             setting up the source source configuration. The configuration must be a hash
242             reference, and supports the following keys:
243              
244             =over
245              
246             =item C
247              
248             The path to the C command. Defaults to simply "mysql", which should work
249             well enough if it's in your path.
250              
251             =item C
252              
253             The database to which to connect to run the tests. Defaults to the system
254             username.
255              
256             =item C
257              
258             The MySQL user to use to connect to MySQL. If not specified, no user will be
259             used, in which case C will fall back on the system username.
260              
261             =item C
262              
263             The password to use to connect to MySQL. If not specified, no password will be
264             used.
265              
266             =item C
267              
268             Specifies the host name of the machine to which to connect to the MySQL
269             server. Defaults to the local host.
270              
271             =item C
272              
273             Specifies the TCP port or the local Unix-domain socket file extension on which
274             the server is listening for connections. Defaults to the port specified at the
275             time C was compiled, usually 3306.
276              
277             =back
278              
279             =cut
280              
281             sub make_iterator {
282 4     4 1 21354 my ( $class, $source ) = @_;
283 4         18 my $config = $source->config_for('MyTAP');
284              
285 4   100     88 my @command = ( $config->{mysql} || 'mysql' );
286 4         9 push @command, qw(
287             --disable-pager
288             --batch
289             --raw
290             --skip-column-names
291             --unbuffered
292             );
293              
294 4         10 for (qw(user host port database)) {
295 16 100       48 push @command, "--$_" => $config->{$_} if defined $config->{$_};
296             }
297              
298             # Special-case --password, which requires = before the value. O_o
299 4 50       12 if (my $pw = $config->{password}) {
300 0         0 push @command, "--password=$pw";
301             }
302              
303 4 100       12 my $fn = ref $source->raw ? ${ $source->raw } : $source->raw;
  1         8  
304 4 100 100     143 $class->_croak(
    100          
305             'No such file or directory: ' . ( defined $fn ? $fn : '' ) )
306             unless $fn && -e $fn;
307              
308 2         6 push @command, '--execute', "source $fn";
309              
310 2         8 return TAP::Parser::Iterator::Process->new({
311             command => \@command,
312             merge => $source->merge
313             });
314             }
315              
316             =head1 See Also
317              
318             =over
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             =item * L
333              
334             =item * L
335              
336             =item * L
337              
338             =item * L
339              
340             =back
341              
342             =head1 Support
343              
344             This module is managed in an open
345             L.
346             Feel free to fork and contribute, or to clone
347             C and send
348             patches!
349              
350             Found a bug? Please
351             L or
352             L a report!
353              
354             =head1 Author
355              
356             David E. Wheeler
357              
358             =head1 Copyright and License
359              
360             Copyright (c) 2010-2016 David E. Wheeler. Some Rights Reserved.
361              
362             This module is free software; you can redistribute it and/or modify it under
363             the same terms as Perl itself.
364              
365             =cut