File Coverage

blib/lib/Test/CLI.pm
Criterion Covered Total %
statement 167 176 94.8
branch 5 10 50.0
condition 17 36 47.2
subroutine 31 32 96.8
pod 12 12 100.0
total 232 266 87.2


line stmt bran cond sub pod time code
1             package Test::CLI;
2 6     6   609812 use 5.024000;
  6         73  
3 6     6   35 use warnings;
  6         11  
  6         178  
4 6     6   3160 use experimental qw< signatures >;
  6         21202  
  6         32  
5 6     6   1053 no warnings qw< experimental::signatures >;
  6         14  
  6         413  
6             { our $VERSION = '0.001' }
7              
8 6     6   3242 use Command::Template qw< command_runner >;
  6         267237  
  6         365  
9 6     6   54 use Test2::API 'context';
  6         13  
  6         322  
10              
11 6     6   37 use Exporter 'import';
  6         12  
  6         470  
12             our @EXPORT_OK = qw< tc test_cli >;
13              
14             # functional interface
15 7     7 1 1742 sub test_cli (@command) { __PACKAGE__->new(@command) }
  7         50  
  7         16  
  7         75  
16             {
17 6     6   37 no strict 'refs';
  6         11  
  6         4902  
18             *tc = *test_cli;
19             }
20              
21             # constructor, accessors, and commodity functions
22 7     7 1 17 sub new ($pack, @cmd) { bless {runner => command_runner(@cmd)}, $pack }
  7         15  
  7         16  
  7         12  
  7         33  
23 18     18 1 1636 sub run ($self, @args) { return $self->runner->run(@args)->success }
  18         47  
  18         61  
  18         30  
  18         99  
24 125     125 1 187 sub runner ($self) { return $self->{runner} }
  125         174  
  125         153  
  125         498  
25 107     107 1 222 sub last_run ($self) { return $self->runner->last_run }
  107         211  
  107         152  
  107         272  
26 38     38 1 71 sub last_command ($self) { return $self->last_run->command_as_string }
  38         60  
  38         53  
  38         98  
27              
28 1     1 1 18 sub verbose ($self, @new) {
  1         3  
  1         3  
  1         3  
29 1 50       5 return $self->{verbose} unless @new;
30 1         16 $self->{verbose} = $new[0];
31 1         5 return $self;
32             }
33 34     34   93 sub _message ($self, $pref) { $pref . ' ' . $self->last_command }
  34         71  
  34         67  
  34         55  
  34         123  
34              
35             # test interface
36 5     5 1 15490 sub run_ok ($self, $bindopts = {}, $message = undef) {
  5         16  
  5         20  
  5         14  
  5         18  
37 5         29 $self->run($bindopts->%*);
38 5         69475 $self->ok($message);
39             }
40              
41 3     3 1 993 sub run_failure_ok ($self, $bindopts = {}, $message = undef) {
  3         6  
  3         7  
  3         6  
  3         5  
42 3         24 $self->run($bindopts->%*);
43 3         43096 $self->failure_ok($message);
44             }
45              
46 0     0 1 0 sub dump_diag ($self) {
  0         0  
  0         0  
47 0         0 require Data::Dumper;
48 0         0 local $Data::Dumper::Indent = 1;
49 0         0 my $c = context();
50 0         0 $c->diag(Data::Dumper::Dumper({$self->last_run->%*}));
51 0         0 $c->release;
52 0         0 return $self;
53             } ## end sub dump_diag ($self)
54              
55 5     5 1 35 sub ok ($self, $message = undef) {
  5         25  
  5         12  
  5         11  
56 5         43 my $outcome = $self->last_run->success;
57 5         161 my $c = context();
58 5   66     1926 $c->ok($outcome, $message // $self->last_command);
59 5         2779 $c->release;
60 5 50 33     229 $self->dump_diag if (!$outcome) && $self->verbose;
61 5         50 return $self;
62             } ## end sub ok
63              
64 3     3 1 20 sub failure_ok ($self, $message = undef) {
  3         6  
  3         30  
  3         10  
65 3         32 my $outcome = $self->last_run->failure;
66 3         126 my $c = context();
67 3   66     1475 $c->ok($outcome, $message // $self->_message('(failure on)'));
68 3         1631 $c->release;
69 3 50 33     170 $self->dump_diag if (!$outcome) && $self->verbose;
70 3         33 return $self;
71             } ## end sub failure_ok
72              
73 61     61   920 sub _ok ($self, $outcome, $errormsg, $message) {
  61         102  
  61         132  
  61         107  
  61         127  
  61         93  
74 61         329 my $c = context();
75 61         9093 $c->ok($outcome, $message);
76 61 50 33     13511 $c->diag($errormsg) if $errormsg && !$outcome;
77 61         347 $c->release;
78 61 50 33     1967 $self->dump_diag if (!$outcome) && $self->verbose;
79 61         263 return $self;
80             } ## end sub _ok
81              
82             for my $case (
83             [
84             'exit code',
85             qw<
86             exit_code
87             exit_code_ok exit_code_failure_ok
88             exit_code_is exit_code_isnt
89             >
90             ],
91             [
92             'signal',
93             qw<
94             signal
95             signal_ok signal_failure_ok
96             signal_is signal_isnt
97             >
98             ],
99             [
100             'timeout',
101             qw<
102             timeout
103             in_time_ok timed_out_ok
104             timeout_is timeout_isnt
105             >
106             ],
107             )
108             {
109             my ($name, $method, $ok, $not_ok, $is, $isnt) = $case->@*;
110 6     6   54 no strict 'refs';
  6         13  
  6         2443  
111              
112 5     5   1043416 *{$ok} = sub ($self, $message = undef) { $self->$is(0, $message) };
  5         110  
  5         40  
  5         45  
  5         78  
113              
114 4     4   2178203 *{$not_ok} = sub ($self, $msg = undef) { $self->$isnt(0, $msg) };
  4         34  
  4         172  
  4         15  
  4         84  
115              
116 13     13   187 *{$is} = sub ($self, $exp, $message = undef) {
  13         53  
  13         38  
  13         38  
  13         33  
117 13         79 my $got = $self->last_run->$method;
118 13   33     411 return $self->_ok(
119             $got == $exp,
120             "$name: got $got, expected $exp",
121             $message // $self->_message("($name is $exp on)"),
122             );
123             };
124              
125 14     14   174 *{$isnt} = sub ($self, $nexp, $message = undef) {
  14         43  
  14         31  
  14         36  
  14         21  
126 14         59 my $got = $self->last_run->$method;
127 14   33     380 return $self->_ok(
128             $got != $nexp,
129             "$name: did not expect $nexp",
130             $message // $self->_message("($name is not $nexp on)"),
131             );
132             };
133             } ## end for my $case (['exit code'...])
134              
135             for my $case (
136             [qw< stdout stdout stdout_is stdout_isnt stdout_like stdout_unlike >],
137             [qw< stderr stderr stderr_is stderr_isnt stderr_like stderr_unlike >],
138             [qw< merged merged merged_is merged_isnt merged_like merged_unlike >],
139             )
140             {
141             my ($name, $method, $is, $isnt, $like, $unlike) = $case->@*;
142 6     6   48 no strict 'refs';
  6         10  
  6         3125  
143              
144 8     8   39739 *{$is} = sub ($self, $exp, $message = undef) {
  8         30  
  8         67  
  8         62  
  8         32  
145 8         43 my $got = $self->last_run->$method;
146 8   66     302 return $self->_ok(
147             $got eq $exp,
148             "$name: got <$got>, expected <$exp>",
149             $message // $self->_message("($name is <$exp> on)"),
150             );
151             };
152              
153 7     7   131 *{$isnt} = sub ($self, $nexp, $message = undef) {
  7         14  
  7         27  
  7         37  
  7         16  
154 7         20 my $got = $self->last_run->$method;
155 7   33     149 return $self->_ok(
156             $got ne $nexp,
157             "$name: did not expect <$nexp>",
158             $message // $self->_message("($name is not <$nexp> on)"),
159             );
160             };
161              
162 10     10   242 *{$like} = sub ($self, $regex, $message = undef) {
  10         27  
  10         27  
  10         26  
  10         15  
163 10         31 my $got = $self->last_run->$method;
164 10         361 my $outcome = $got =~ m{$regex};
165 10   66     115 return $self->_ok(
166             $outcome,
167             "$name: did not match $regex",
168             $message // $self->_message("($name match $regex on)"),
169             );
170             };
171              
172 9     9   190 *{$unlike} = sub ($self, $regex, $message = undef) {
  9         26  
  9         27  
  9         42  
  9         22  
173 9         33 my $got = $self->last_run->$method;
174 9         242 my $outcome = $got !~ m{$regex};
175 9   66     91 return $self->_ok(
176             $outcome,
177             "$name: unepected match of $regex",
178             $message // $self->_message("($name does not match $regex on)"),
179             );
180             };
181             } ## end for my $case ([...])
182              
183             1;