File Coverage

blib/lib/Test/Run/CmdLine.pm
Criterion Covered Total %
statement 121 139 87.0
branch 6 14 42.8
condition n/a
subroutine 31 34 91.1
pod 8 8 100.0
total 166 195 85.1


line stmt bran cond sub pod time code
1             package Test::Run::CmdLine;
2              
3 7     7   26113 use warnings;
  7         23  
  7         204  
4 7     7   34 use strict;
  7         13  
  7         128  
5              
6 7     7   130 use 5.008;
  7         27  
7              
8 7     7   39 use Carp;
  7         12  
  7         465  
9 7     7   813 use UNIVERSAL::require;
  7         1515  
  7         85  
10 7     7   4931 use YAML::XS ();
  7         21883  
  7         163  
11              
12 7     7   4674 use Test::Run::Base;
  7         2578453  
  7         94  
13              
14 7     7   5869 use Test::Run::Iface;
  7         614  
  7         75  
15 7     7   4290 use Test::Run::Obj;
  7         4248462  
  7         91  
16              
17             =head1 NAME
18              
19             Test::Run::CmdLine - Analyze tests from the command line using Test::Run
20              
21             =cut
22              
23 7     7   270 use vars (qw($VERSION));
  7         15  
  7         377  
24              
25             $VERSION = '0.0131';
26              
27 7     7   37 use Moose;
  7         13  
  7         46  
28              
29             extends ('Test::Run::Base');
30              
31             =head1 SYNOPSIS
32              
33             use Test::Run::CmdLine;
34              
35             my $tester = Test::Run::CmdLine->new(
36             {
37             'test_files' => ["t/one.t", "t/two.t"],
38             },
39             );
40              
41             $tester->run();
42              
43             =cut
44              
45             has 'backend_class' => (is => "rw", isa => "Str",
46             default => "Test::Run::Iface"
47             );
48             has 'backend_params' => (is => "rw", isa => "HashRef");
49             has 'backend_plugins' => (is => "rw", isa => "ArrayRef",
50             default => sub { [] },
51             );
52             has 'backend_env_args' => (is => "rw", isa => "ArrayRef",
53             default => sub { [] },
54             );
55             has 'test_files' => (is => "rw", isa => "ArrayRef");
56              
57             sub BUILD
58             {
59 6     6 1 10379 my $self = shift;
60              
61 6         46 $self->_collect_backend_plugins();
62              
63 6         18 return;
64             }
65              
66             sub _process_args
67             {
68 0     0   0 my ($self, $args) = @_;
69 0 0       0 if (exists($args->{backend_params}))
70             {
71 0         0 $self->backend_params($args->{backend_params});
72             }
73              
74 0         0 return 0;
75             }
76              
77             =head1 Interface Functions
78              
79             =head2 $tester = Test::Run::CmdLine->new({'test_files' => \@test_files, ....});
80              
81             Initializes a new testing front end. C<test_files> is a named argument that
82             contains the files to test.
83              
84             Other named arguments are:
85              
86             =over 4
87              
88             =item backend_params
89              
90             This is a hash of named parameters to be passed to the backend class (derived
91             from L<Test::Run::Obj>.)
92              
93             =item driver_class
94              
95             This is the backend class that will be instantiated and used to perform
96             the processing. Defaults to L<Test::Run::Obj>.
97              
98             =back
99              
100             =head2 $tester->run()
101              
102             Actually runs the tests on the command line.
103              
104             TODO : Write more.
105              
106             =head2 BUILD
107              
108             For Moose.
109              
110             =cut
111              
112             sub run
113             {
114 3     3 1 69 my $self = shift;
115 3         126 my $backend_class = $self->backend_class();
116 3         43 $backend_class->require();
117 3 50       99 if ($@)
118             {
119 0         0 die $@;
120             }
121 3         7 foreach my $plugin (@{$self->_calc_plugins_for_ISA()})
  3         21  
122             {
123 3         21 $plugin->require();
124 3 50       487 if ($@)
125             {
126 0         0 die $@;
127             }
128             {
129 7     7   46200 no strict 'refs';
  7         22  
  7         453  
  3         6  
130 3         27 push @{"${backend_class}::ISA"}, $plugin;
  3         54  
131             }
132             }
133              
134             # Finally - put Test::Run::Obj there.
135             {
136 7     7   37 no strict 'refs';
  7         12  
  7         8460  
  3         7  
137 3         6 push @{"${backend_class}::ISA"}, "Test::Run::Obj";
  3         82  
138             }
139              
140             my $backend = $backend_class->new(
141             {
142             'test_files' => $self->test_files(),
143 3         142 @{$self->get_backend_args()},
  3         29  
144             },
145             );
146              
147 3         50757 return $backend->runtests();
148             }
149              
150             =head1 Environment Variables
151              
152             The following environment variables (C<%ENV>) affect the behaviour of
153             Test::Run::CmdLine:
154              
155             =over 4
156              
157             =item HARNESS_COLUMNS
158              
159             This determines the width of the terminal (sets C<'Columns'>) in
160             L<Test::Run::Obj>). If not specified, it will be determined according
161             to the C<COLUMNS> environment variable, that is normally specified by
162             the terminal.
163              
164             =item HARNESS_DEBUG
165              
166             Triggers the C<'Debug'> option in Test::Run::Obj. Meaning, it will print
167             debugging information about itself as it runs the tests.
168              
169             =item HARNESS_FILELEAK_IN_DIR
170              
171             This variable points to a directory that will be monitored. After each
172             test file, the module will check if new files appeared in the direcotry
173             and report them.
174              
175             It is advisable to give an absolute path here. If it is relative, it would
176             be relative to the current working directory when C<$tester-E<gt>run()> was
177             called.
178              
179             =item HARNESS_NOTTY
180              
181             Triggers the C<'NoTty'> option in Test::Run::Obj. Meaning, it causes
182             Test::Run::CmdLine not to treat STDOUT as if it were a console. In this
183             case, it will not emit more frequent progress reports using carriage
184             returns (C<"\r">s).
185              
186             =item HARNESS_PERL
187              
188             Specifies the C<'Test_Interpreter'> variable of L<Test::Run::Obj>. This allows
189             specifying a different Perl interprter to use besides C<$^X>.
190              
191             =item HARNESS_PERL_SWITCHES
192              
193             Specifies the C<'Switches'> variable of L<Test::Run::Obj>. This allows
194             specifying more switches to the Perl interpreter.
195              
196             =item HARNESS_TIMER
197              
198             This variable triggers the C<'Timer'> option in Test::Run::Obj. What it
199             does is causes the time that took for tests to run to be displayed.
200              
201             =item HARNESS_VERBOSE
202              
203             Triggers the C<'Verbose'> option in Test::Run::Obj. Meaning, it emits
204             the standard output of the test files while they are processed.
205              
206             =back
207              
208             =head1 Internal Functions
209              
210             =head2 my $args_array_ref = $tester->get_backend_args()
211              
212             Calculate and retrieve the arguments for the backend class (that inherits
213             from L<Test::Run::Obj>) as a single array reference. Currently it appends
214             the arguments of get_backend_env_args() to that of get_backend_init_args().
215              
216             =cut
217              
218             sub get_backend_args
219             {
220 4     4 1 21 my $self = shift;
221              
222 4         24 return $self->accum_array(
223             {
224             method => "private_backend_args",
225             }
226             );
227             }
228              
229             =head2 $self->private_backend_args()
230              
231             Calculates the get_backend_args()-specific arguments for this class.
232              
233             =cut
234              
235             sub private_backend_args
236             {
237 4     4 1 1271 my $self = shift;
238              
239 4         26 $self->get_backend_env_args();
240              
241 4         31 my $init_args = $self->get_backend_init_args();
242              
243 4         9 return [@{$self->backend_env_args()}, @$init_args];
  4         153  
244             }
245              
246             =head2 $tester->get_backend_env_args()
247              
248             Calculate the arguments for the backend class, that originated
249             from the environment (%ENV), and puts them in C<$tester->backend_env_args()>
250              
251             =cut
252              
253             sub _get_direct_backend_env_mapping
254             {
255 4     4   10 my $self = shift;
256              
257 4         27 return $self->accum_array(
258             {
259             method => "private_direct_backend_env_mapping",
260             }
261             );
262             }
263              
264             =head2 $self->private_direct_backend_env_mapping()
265              
266             The return value of this method is collected from every class, and adapted
267             to the direct backend environment mapping.
268              
269             =cut
270              
271             sub private_direct_backend_env_mapping
272             {
273 4     4 1 1175 my $self = shift;
274             return [
275 4         84 { 'env' => "HARNESS_FILELEAK_IN_DIR", 'arg' => "Leaked_Dir", },
276             { 'env' => "HARNESS_VERBOSE", 'arg' => "Verbose", },
277             { 'env' => "HARNESS_DEBUG", 'arg' => "Debug", },
278             { 'env' => "COLUMNS", 'arg' => "Columns", },
279             { 'env' => "HARNESS_COLUMNS", 'arg' => "Columns", },
280             { 'env' => "HARNESS_TIMER", 'arg' => "Timer", },
281             { 'env' => "HARNESS_NOTTY", 'arg' => "NoTty", },
282             { 'env' => "HARNESS_PERL", 'arg' => "Test_Interpreter", },
283             { 'env' => "HARNESS_PERL_SWITCHES", 'arg' => "Switches_Env", },
284             ];
285             }
286              
287             sub _get_non_direct_backend_env_mapping
288             {
289 4     4   8 my $self = shift;
290              
291 4         23 return $self->accum_array(
292             {
293             method => "private_non_direct_backend_env_mapping",
294             }
295             );
296             }
297              
298             sub _get_backend_env_mapping
299             {
300 4     4   8 my $self = shift;
301              
302             return
303             [
304 36         144 (map { +{ type => "direct", %$_ } } @{$self->_get_direct_backend_env_mapping()}),
  4         31  
305 4         8 @{$self->_get_non_direct_backend_env_mapping()},
  4         27  
306             ];
307             }
308              
309             sub _handle_backend_env_spec
310             {
311 37     37   58 my ($self, $spec) = @_;
312              
313 37         58 my $type = $spec->{type};
314 37         52 my $env = $spec->{env};
315              
316 37 100       120 if (exists($ENV{$env}))
317             {
318 4         32 my $sub = $self->can("_backend_spec_handler_for_$type");
319              
320 4 50       15 if (! $sub)
321             {
322 0         0 confess "Cannot find type handler for $type!";
323             }
324              
325 4         12 $sub->(
326             $self,
327             $spec,
328             );
329             }
330             }
331              
332             sub _backend_spec_handler_for_direct
333             {
334 3     3   6 my ($self, $spec) = @_;
335              
336 3         6 my $arg = $spec->{arg};
337 3         15 my $env = $spec->{env};
338              
339 3         131 push @{$self->backend_env_args()},
340 3         5 ($arg => $ENV{$env});
341             }
342              
343             sub _backend_spec_handler_for_yamldata
344             {
345 1     1   3 my ($self, $spec) = @_;
346              
347 1         2 my $arg = $spec->{arg};
348 1         8 my $env = $spec->{env};
349              
350 1         37 push @{$self->backend_env_args()},
351 1         2 ($arg => YAML::XS::LoadFile($ENV{$env}));
352             }
353              
354             sub _calc_backend_env_var_map
355             {
356 0     0   0 my ($self, $mapping_string) = @_;
357              
358 0         0 my @assignments = split(/\s*;\s*/, $mapping_string);
359             return
360             +{
361 0 0       0 map { /\A([^=]*)=(.*)\z/ms ? ($1 => $2) : () }
  0         0  
362             @assignments
363             };
364             }
365              
366             sub _backend_spec_handler_for_varmap
367             {
368 0     0   0 my ($self, $spec) = @_;
369              
370 0         0 my $arg = $spec->{arg};
371 0         0 my $env = $spec->{env};
372              
373 0         0 push @{$self->backend_env_args()},
374 0         0 ($arg => $self->_calc_backend_env_var_map($ENV{$env}));
375             }
376              
377             sub get_backend_env_args
378             {
379 4     4 1 9 my $self = shift;
380 4         7 foreach my $spec (@{$self->_get_backend_env_mapping()})
  4         27  
381             {
382 37         1126 $self->_handle_backend_env_spec($spec);
383             }
384              
385 4         749 return 0;
386             }
387              
388             =head2 my $args_array_ref = $tester->get_backend_init_args()
389              
390             Calculate and return the arguments for the backend class, that originated
391             from the arguments passed to the (front-end) object from its constructor.
392              
393             =cut
394              
395             sub get_backend_init_args
396             {
397 4     4 1 9 my $self = shift;
398 4         7 my @args;
399 4 50       178 if (defined($self->backend_params()))
400             {
401 0         0 push @args, (%{$self->backend_params()});
  0         0  
402             }
403 4         12 return \@args;
404             }
405              
406             sub _calc_plugins_for_ISA
407             {
408 3     3   6 my $self = shift;
409             return
410             [
411 3         13 map { $self->_calc_single_plugin_for_ISA($_) }
412 3         6 @{$self->backend_plugins()}
  3         118  
413             ];
414             }
415              
416             sub _calc_single_plugin_for_ISA
417             {
418 3     3   5 my $self = shift;
419 3         5 my $p = shift;
420 3         12 return "Test::Run::Plugin::$p";
421             }
422              
423             =head2 $self->private_backend_plugins()
424              
425             Calculates the backend plugins specific for this class. They will be collected
426             to formulate a list of plugins that will be C<add_to_backend_plugins()>'ed.
427              
428             =cut
429              
430             sub _get_backend_plugins_accumulation
431             {
432 6     6   12 my $self = shift;
433              
434 6         12 return [reverse(@{$self->accum_array(
  6         71  
435             {
436             method => "private_backend_plugins",
437             }
438             )})];
439             }
440              
441             sub _collect_backend_plugins
442             {
443 6     6   14 my $self = shift;
444              
445 6         49 foreach my $plug (@{$self->_get_backend_plugins_accumulation()})
  6         38  
446             {
447 4         807 $self->add_to_backend_plugins($plug);
448             }
449              
450 6         913 return;
451             }
452              
453             =head2 $self->add_to_backend_plugins($plugin)
454              
455             Appends a plugin to the plugins list. Useful in front-end plug-ins.
456              
457             =cut
458              
459             sub add_to_backend_plugins
460             {
461 7     7 1 43 my $self = shift;
462 7         14 my $plugin = shift;
463 7         9 unshift @{$self->backend_plugins()}, $plugin;
  7         281  
464             }
465              
466             =head1 AUTHORS
467              
468             Shlomi Fish, L<http://www.shlomifish.org/> .
469              
470             =head1 BUGS
471              
472             Please report any bugs or feature requests to
473             C<bug-test-run-cmdline@rt.cpan.org>, or through the web interface at
474             L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-Run-CmdLine>.
475             I will be notified, and then you'll automatically be notified of progress on
476             your bug as I make changes.
477              
478             =head1 SUPPORT
479              
480             You can find documentation for this module with the perldoc command.
481              
482             perldoc Test::Run::CmdLine
483              
484             You can also look for information at:
485              
486             =over 4
487              
488             =item * AnnoCPAN: Annotated CPAN documentation
489              
490             L<http://annocpan.org/dist/Test::Run::CmdLine>
491              
492             =item * CPAN Ratings
493              
494             L<http://cpanratings.perl.org/d/Test::Run::CmdLine>
495              
496             =item * RT: CPAN's request tracker
497              
498             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Test::Run::CmdLine>
499              
500             =item * Search CPAN
501              
502             L<http://search.cpan.org/dist/Test::Run::CmdLine/>
503              
504             =back
505              
506             =head1 SOURCE AVAILABILITY
507              
508             The latest source of Test::Run::CmdLine is available from the Test::Run
509             BerliOS Subversion repository:
510              
511             L<https://svn.berlios.de/svnroot/repos/web-cpan/Test-Harness-NG/>
512              
513             =head1 ACKNOWLEDGEMENTS
514              
515             =head1 COPYRIGHT & LICENSE
516              
517             Copyright 2005 Shlomi Fish, all rights reserved.
518              
519             This program is released under the MIT X11 License.
520              
521             =cut
522              
523             1; # End of Test::Run::CmdLine