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   69816 use warnings;
  7         13  
  7         227  
4 7     7   36 use strict;
  7         14  
  7         123  
5              
6 7     7   135 use 5.008;
  7         23  
7              
8 7     7   36 use Carp;
  7         13  
  7         472  
9 7     7   550 use UNIVERSAL::require;
  7         1278  
  7         54  
10 7     7   3257 use YAML::XS ();
  7         20078  
  7         161  
11              
12 7     7   2855 use Test::Run::Base;
  7         2579188  
  7         106  
13              
14 7     7   4145 use Test::Run::Iface;
  7         811  
  7         82  
15 7     7   2680 use Test::Run::Obj;
  7         4481134  
  7         137  
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   379 use vars (qw($VERSION));
  7         16  
  7         440  
24              
25             $VERSION = '0.0132';
26              
27 7     7   48 use Moose;
  7         15  
  7         47  
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 8886 my $self = shift;
60              
61 6         49 $self->_collect_backend_plugins();
62              
63 6         19 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 40 my $self = shift;
115 3         112 my $backend_class = $self->backend_class();
116 3         40 $backend_class->require();
117 3 50       106 if ($@)
118             {
119 0         0 die $@;
120             }
121 3         8 foreach my $plugin (@{$self->_calc_plugins_for_ISA()})
  3         17  
122             {
123 3         19 $plugin->require();
124 3 50       547 if ($@)
125             {
126 0         0 die $@;
127             }
128             {
129 7     7   50024 no strict 'refs';
  7         39  
  7         539  
  3         6  
130 3         5 push @{"${backend_class}::ISA"}, $plugin;
  3         54  
131             }
132             }
133              
134             # Finally - put Test::Run::Obj there.
135             {
136 7     7   53 no strict 'refs';
  7         16  
  7         8754  
  3         19  
137 3         7 push @{"${backend_class}::ISA"}, "Test::Run::Obj";
  3         74  
138             }
139              
140             my $backend = $backend_class->new(
141             {
142             'test_files' => $self->test_files(),
143 3         138 @{$self->get_backend_args()},
  3         22  
144             },
145             );
146              
147 3         50842 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 23 my $self = shift;
221              
222 4         20 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 1523 my $self = shift;
238              
239 4         30 $self->get_backend_env_args();
240              
241 4         28 my $init_args = $self->get_backend_init_args();
242              
243 4         9 return [@{$self->backend_env_args()}, @$init_args];
  4         118  
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   11 my $self = shift;
256              
257 4         36 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 1406 my $self = shift;
274             return [
275 4         86 { '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   10 my $self = shift;
290              
291 4         20 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   9 my $self = shift;
301              
302             return
303             [
304 36         133 (map { +{ type => "direct", %$_ } } @{$self->_get_direct_backend_env_mapping()}),
  4         23  
305 4         9 @{$self->_get_non_direct_backend_env_mapping()},
  4         27  
306             ];
307             }
308              
309             sub _handle_backend_env_spec
310             {
311 37     37   88 my ($self, $spec) = @_;
312              
313 37         60 my $type = $spec->{type};
314 37         47 my $env = $spec->{env};
315              
316 37 100       93 if (exists($ENV{$env}))
317             {
318 4         32 my $sub = $self->can("_backend_spec_handler_for_$type");
319              
320 4 50       16 if (! $sub)
321             {
322 0         0 confess "Cannot find type handler for $type!";
323             }
324              
325 4         13 $sub->(
326             $self,
327             $spec,
328             );
329             }
330             }
331              
332             sub _backend_spec_handler_for_direct
333             {
334 3     3   17 my ($self, $spec) = @_;
335              
336 3         10 my $arg = $spec->{arg};
337 3         5 my $env = $spec->{env};
338              
339 3         124 push @{$self->backend_env_args()},
340 3         6 ($arg => $ENV{$env});
341             }
342              
343             sub _backend_spec_handler_for_yamldata
344             {
345 1     1   2 my ($self, $spec) = @_;
346              
347 1         3 my $arg = $spec->{arg};
348 1         2 my $env = $spec->{env};
349              
350 1         29 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 15 my $self = shift;
380 4         11 foreach my $spec (@{$self->_get_backend_env_mapping()})
  4         24  
381             {
382 37         1240 $self->_handle_backend_env_spec($spec);
383             }
384              
385 4         200 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 10 my $self = shift;
398 4         8 my @args;
399 4 50       164 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   7 my $self = shift;
409             return
410             [
411 3         11 map { $self->_calc_single_plugin_for_ISA($_) }
412 3         6 @{$self->backend_plugins()}
  3         99  
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         10 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   15 my $self = shift;
433              
434 6         12 return [reverse(@{$self->accum_array(
  6         50  
435             {
436             method => "private_backend_plugins",
437             }
438             )})];
439             }
440              
441             sub _collect_backend_plugins
442             {
443 6     6   13 my $self = shift;
444              
445 6         14 foreach my $plug (@{$self->_get_backend_plugins_accumulation()})
  6         32  
446             {
447 4         867 $self->add_to_backend_plugins($plug);
448             }
449              
450 6         1024 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 44 my $self = shift;
462 7         12 my $plugin = shift;
463 7         13 unshift @{$self->backend_plugins()}, $plugin;
  7         217  
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 * CPAN Ratings
489              
490             L<http://cpanratings.perl.org/d/Test::Run::CmdLine>
491              
492             =item * RT: CPAN's request tracker
493              
494             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Test::Run::CmdLine>
495              
496             =item * Search CPAN
497              
498             L<http://search.cpan.org/dist/Test::Run::CmdLine/>
499              
500             =back
501              
502             =head1 SOURCE AVAILABILITY
503              
504             The latest source of Test::Run::CmdLine is available from the Test::Run
505             BerliOS Subversion repository:
506              
507             L<https://svn.berlios.de/svnroot/repos/web-cpan/Test-Harness-NG/>
508              
509             =head1 ACKNOWLEDGEMENTS
510              
511             =head1 COPYRIGHT & LICENSE
512              
513             Copyright 2005 Shlomi Fish, all rights reserved.
514              
515             This program is released under the MIT X11 License.
516              
517             =cut
518              
519             1; # End of Test::Run::CmdLine