File Coverage

blib/lib/App/NDTools/Test.pm
Criterion Covered Total %
statement 73 86 84.8
branch 28 38 73.6
condition 12 24 50.0
subroutine 12 14 85.7
pod 0 4 0.0
total 125 166 75.3


line stmt bran cond sub pod time code
1             package App::NDTools::Test;
2              
3 12     12   1087395 use strict;
  12         138  
  12         421  
4 12     12   71 use warnings FATAL => 'all';
  12         27  
  12         513  
5 12     12   4825 use parent qw(Exporter);
  12         3137  
  12         70  
6              
7 12     12   6195 use Capture::Tiny qw(capture);
  12         269951  
  12         824  
8 12     12   7815 use Data::Dumper;
  12         84829  
  12         834  
9 12     12   100 use Scalar::Util qw(blessed);
  12         29  
  12         632  
10 12     12   81 use Test::More;
  12         28  
  12         97  
11              
12             our @EXPORT = qw(
13             run_ok
14             t_ab_cmp
15             t_dir
16             t_dump
17             );
18              
19             sub run_ok {
20 197     197 0 351482 my %t = @_;
21              
22 197         632 local $Test::Builder::Level = $Test::Builder::Level + 1;
23              
24 197 50 33     859 if (exists $t{skip} and $t{skip}->()) {
25 0         0 pass("Test '$t{name}' cancelled by 'skip' opt");
26 0         0 return;
27             }
28              
29 197 50       757 my @envs = exists $t{env} ? %{$t{env}} : ();
  0         0  
30             SET_ENV: # can't use loop here - env vars will be localized in it's block
31 197 50       563 @envs and local $ENV{$envs[0]} = $envs[1];
32 197 50       564 if (@envs) {
33 0         0 splice @envs, 0, 2;
34 0         0 goto SET_ENV;
35             }
36              
37 197 50 66     820 if (exists $t{pre} and not $t{pre}->()) {
38 0         0 fail("Pre hook for '$t{name}' failed");
39 0         0 return;
40             }
41              
42 197         28694 my ($out, $err, $exit);
43 197 100       479 if (eval { $t{cmd}->[0]->isa('App::NDTools::NDTool') }) {
  197         2572  
44 185         387 my $tool = shift @{$t{cmd}};
  185         585  
45              
46             ($out, $err) = capture {
47 185     185   227205 local $Log::Log4Cli::LEVEL = 0; # reset loglevel
48 185         434 eval { $tool->new(@{$t{cmd}})->exec() }
  185         354  
  185         1756  
49 185         6579 };
50              
51 185 50 33     191193 if (blessed($@) and $@->isa('Log::Log4Cli::Exception')) {
52 185         823 $err .= $@->{LOG_MESSAGE};
53 185         516 $exit = $@->{EXIT_CODE};
54             } else {
55 0         0 $err .= $@;
56 0         0 $exit = 255;
57             }
58              
59 185         462 unshift @{$t{cmd}}, $tool;
  185         706  
60             } else { # assume it's binary
61 12     12   397 ($out, $err, $exit) = capture { system(@{$t{cmd}}) };
  12         14598  
  12         2912262  
62 12         21834 $exit = $exit >> 8;
63             }
64              
65             subtest $t{name} => sub {
66              
67 197     197   204249 for my $std ('stdout', 'stderr') {
68 394 50 66     136082 next if (exists $t{$std} and not defined $t{$std}); # set to undef to skip test
69 394 100       1353 $t{$std} = '' unless (exists $t{$std}); # silence expected by default
70              
71 394         1465 my $desc = uc($std) . " check for $t{name}: [@{$t{cmd}}]";
  394         1972  
72 394 100       1325 my $data = $std eq 'stdout' ? $out : $err;
73              
74 394 100       1371 if (ref $t{$std} eq 'CODE') {
    100          
75 98         479 ok($t{$std}->($data), $desc);
76             } elsif (ref $t{$std} eq 'Regexp') {
77 34         201 like($data, $t{$std}, $desc);
78             } else {
79 262         1069 is($data, $t{$std}, $desc);
80             }
81             }
82              
83 197 50 66     83275 if (not exists $t{exit} or defined $t{exit}) { # set to undef to skip test
84 197 100       808 $t{exit} = 0 unless exists $t{exit}; # defailt exit code
85             is(
86             $exit, $t{exit},
87 197         951 "Exit code check for $t{name}: [@{$t{cmd}}]"
  197         1282  
88             );
89             }
90              
91 197 100       79540 $t{test}->() if (exists $t{test});
92              
93 197 50 33     48446 if (exists $t{post} and not $t{post}->()) {
94 0         0 fail("Post hook for '$t{name}' failed");
95 0         0 return;
96             }
97              
98 197 50 66     797 if (not exists $t{clean} or defined $t{clean}) { # set to undef to skip
99 197 100       838 @{$t{clean}} = "$t{name}.got" unless exists $t{clean};
  190         953  
100 197 100       402 map { unlink $_ if (-f $_) } @{$t{clean}};
  204         24337  
  197         515  
101             }
102              
103 197         1164 done_testing();
104             }
105 197         2681 }
106              
107             sub t_ab_cmp {
108 0     0 0 0 return "GOT: " . t_dump(shift) . "\nEXP: " . t_dump(shift);
109             }
110              
111             sub t_dir {
112 12   33 12 0 1168 my $tfile = shift || (caller)[1];
113 12         340 substr($tfile, 0, length($tfile) - 1) . "d";
114             }
115              
116             sub t_dump {
117 0     0 0   return Data::Dumper->new([shift])->Terse(1)->Sortkeys(1)->Quotekeys(0)->Indent(0)->Deepcopy(1)->Dump();
118             }
119              
120             1;