File Coverage

blib/lib/TAP/Parser/SourceHandler/MyTAP.pm
Criterion Covered Total %
statement 36 36 100.0
branch 17 20 85.0
condition 6 7 85.7
subroutine 6 6 100.0
pod 2 2 100.0
total 67 71 94.3


line stmt bran cond sub pod time code
1             package TAP::Parser::SourceHandler::MyTAP;
2              
3 1     1   636 use strict;
  1         2  
  1         37  
4 1     1   4 use vars qw($VERSION @ISA);
  1         1  
  1         45  
5              
6 1     1   503 use TAP::Parser::IteratorFactory ();
  1         941  
  1         17  
7 1     1   480 use TAP::Parser::Iterator::Process ();
  1         6479  
  1         332  
8              
9             @ISA = qw(TAP::Parser::SourceHandler);
10             TAP::Parser::IteratorFactory->register_handler(__PACKAGE__);
11              
12             our $VERSION = '3.26';
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 2513 my ( $class, $source ) = @_;
206 7         13 my $meta = $source->meta;
207              
208 7 100       38 return 0 unless $meta->{is_file};
209              
210 5         27 my $suf = $meta->{file}{lc_ext};
211              
212             # If the config specifies a suffix, it's required.
213 5 100       11 if ( my $config = $source->config_for('MyTAP') ) {
214 2 50       28 if ( my $suffix = $config->{suffix} ) {
215 2 100       5 if (ref $suffix) {
216 1 50       1 return (grep { $suf eq $_ } @{ $suffix }) ? 1 : 0;
  2         8  
  1         2  
217             }
218 1 50       4 return $suf eq $config->{suffix} ? 1 : 0;
219             }
220             }
221              
222             # Otherwise, return a score for our supported suffixes.
223 3         45 my %score_for = (
224             '.my' => 0.9,
225             '.sql' => 0.8,
226             '.s' => 0.75,
227             );
228 3   50     13 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 23183 my ( $class, $source ) = @_;
283 4         12 my $config = $source->config_for('MyTAP');
284              
285 4   100     71 my @command = ( $config->{mysql} || 'mysql' );
286 4         8 push @command, qw(
287             --disable-pager
288             --batch
289             --raw
290             --skip-column-names
291             --unbuffered
292             );
293              
294 4         10 for (qw(user password host port database)) {
295 20 100       44 push @command, "--$_" => $config->{$_} if defined $config->{$_};
296             }
297              
298 4 100       9 my $fn = ref $source->raw ? ${ $source->raw } : $source->raw;
  1         6  
299 4 100 100     94 $class->_croak(
    100          
300             'No such file or directory: ' . ( defined $fn ? $fn : '' ) )
301             unless $fn && -e $fn;
302              
303 2         4 push @command, '--execute', "source $fn";
304              
305 2         6 return TAP::Parser::Iterator::Process->new({
306             command => \@command,
307             merge => $source->merge
308             });
309             }
310              
311             =head1 See Also
312              
313             =over
314              
315             =item * L
316              
317             =item * L
318              
319             =item * L
320              
321             =item * L
322              
323             =item * L
324              
325             =item * L
326              
327             =item * L
328              
329             =item * L
330              
331             =item * L
332              
333             =item * L
334              
335             =back
336              
337             =head1 Support
338              
339             This module is managed in an open L
340             repository|http://github.com/theory/tap-parser-sourcehandler-mytap/>. Feel
341             free to fork and contribute, or to clone
342             C and send
343             patches!
344              
345             Found a bug? Please
346             L or
347             L a report!
348              
349             =head1 Author
350              
351             David E. Wheeler
352              
353             =head1 Copyright and License
354              
355             Copyright (c) 2010-2015 David E. Wheeler. Some Rights Reserved.
356              
357             This module is free software; you can redistribute it and/or modify it under
358             the same terms as Perl itself.
359              
360             =cut