File Coverage

blib/lib/Test/Command.pm
Criterion Covered Total %
statement 258 265 97.3
branch 58 74 78.3
condition 11 12 91.6
subroutine 45 45 100.0
pod 34 34 100.0
total 406 430 94.4


line stmt bran cond sub pod time code
1             package Test::Command;
2              
3 7     7   81549 use warnings;
  7         298  
  7         507  
4 7     7   42 use strict;
  7         13  
  7         524  
5              
6 7     7   41 use Carp qw/ confess /;
  7         20  
  7         737  
7 7     7   14559 use File::Temp qw/ tempfile /;
  7         224288  
  7         563  
8              
9 7     7   66 use base 'Test::Builder::Module';
  7         14  
  7         18827  
10              
11             our @EXPORT = qw(
12             exit_value
13             exit_is_num
14             exit_isnt_num
15             exit_cmp_ok
16             exit_is_defined
17             exit_is_undef
18              
19             signal_value
20             signal_is_num
21             signal_isnt_num
22             signal_cmp_ok
23             signal_is_defined
24             signal_is_undef
25              
26             stdout_value
27             stdout_file
28             stdout_is_eq
29             stdout_isnt_eq
30             stdout_is_num
31             stdout_isnt_num
32             stdout_like
33             stdout_unlike
34             stdout_cmp_ok
35             stdout_is_file
36              
37             stderr_value
38             stderr_file
39             stderr_is_eq
40             stderr_isnt_eq
41             stderr_is_num
42             stderr_isnt_num
43             stderr_like
44             stderr_unlike
45             stderr_cmp_ok
46             stderr_is_file
47              
48             );
49            
50             =head1 NAME
51              
52             Test::Command - Test routines for external commands
53              
54             =head1 VERSION
55              
56             Version 0.11
57              
58             =cut
59              
60             our $VERSION = '0.11';
61              
62             =head1 SYNOPSIS
63              
64             Test the exit status, signal, STDOUT or STDERR of an external command.
65              
66             use Test::Command tests => 11;
67              
68             ## testing exit status
69              
70             my $cmd = 'true';
71              
72             exit_is_num($cmd, 0);
73             exit_cmp_ok($cmd, '<', 10);
74              
75             $cmd = 'false';
76              
77             exit_isnt_num($cmd, 0);
78              
79             ## testing terminating signal
80              
81             $cmd = 'true';
82              
83             signal_is_num($cmd, 0);
84              
85             ## testing STDOUT
86              
87             $cmd = [qw/ echo out /]; ## run as "system @$cmd"
88             my $file_exp = 'echo_stdout.exp';
89              
90             stdout_is_eq($cmd, "out\n");
91             stdout_isnt_eq($cmd, "out");
92             stdout_is_file($cmd, $file_exp);
93              
94             ## testing STDERR
95              
96             $cmd = 'echo err >&2';
97              
98             stderr_like($cmd, /err/);
99             stderr_unlike($cmd, /rre/);
100             stderr_cmp_ok($cmd, 'eq', "err\n");
101              
102             ## run-once-test-many-OO-style
103             ## the first test lazily runs command
104             ## the second test uses cached results
105              
106             my $echo_test = Test::Command->new( cmd => 'echo out' );
107              
108             $echo_test->exit_is_num(0);
109             $echo_test->signal_is_num(0);
110             $echo_test->stdout_is_eq("out\n");
111              
112             ## force a re-run of the command
113              
114             $echo_test->run;
115              
116             ## arbitrary results inspection
117              
118             is( $echo_test->exit_value, 0, 'echo exit' );
119             is( $echo_test->signal_value, undef, 'echo signal' );
120             is( $echo_test->stdout_value, "out\n", 'echo stdout' );
121             is( $echo_test->stderr_value, '', 'echo stderr' );
122             is( -s $echo_test->stdout_file, 4, 'echo stdout file size' );
123             is( -s $echo_test->stderr_file, 0, 'echo stderr file size' );
124              
125             =head1 DESCRIPTION
126              
127             C intends to bridge the gap between the well tested functions and
128             objects you choose and their usage in your programs. By examining the exit
129             status, terminating signal, STDOUT and STDERR of your program you can determine
130             if it is behaving as expected.
131              
132             This includes testing the various combinations and permutations of options and
133             arguments as well as the interactions between the various functions and objects
134             that make up your program.
135              
136             The various test functions below can accept either a command string or an
137             array reference for the first argument. If the command is expressed as a
138             string it is passed to C as is. If the command is expressed as an
139             array reference it is dereferenced and passed to C as a list. See
140             'C' for how these may differ.
141              
142             The final argument for the test functions, C<$name>, is optional. By default the
143             C<$name> is a concatenation of the test function name, the command string and
144             the expected value. This construction is generally sufficient for identifying a
145             failing test, but you may always specify your own C<$name> if desired.
146              
147             Any of the test functions can be used as instance methods on a C
148             object. This is done by dropping the initial C<$cmd> argument and instead using
149             arrow notation.
150              
151             All of the following C calls are equivalent.
152              
153             exit_is_num('true', 0);
154             exit_is_num('true', 0, 'exit_is_num: true, 0');
155             exit_is_num(['true'], 0);
156             exit_is_num(['true'], 0, 'exit_is_num: true, 0');
157              
158             my $cmd = Test::Command->new( cmd => 'true' );
159              
160             exit_is_num($cmd, 0);
161             exit_is_num($cmd, 0, 'exit_is_num: true, 0');
162             $cmd->exit_is_num(0);
163             $cmd->exit_is_num(0, 'exit_is_num: true, 0');
164              
165             $cmd = Test::Command->new( cmd => ['true'] );
166              
167             exit_is_num($cmd, 0);
168             exit_is_num($cmd, 0, 'exit_is_num: true, 0');
169             $cmd->exit_is_num(0);
170             $cmd->exit_is_num(0, 'exit_is_num: true, 0');
171              
172             =head1 EXPORT
173              
174             All of the test functions mentioned below are exported by default.
175              
176             =head1 METHODS
177              
178             =head2 new
179              
180             my $test_cmd_obj = Test::Command->new( cmd => $cmd )
181              
182             This constructor creates and returns a C object. Use this to test
183             multiple aspects of a single command execution while avoiding repeatedly running
184             commands which are slow or resource intensive.
185              
186             The C parameter can accept either a string or an array reference for its
187             value. The value is dereferenced if necessary and passed directly to the
188             C builtin.
189              
190             =cut
191              
192             sub new
193             {
194 3     3 1 15961 my ($class, @args) = @_;
195              
196 3         70 my $self = bless { @args }, $class;
197              
198 3         22 return $self;
199              
200             }
201              
202             =head2 run
203              
204             $test_cmd_obj->run;
205              
206             This instance method forces the execution of the command specified by the
207             invocant.
208              
209             You only need to call this when you wish to re-run a command since the first
210             test method invoked will lazily execute the command if necessary. However, if
211             the state of your inputs has changed and you wish to re-run the command, you may
212             do so by invoking this method at any point between your tests.
213              
214             =cut
215              
216             sub run
217             {
218 3     3 1 3238 my ($self) = @_;
219              
220 3         52 my $run_info = _run_cmd( $self->{'cmd'} );
221              
222 3         30 $self->{'result'}{'exit_status'} = $run_info->{'exit_status'};
223 3         10 $self->{'result'}{'term_signal'} = $run_info->{'term_signal'};
224 3         13 $self->{'result'}{'stdout_file'} = $run_info->{'stdout_file'};
225 3         25 $self->{'result'}{'stderr_file'} = $run_info->{'stderr_file'};
226              
227 3         48 return $self;
228              
229             }
230              
231             =head1 FUNCTIONS
232              
233             =cut
234              
235             ## private helper functions
236              
237             sub _slurp
238             {
239 51     51   5101 my ($file_name) = @_;
240 51 100       343 defined $file_name or confess '$file_name is undefined';
241 50 100       8660 open my $fh, '<', $file_name or confess "$file_name: $!";
242 49         88 my $text = do { local $/ = undef; <$fh> };
  49         800  
  49         4064  
243 49 50       875 close $fh or confess "failed to close $file_name: $!";
244 49         313 return $text;
245             }
246              
247             sub _diff_column
248             {
249 11     11   3102 my ($line_1, $line_2) = @_;
250              
251 11         13 my $diff_column;
252              
253 11         22 my $defined_args = grep defined($_), $line_1, $line_2;
254              
255 11 100       59 if (1 == $defined_args)
    100          
256             {
257 4         7 $diff_column = 1;
258             }
259             elsif (2 == $defined_args)
260             {
261              
262 6         14 my $max_length =
263 6         29 ( sort { $b <=> $a } map length($_), $line_1, $line_2 )[0];
264              
265 6         13 for my $position ( 1 .. $max_length )
266             {
267              
268 25         29 my $char_line_1 = substr $line_1, $position - 1, 1;
269 25         25 my $char_line_2 = substr $line_2, $position - 1, 1;
270              
271 25 100       44 if ($char_line_1 ne $char_line_2)
272             {
273 5         6 $diff_column = $position;
274 5         7 last;
275             }
276              
277             }
278              
279             }
280              
281 11         21 return $diff_column;
282              
283             }
284              
285             sub _compare_files
286             {
287 13     13   6079 my ($got_file, $exp_file) = @_;
288              
289 13 100       426 defined $got_file or confess '$got_file is undefined';
290 11 100       210 defined $exp_file or confess '$exp_file is undefined';
291              
292 10 100       1030 open my $got_fh, '<', $got_file or confess "$got_file: $!";
293 9 100       621 open my $exp_fh, '<', $exp_file or confess "$exp_file: $!";
294              
295 8         26 my $ok = 1;
296 8         18 my $diff_line;
297             my $diff_column;
298 0         0 my $got_line;
299 0         0 my $exp_line;
300 0         0 my $col_mark;
301              
302 20         356 CHECK_LINE:
303             {
304 8         13 $got_line = <$got_fh>;
305 20         225 $exp_line = <$exp_fh>;
306              
307 20 100 66     91 last CHECK_LINE if ! defined $got_line &&
308             ! defined $exp_line;
309              
310 15         28 $diff_line++;
311              
312 15   100     163 $ok = defined $got_line &&
313             defined $exp_line &&
314             $got_line eq $exp_line;
315              
316 15 100       44 if (! $ok)
317             {
318 3         10 $diff_column = _diff_column($got_line, $exp_line);
319 3         8 $col_mark = ' ' x ( $diff_column - 1 );
320 3         5 $col_mark .= '^';
321 3         4 last CHECK_LINE;
322             }
323              
324 12         27 redo CHECK_LINE;
325              
326             };
327              
328 8 50       126 close $got_fh or confess "failed to close 'got' handle: $!";
329 8 50       584 close $exp_fh or confess "failed to close 'exp' handle: $!";
330              
331 8         63 return $ok, $diff_line, $got_line, $exp_line, $col_mark;
332             }
333              
334             sub _build_name
335             {
336 71     71   3747 my ($name, $cmd, @args) = @_;
337              
338 71 100       369 if (defined $name)
339             {
340 2         7 return $name;
341             }
342              
343 69 100       578 defined $cmd or confess '$cmd is undefined';
344              
345 68 100 100     1079 if ( ref $cmd && UNIVERSAL::isa($cmd, 'Test::Command') )
346             {
347 26         70 $cmd = $cmd->{'cmd'};
348             }
349              
350 68 100       279 if (ref $cmd eq 'ARRAY')
351             {
352 12         237 $cmd = join ' ', @{ $cmd };
  12         88  
353             }
354              
355             ## remove any leading package information from the subroutine name
356 68         3030 (my $test_sub = (caller 1)[3]) =~ s/.*:://;
357 68         1191 return "$test_sub: " . join ', ', $cmd, @args;
358             }
359              
360             sub _get_result
361             {
362 80     80   699 my ($cmd) = @_;
363              
364 80 100       601 defined $cmd or confess '$cmd is undefined';
365              
366 79 100 100     922 if ( ref $cmd && UNIVERSAL::isa($cmd, 'Test::Command') )
367             {
368              
369             ## run the command if needed
370 32 100       160 if ( ! $cmd->{'result'} )
371             {
372 1         6 $cmd->run;
373             }
374              
375 32         97 return $cmd->{'result'};
376             }
377             else
378             {
379 47         349 return _run_cmd(@_);
380             }
381              
382             }
383              
384             sub _run_cmd
385             {
386 51     51   640 my ($cmd) = @_;
387              
388             ## do as much as we can before redirecting STDOUT and STDERR, we want
389             ## to avoid getting our peanut butter in their chocolate
390              
391 51 100       680 defined $cmd or confess '$cmd is undefined';
392              
393 50 100       206 if ( ! ref $cmd )
394             {
395 40         153 $cmd = [ $cmd ];
396             }
397              
398             ## save copies of STDOUT and STDERR
399 50 50       2113 open my $saved_stdout, '>&STDOUT' or confess 'Cannot duplicate STDOUT';
400 50 50       1031 open my $saved_stderr, '>&STDERR' or confess 'Cannot duplicate STDERR';
401              
402             ## create tempfiles for capturing STDOUT and STDERR
403 50         1283 my ($temp_stdout_fh, $temp_stdout_file) = tempfile(UNLINK => 1);
404 50         110722 my ($temp_stderr_fh, $temp_stderr_file) = tempfile(UNLINK => 1);
405              
406             ## close and reopen STDOUT and STDERR to temp files
407 50 50       41940 close STDOUT or confess "failed to close STDOUT: $!";
408 50 50       450 close STDERR or confess "failed to close STDERR: $!";
409 50 50       1650 open STDOUT, '>&' . fileno $temp_stdout_fh or confess 'Cannot duplicate temporary STDOUT';
410 50 50       1327 open STDERR, '>&' . fileno $temp_stderr_fh or confess 'Cannot duplicate temporary STDERR';
411              
412             ## run the command
413 50         183 system(@{ $cmd });
  50         868892  
414            
415 50 50       3283 my $system_return = defined ${^CHILD_ERROR_NATIVE} ? ${^CHILD_ERROR_NATIVE} : $?;
416            
417 50         155 my $exit_status;
418             my $term_signal;
419              
420 50         199 my $wait_status = $system_return & 127;
421 50 100       665 if ($wait_status)
422             {
423 6         52 $exit_status = undef;
424 6         24 $term_signal = $wait_status;
425             }
426             else
427             {
428 44         191 $exit_status = $system_return >> 8;
429 44         147 $term_signal = undef;
430             }
431              
432             ## close and restore STDOUT and STDERR to original handles
433 50 50       1712 close STDOUT or confess "failed to close STDOUT: $!";
434 50 50       688 close STDERR or confess "failed to close STDERR: $!";
435 50 50       2896 open STDOUT, '>&' . fileno $saved_stdout or confess 'Cannot restore STDOUT';
436 50 50       1948 open STDERR, '>&' . fileno $saved_stderr or confess 'Cannot restore STDERR';
437              
438 50         5520 return { exit_status => $exit_status,
439             term_signal => $term_signal,
440             stdout_file => $temp_stdout_file,
441             stderr_file => $temp_stderr_file };
442              
443             }
444              
445             =head2 Testing Exit Status
446              
447             The test routines below compare against the exit status of the executed
448             command right shifted by 8 (that is, C<$? EE 8>).
449              
450             =head3 exit_value
451              
452             exit_value($cmd)
453              
454             Return the exit status of the command. Useful for performing arbitrary tests
455             not covered by this module.
456              
457             =cut
458              
459             sub exit_value
460             {
461 3     3 1 4992 my ($cmd) = @_;
462              
463 3         39 my $result = _get_result($cmd);
464            
465 3         103 return $result->{'exit_status'};
466             }
467              
468             =head3 exit_is_num
469              
470             exit_is_num($cmd, $exp_num, $name)
471              
472             If the exit status of the command is numerically equal to the expected number,
473             this passes. Otherwise it fails.
474              
475             =cut
476              
477             sub exit_is_num
478             {
479 5     5 1 1328 my ($cmd, $exp, $name) = @_;
480              
481 5         35 my $result = _get_result($cmd);
482            
483 5         96 $name = _build_name($name, @_);
484              
485 5         146 return __PACKAGE__->builder->is_num($result->{'exit_status'}, $exp, $name);
486             }
487              
488             =head3 exit_isnt_num
489              
490             exit_isnt_num($cmd, $unexp_num, $name)
491              
492             If the exit status of the command is B numerically equal to the given
493             number, this passes. Otherwise it fails.
494              
495             =cut
496              
497             sub exit_isnt_num
498             {
499 3     3 1 2089 my ($cmd, $not_exp, $name) = @_;
500              
501 3         13 my $result = _get_result($cmd);
502              
503 3         48 $name = _build_name($name, @_);
504              
505 3         44 return __PACKAGE__->builder->isnt_num($result->{'exit_status'}, $not_exp, $name);
506             }
507              
508             =head3 exit_cmp_ok
509              
510             exit_cmp_ok($cmd, $op, $operand, $name)
511              
512             If the exit status of the command is compared with the given operand using
513             the given operator, and that operation returns true, this passes. Otherwise
514             it fails.
515              
516             =cut
517              
518             sub exit_cmp_ok
519             {
520 3     3 1 1594 my ($cmd, $op, $exp, $name) = @_;
521              
522 3         16 my $result = _get_result($cmd);
523              
524 3         35 $name = _build_name($name, @_);
525              
526 3         48 return __PACKAGE__->builder->cmp_ok($result->{'exit_status'}, $op, $exp, $name);
527             }
528              
529             =head3 exit_is_defined
530              
531             exit_is_defined($cmd, $name)
532              
533             If the exit status of the command is defined, this passes. Otherwise it
534             fails. A defined exit status indicates that the command exited normally
535             by calling exit() or running off the end of the program.
536              
537             =cut
538              
539             sub exit_is_defined
540             {
541 1     1 1 12 my ($cmd, $op, $exp, $name) = @_;
542              
543 1         35 my $result = _get_result($cmd);
544              
545 1         21 $name = _build_name($name, @_);
546              
547 1         38 return __PACKAGE__->builder->ok(defined $result->{'exit_status'}, $name);
548             }
549              
550             =head3 exit_is_undef
551              
552             exit_is_undef($cmd, $name)
553              
554             If the exit status of the command is not defined, this passes. Otherwise it
555             fails. An undefined exit status indicates that the command likely exited
556             due to a signal.
557              
558             =cut
559              
560             sub exit_is_undef
561             {
562 1     1 1 6 my ($cmd, $op, $exp, $name) = @_;
563              
564 1         10 my $result = _get_result($cmd);
565              
566 1         16 $name = _build_name($name, @_);
567              
568 1         32 return __PACKAGE__->builder->ok(! defined $result->{'exit_status'}, $name);
569             }
570              
571             =head2 Testing Terminating Signal
572              
573             The test routines below compare against the lower 8 bits of the exit status
574             of the executed command.
575              
576             =head3 signal_value
577              
578             signal_value($cmd)
579              
580             Return the signal code of the command. Useful for performing arbitrary tests
581             not covered by this module.
582              
583             =cut
584              
585             sub signal_value
586             {
587 2     2 1 1870 my ($cmd) = @_;
588              
589 2         18 my $result = _get_result($cmd);
590            
591 2         56 return $result->{'term_signal'};
592             }
593              
594             =head3 signal_is_num
595              
596             signal_is_num($cmd, $exp_num, $name)
597              
598             If the terminating signal of the command is numerically equal to the expected number,
599             this passes. Otherwise it fails.
600              
601             =cut
602              
603             sub signal_is_num
604             {
605 1     1 1 36 my ($cmd, $exp, $name) = @_;
606              
607 1         14 my $result = _get_result($cmd);
608            
609 1         23 $name = _build_name($name, @_);
610              
611 1         51 return __PACKAGE__->builder->is_num($result->{'term_signal'}, $exp, $name);
612             }
613              
614             =head3 signal_isnt_num
615              
616             signal_isnt_num($cmd, $unexp_num, $name)
617              
618             If the terminating signal of the command is B numerically equal to the given
619             number, this passes. Otherwise it fails.
620              
621             =cut
622              
623             sub signal_isnt_num
624             {
625 1     1 1 3 my ($cmd, $not_exp, $name) = @_;
626              
627 1         9 my $result = _get_result($cmd);
628              
629 1         20 $name = _build_name($name, @_);
630              
631 1         37 return __PACKAGE__->builder->isnt_num($result->{'term_signal'}, $not_exp, $name);
632             }
633              
634             =head3 signal_cmp_ok
635              
636             signal_cmp_ok($cmd, $op, $operand, $name)
637              
638             If the terminating signal of the command is compared with the given operand
639             using the given operator, and that operation returns true, this passes. Otherwise
640             it fails.
641              
642             =cut
643              
644             sub signal_cmp_ok
645             {
646 1     1 1 4 my ($cmd, $op, $exp, $name) = @_;
647              
648 1         10 my $result = _get_result($cmd);
649              
650 1         27 $name = _build_name($name, @_);
651              
652 1         39 return __PACKAGE__->builder->cmp_ok($result->{'term_signal'}, $op, $exp, $name);
653             }
654              
655             =head3 signal_is_defined
656              
657             signal_is_defined($cmd, $name)
658              
659             If the terminating signal of the command is defined, this passes. Otherwise it
660             fails. A defined signal indicates that the command likely exited due to a
661             signal.
662              
663             =cut
664              
665             sub signal_is_defined
666             {
667 1     1 1 11 my ($cmd, $op, $exp, $name) = @_;
668              
669 1         111 my $result = _get_result($cmd);
670              
671 1         31 $name = _build_name($name, @_);
672              
673 1         66 return __PACKAGE__->builder->ok(defined $result->{'term_signal'}, $name);
674             }
675              
676             =head3 signal_is_undef
677              
678             signal_is_undef($cmd, $name)
679              
680             If the terminating signal of the command is not defined, this passes.
681             Otherwise it fails. An undefined signal indicates that the command exited
682             normally by calling exit() or running off the end of the program.
683              
684             =cut
685              
686             sub signal_is_undef
687             {
688 5     5 1 16292 my ($cmd, $name) = @_;
689              
690 5         42 my $result = _get_result($cmd);
691              
692 5         62 $name = _build_name($name, @_);
693              
694 5         131 return __PACKAGE__->builder->ok(! defined $result->{'term_signal'}, $name);
695             }
696              
697             =head2 Testing STDOUT
698              
699             Except where specified, the test routines below treat STDOUT as a single slurped
700             string.
701              
702             =head3 stdout_value
703              
704             stdout_value($cmd)
705              
706             Return the STDOUT of the command. Useful for performing arbitrary tests
707             not covered by this module.
708              
709             =cut
710              
711             sub stdout_value
712             {
713 2     2 1 22077 my ($cmd) = @_;
714              
715 2         37 my $result = _get_result($cmd);
716 2         30 my $stdout_text = _slurp($result->{'stdout_file'});
717            
718 2         103 return $stdout_text;
719             }
720              
721             =head3 stdout_file
722              
723             stdout_file($cmd)
724              
725             Return the file name containing the STDOUT of the command. Useful for
726             performing arbitrary tests not covered by this module.
727              
728             =cut
729              
730             sub stdout_file
731             {
732 2     2 1 7 my ($cmd) = @_;
733              
734 2         11 my $result = _get_result($cmd);
735              
736 2         37 return $result->{'stdout_file'};
737             }
738              
739             =head3 stdout_is_eq
740              
741             stdout_is_eq($cmd, $exp_string, $name)
742              
743             If the STDOUT of the command is equal (compared using C) to the expected
744             string, then this passes. Otherwise it fails.
745              
746             =cut
747              
748             sub stdout_is_eq
749             {
750 6     6 1 1246 my ($cmd, $exp, $name) = @_;
751              
752 6         36 my $result = _get_result($cmd);
753              
754 6         89 my $stdout_text = _slurp($result->{'stdout_file'});
755              
756 6         158 $name = _build_name($name, @_);
757              
758 6         169 return __PACKAGE__->builder->is_eq($stdout_text, $exp, $name);
759             }
760              
761             =head3 stdout_isnt_eq
762              
763             stdout_isnt_eq($cmd, $unexp_string, $name)
764              
765             If the STDOUT of the command is B equal (compared using C) to the
766             given string, this passes. Otherwise it fails.
767              
768             =cut
769              
770             sub stdout_isnt_eq
771             {
772 2     2 1 15 my ($cmd, $not_exp, $name) = @_;
773              
774 2         10 my $result = _get_result($cmd);
775              
776 2         30 my $stdout_text = _slurp($result->{'stdout_file'});
777              
778 2         19 $name = _build_name($name, @_);
779              
780 2         41 return __PACKAGE__->builder->isnt_eq($stdout_text, $not_exp, $name);
781             }
782              
783             =head3 stdout_is_num
784              
785             stdout_is_num($cmd, $exp_num, $name)
786              
787             If the STDOUT of the command is equal (compared using C<==>) to the expected
788             number, then this passes. Otherwise it fails.
789              
790             =cut
791              
792             sub stdout_is_num
793             {
794 2     2 1 10 my ($cmd, $exp, $name) = @_;
795              
796 2         10 my $result = _get_result($cmd);
797              
798 2         32 my $stdout_text = _slurp($result->{'stdout_file'});
799              
800 2         19 $name = _build_name($name, @_);
801              
802 2         41 return __PACKAGE__->builder->is_num($stdout_text, $exp, $name);
803             }
804              
805             =head3 stdout_isnt_num
806              
807             stdout_isnt_num($cmd, $unexp_num, $name)
808              
809             If the STDOUT of the command is B equal (compared using C<==>) to the
810             given number, this passes. Otherwise it fails.
811              
812             =cut
813              
814             sub stdout_isnt_num
815             {
816 2     2 1 7 my ($cmd, $not_exp, $name) = @_;
817              
818 2         11 my $result = _get_result($cmd);
819              
820 2         28 my $stdout_text = _slurp($result->{'stdout_file'});
821              
822 2         17 $name = _build_name($name, @_);
823              
824 2         110 return __PACKAGE__->builder->isnt_num($stdout_text, $not_exp, $name);
825             }
826              
827             =head3 stdout_like
828              
829             stdout_like($cmd, $exp_regex, $name)
830              
831             If the STDOUT of the command matches the expected regular expression,
832             this passes. Otherwise it fails.
833              
834             =cut
835              
836             sub stdout_like
837             {
838 2     2 1 1101 my ($cmd, $exp, $name) = @_;
839              
840 2         10 my $result = _get_result($cmd);
841              
842 2         33 my $stdout_text = _slurp($result->{'stdout_file'});
843              
844 2         21 $name = _build_name($name, @_);
845              
846 2         44 return __PACKAGE__->builder->like($stdout_text, $exp, $name);
847             }
848              
849             =head3 stdout_unlike
850              
851             stdout_unlike($cmd, $unexp_regex, $name)
852              
853             If the STDOUT of the command does B match the given regular
854             expression, this passes. Otherwise it fails.
855              
856             =cut
857              
858             sub stdout_unlike
859             {
860 2     2 1 7021 my ($cmd, $exp, $name) = @_;
861              
862 2         160 my $result = _get_result($cmd);
863              
864 2         28 my $stdout_text = _slurp($result->{'stdout_file'});
865              
866 2         24 $name = _build_name($name, @_);
867              
868 2         41 return __PACKAGE__->builder->unlike($stdout_text, $exp, $name);
869             }
870              
871             =head3 stdout_cmp_ok
872              
873             stdout_cmp_ok($cmd, $op, $operand, $name)
874              
875             If the STDOUT of the command is compared with the given operand using
876             the given operator, and that operation returns true, this passes. Otherwise
877             it fails.
878              
879             =cut
880              
881             sub stdout_cmp_ok
882             {
883 4     4 1 1415 my ($cmd, $op, $exp, $name) = @_;
884              
885 4         97 my $result = _get_result($cmd);
886              
887 4         60 my $stdout_text = _slurp($result->{'stdout_file'});
888              
889 4         45 $name = _build_name($name, @_);
890              
891 4         481 return __PACKAGE__->builder->cmp_ok($stdout_text, $op, $exp, $name);
892             }
893              
894             =head3 stdout_is_file
895              
896             stdout_is_file($cmd, $exp_file, $name)
897              
898             If the STDOUT of the command is equal (compared using C) to the contents of
899             the given file, then this passes. Otherwise it fails. Note that this comparison
900             is performed line by line, rather than slurping the entire file.
901              
902             =cut
903              
904             sub stdout_is_file
905             {
906 2     2 1 1356 my ($cmd, $exp_file, $name) = @_;
907              
908 2         16 my $result = _get_result($cmd);
909              
910 2         184 my ($ok, $diff_start, $got_line, $exp_line, $col_mark) =
911             _compare_files($result->{'stdout_file'}, $exp_file);
912              
913 2         18 $name = _build_name($name, @_);
914              
915 2         37 my $is_ok = __PACKAGE__->builder->ok($ok, $name);
916              
917 2 50       2513 if (! $is_ok)
918             {
919 0         0 chomp( $got_line, $exp_line );
920 0         0 __PACKAGE__->builder->diag(<
921             STDOUT differs from $exp_file starting at line $diff_start.
922             got: $got_line
923             exp: $exp_line
924             $col_mark
925             EOD
926             }
927              
928 2         359 return $is_ok;
929             }
930              
931             =head2 Testing STDERR
932              
933             Except where specified, the test routines below treat STDERR as a single slurped
934             string.
935              
936             =head3 stderr_value
937              
938             stderr_value($cmd)
939              
940             Return the STDERR of the command. Useful for performing arbitrary tests
941             not covered by this module.
942              
943             =cut
944              
945             sub stderr_value
946             {
947 2     2 1 32270 my ($cmd) = @_;
948              
949 2         28 my $result = _get_result($cmd);
950 2         22 my $stderr_text = _slurp($result->{'stderr_file'});
951            
952 2         99 return $stderr_text;
953             }
954              
955             =head3 stderr_file
956              
957             stderr_file($cmd)
958              
959             Return the file name containing the STDERR of the command. Useful for
960             performing arbitrary tests not covered by this module.
961              
962             =cut
963              
964             sub stderr_file
965             {
966 2     2 1 5 my ($cmd) = @_;
967              
968 2         9 my $result = _get_result($cmd);
969              
970 2         48 return $result->{'stderr_file'};
971             }
972              
973             =head3 stderr_is_eq
974              
975             stderr_is_eq($cmd, $exp_string, $name)
976              
977             If the STDERR of the command is equal (compared using C) to the expected
978             string, then this passes. Otherwise it fails.
979              
980             =cut
981              
982             sub stderr_is_eq
983             {
984 6     6 1 844 my ($cmd, $exp, $name) = @_;
985              
986 6         26 my $result = _get_result($cmd);
987              
988 6         131 my $stderr_text = _slurp($result->{'stderr_file'});
989              
990 6         151 $name = _build_name($name, @_);
991              
992 6         163 return __PACKAGE__->builder->is_eq($stderr_text, $exp, $name);
993             }
994              
995             =head3 stderr_isnt_eq
996              
997             stderr_isnt_eq($cmd, $unexp_string, $name)
998              
999             If the STDERR of the command is B equal (compared using C) to the
1000             given string, this passes. Otherwise it fails.
1001              
1002             =cut
1003              
1004             sub stderr_isnt_eq
1005             {
1006 2     2 1 9 my ($cmd, $not_exp, $name) = @_;
1007              
1008 2         15 my $result = _get_result($cmd);
1009              
1010 2         33 my $stderr_text = _slurp($result->{'stderr_file'});
1011              
1012 2         16 $name = _build_name($name, @_);
1013              
1014 2         40 return __PACKAGE__->builder->isnt_eq($stderr_text, $not_exp, $name);
1015             }
1016              
1017             =head3 stderr_is_num
1018              
1019             stderr_is_num($cmd, $exp_num, $name)
1020              
1021             If the STDERR of the command is equal (compared using C<==>) to the expected
1022             number, then this passes. Otherwise it fails.
1023              
1024             =cut
1025              
1026             sub stderr_is_num
1027             {
1028 2     2 1 12 my ($cmd, $exp, $name) = @_;
1029              
1030 2         15 my $result = _get_result($cmd);
1031              
1032 2         24 my $stderr_text = _slurp($result->{'stderr_file'});
1033              
1034 2         19 $name = _build_name($name, @_);
1035              
1036 2         38 return __PACKAGE__->builder->is_num($stderr_text, $exp, $name);
1037             }
1038              
1039             =head3 stderr_isnt_num
1040              
1041             stderr_isnt_num($cmd, $unexp_num, $name)
1042              
1043             If the STDERR of the command is B equal (compared using C<==>) to the
1044             given number, this passes. Otherwise it fails.
1045              
1046             =cut
1047              
1048             sub stderr_isnt_num
1049             {
1050 2     2 1 7 my ($cmd, $not_exp, $name) = @_;
1051              
1052 2         15 my $result = _get_result($cmd);
1053              
1054 2         30 my $stderr_text = _slurp($result->{'stderr_file'});
1055              
1056 2         18 $name = _build_name($name, @_);
1057              
1058 2         56 return __PACKAGE__->builder->isnt_num($stderr_text, $not_exp, $name);
1059             }
1060              
1061             =head3 stderr_like
1062              
1063             stderr_like($cmd, $exp_regex, $name)
1064              
1065             If the STDERR of the command matches the expected regular expression,
1066             this passes. Otherwise it fails.
1067              
1068             =cut
1069              
1070             sub stderr_like
1071             {
1072 2     2 1 812 my ($cmd, $exp, $name) = @_;
1073              
1074 2         11 my $result = _get_result($cmd);
1075              
1076 2         28 my $stderr_text = _slurp($result->{'stderr_file'});
1077              
1078 2         17 $name = _build_name($name, @_);
1079              
1080 2         45 return __PACKAGE__->builder->like($stderr_text, $exp, $name);
1081             }
1082              
1083             =head3 stderr_unlike
1084              
1085             stderr_unlike($cmd, $unexp_regex, $name)
1086              
1087             If the STDERR of the command does B match the given regular
1088             expression, this passes. Otherwise it fails.
1089              
1090             =cut
1091              
1092             sub stderr_unlike
1093             {
1094 2     2 1 886 my ($cmd, $exp, $name) = @_;
1095              
1096 2         162 my $result = _get_result($cmd);
1097              
1098 2         309 my $stderr_text = _slurp($result->{'stderr_file'});
1099              
1100 2         17 $name = _build_name($name, @_);
1101              
1102 2         43 return __PACKAGE__->builder->unlike($stderr_text, $exp, $name);
1103             }
1104              
1105             =head3 stderr_cmp_ok
1106              
1107             stderr_cmp_ok($cmd, $op, $operand, $name)
1108              
1109             If the STDERR of the command is compared with the given operand using
1110             the given operator, and that operation returns true, this passes. Otherwise
1111             it fails.
1112              
1113             =cut
1114              
1115             sub stderr_cmp_ok
1116             {
1117 4     4 1 771 my ($cmd, $op, $exp, $name) = @_;
1118              
1119 4         151 my $result = _get_result($cmd);
1120              
1121 4         60 my $stderr_text = _slurp($result->{'stderr_file'});
1122              
1123 4         44 $name = _build_name($name, @_);
1124              
1125 4         245 return __PACKAGE__->builder->cmp_ok($stderr_text, $op, $exp, $name);
1126             }
1127              
1128             =head3 stderr_is_file
1129              
1130             stderr_is_file($cmd, $exp_file, $name)
1131              
1132             If the STDERR of the command is equal (compared using C) to the contents of
1133             the given file, then this passes. Otherwise it fails. Note that this comparison
1134             is performed line by line, rather than slurping the entire file.
1135              
1136             =cut
1137              
1138             sub stderr_is_file
1139             {
1140 2     2 1 1008 my ($cmd, $exp_file, $name) = @_;
1141              
1142 2         22 my $result = _get_result($cmd);
1143              
1144 2         39 my ($ok, $diff_start, $got_line, $exp_line, $col_mark) =
1145             _compare_files($result->{'stderr_file'}, $exp_file);
1146              
1147 2         10 $name = _build_name($name, @_);
1148              
1149 2         315 my $is_ok = __PACKAGE__->builder->ok($ok, $name);
1150              
1151 2 50       2113 if (! $is_ok)
1152             {
1153 0         0 chomp( $got_line, $exp_line );
1154 0         0 __PACKAGE__->builder->diag(<
1155             STDERR differs from $exp_file starting at line $diff_start.
1156             got: $got_line
1157             exp: $exp_line
1158             $col_mark
1159             EOD
1160             }
1161              
1162 2         175 return $is_ok;
1163             }
1164              
1165             =head1 AUTHOR
1166              
1167             Daniel B. Boorstein, C<< >>
1168              
1169             =head1 BUGS
1170              
1171             Please report any bugs or feature requests to
1172             C, or through the web interface at
1173             L.
1174             I will be notified, and then you'll automatically be notified of progress on
1175             your bug as I make changes.
1176              
1177             =head1 SUPPORT
1178              
1179             You can find documentation for this module with the perldoc command.
1180              
1181             perldoc Test::Command
1182              
1183             You can also look for information at:
1184              
1185             =over 4
1186              
1187             =item * AnnoCPAN: Annotated CPAN documentation
1188              
1189             L
1190              
1191             =item * CPAN Ratings
1192              
1193             L
1194              
1195             =item * RT: CPAN's request tracker
1196              
1197             L
1198              
1199             =item * Search CPAN
1200              
1201             L
1202              
1203             =back
1204              
1205             =head1 ACKNOWLEDGEMENTS
1206              
1207             Test::Builder by Michael Schwern allowed me to focus on the specifics related to
1208             testing system commands by making it easy to produce proper test output.
1209              
1210             =head1 COPYRIGHT & LICENSE
1211              
1212             Copyright 2007 Daniel B. Boorstein, all rights reserved.
1213              
1214             This program is free software; you can redistribute it and/or modify it
1215             under the same terms as Perl itself.
1216              
1217             =head1 DEVELOPMENT IDEAS
1218              
1219             =over 3
1220              
1221             =item * create a tool that produces test scripts given a list of commands to run
1222              
1223             =item * optionally save the temp files with STDOUT and STDERR for user debugging
1224              
1225             =item * if user defines all options and sample arguments to basic command
1226              
1227             =over 3
1228              
1229             =item * create tool to enumerate all possible means of calling program
1230              
1231             =item * allow testing with randomized/permuted/collapsed opts and args
1232              
1233             =back
1234              
1235             =item * potential test functions:
1236              
1237             =over 3
1238              
1239             =item * time_lt($cmd, $seconds)
1240              
1241             =item * time_gt($cmd, $seconds)
1242              
1243             =item * stdout_line_custom($cmd, \&code)
1244              
1245             =item * stderr_line_custom($cmd, \&code)
1246              
1247             =back
1248              
1249             =back
1250              
1251             =head1 SEE ALSO
1252              
1253             L provides the testing methods used in this module.
1254              
1255             L is the superclass of this module.
1256              
1257             =cut
1258              
1259             1;