File Coverage

blib/lib/App/Cmd/Tester/CaptureExternal.pm
Criterion Covered Total %
statement 22 22 100.0
branch 1 2 50.0
condition n/a
subroutine 6 6 100.0
pod n/a
total 29 30 96.6


line stmt bran cond sub pod time code
1 1     1   60286 use strict;
  1         10  
  1         27  
2 1     1   4 use warnings;
  1         2  
  1         68  
3             package App::Cmd::Tester::CaptureExternal 0.334;
4              
5 1     1   411 use parent 'App::Cmd::Tester';
  1         317  
  1         6  
6 1     1   560 use Capture::Tiny 0.13 qw/capture/;
  1         22181  
  1         160  
7              
8             # ABSTRACT: Extends App::Cmd::Tester to capture from external subprograms
9              
10             #pod =head1 SYNOPSIS
11             #pod
12             #pod use Test::More tests => 4;
13             #pod use App::Cmd::Tester::CaptureExternal;
14             #pod
15             #pod use YourApp;
16             #pod
17             #pod my $result = test_app(YourApp => [ qw(command --opt value) ]);
18             #pod
19             #pod like($result->stdout, qr/expected output/, 'printed what we expected');
20             #pod
21             #pod is($result->stderr, '', 'nothing sent to sderr');
22             #pod
23             #pod ok($result->output, "STDOUT concatenated with STDERR");
24             #pod
25             #pod =head1 DESCRIPTION
26             #pod
27             #pod L provides a useful scaffold for testing applications, but it
28             #pod is unable to capture output generated from any external subprograms that are
29             #pod invoked from the application.
30             #pod
31             #pod This subclass uses an alternate mechanism for capturing output
32             #pod (L) that does capture from external programs, with one
33             #pod major limitation.
34             #pod
35             #pod It is not possible to capture externally from both STDOUT and STDERR while
36             #pod also having appropriately interleaved combined output. Therefore, the
37             #pod C from this subclass simply concatenates the two.
38             #pod
39             #pod You can still use C for testing if there is any output at all or for
40             #pod testing if something appeared in either output stream, but you can't rely on
41             #pod the ordering being correct between lines to STDOUT and lines to STDERR.
42             #pod
43             #pod =cut
44              
45             sub _run_with_capture {
46 1     1   3 my ($class, $app, $argv) = @_;
47              
48 1         2 my $run_rv;
49              
50             my ($stdout, $stderr, $ok) = capture {
51 1     1   1310 eval {
52 1         11 local $App::Cmd::Tester::TEST_IN_PROGRESS = 1;
53 1         5 local @ARGV = @$argv;
54 1         8 $run_rv = $app->run;
55 1         95077 1;
56             };
57 1         31 };
58              
59 1 50       1346 my $error = $ok ? undef : $@;
60              
61             return {
62 1         34 stdout => $stdout,
63             stderr => $stderr,
64             output => $stdout . $stderr,
65             error => $error,
66             run_rv => $run_rv,
67             };
68             }
69              
70             1;
71              
72             __END__