| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package App::NDTools::Test; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 11 |  |  | 11 |  | 967367 | use strict; | 
|  | 11 |  |  |  |  | 111 |  | 
|  | 11 |  |  |  |  | 354 |  | 
| 4 | 11 |  |  | 11 |  | 55 | use warnings FATAL => 'all'; | 
|  | 11 |  |  |  |  | 26 |  | 
|  | 11 |  |  |  |  | 386 |  | 
| 5 | 11 |  |  | 11 |  | 5377 | use parent qw(Exporter); | 
|  | 11 |  |  |  |  | 2855 |  | 
|  | 11 |  |  |  |  | 53 |  | 
| 6 |  |  |  |  |  |  |  | 
| 7 | 11 |  |  | 11 |  | 6116 | use Capture::Tiny qw(capture); | 
|  | 11 |  |  |  |  | 269124 |  | 
|  | 11 |  |  |  |  | 700 |  | 
| 8 | 11 |  |  | 11 |  | 7500 | use Data::Dumper; | 
|  | 11 |  |  |  |  | 78443 |  | 
|  | 11 |  |  |  |  | 657 |  | 
| 9 | 11 |  |  | 11 |  | 78 | use Test::More; | 
|  | 11 |  |  |  |  | 21 |  | 
|  | 11 |  |  |  |  | 61 |  | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | our @EXPORT = qw( | 
| 12 |  |  |  |  |  |  | run_ok | 
| 13 |  |  |  |  |  |  | t_ab_cmp | 
| 14 |  |  |  |  |  |  | t_dir | 
| 15 |  |  |  |  |  |  | t_dump | 
| 16 |  |  |  |  |  |  | ); | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | sub run_ok { | 
| 19 | 176 |  |  | 176 | 0 | 539973 | my %t = @_; | 
| 20 |  |  |  |  |  |  |  | 
| 21 | 176 |  |  |  |  | 1217 | local $Test::Builder::Level = $Test::Builder::Level + 1; | 
| 22 |  |  |  |  |  |  |  | 
| 23 | 176 | 50 | 33 |  |  | 1417 | if (exists $t{skip} and $t{skip}->()) { | 
| 24 | 0 |  |  |  |  | 0 | pass("Test '$t{name}' cancelled by 'skip' opt"); | 
| 25 | 0 |  |  |  |  | 0 | return; | 
| 26 |  |  |  |  |  |  | } | 
| 27 |  |  |  |  |  |  |  | 
| 28 | 176 | 50 |  |  |  | 1064 | my @envs = exists $t{env} ? %{$t{env}} : (); | 
|  | 0 |  |  |  |  | 0 |  | 
| 29 |  |  |  |  |  |  | SET_ENV: # can't use loop here - env vars will be localized in it's block | 
| 30 | 176 | 50 |  |  |  | 876 | @envs and local $ENV{$envs[0]} = $envs[1]; | 
| 31 | 176 | 50 |  |  |  | 1195 | if (@envs) { | 
| 32 | 0 |  |  |  |  | 0 | splice @envs, 0, 2; | 
| 33 | 0 |  |  |  |  | 0 | goto SET_ENV; | 
| 34 |  |  |  |  |  |  | } | 
| 35 |  |  |  |  |  |  |  | 
| 36 | 176 | 50 | 66 |  |  | 1520 | if (exists $t{pre} and not $t{pre}->()) { | 
| 37 | 0 |  |  |  |  | 0 | fail("Pre hook for '$t{name}' failed"); | 
| 38 | 0 |  |  |  |  | 0 | return; | 
| 39 |  |  |  |  |  |  | } | 
| 40 |  |  |  |  |  |  |  | 
| 41 | 176 |  |  | 176 |  | 54337 | my ($out, $err, $exit) = capture { system(@{$t{cmd}}) }; | 
|  | 176 |  |  |  |  | 319626 |  | 
|  | 176 |  |  |  |  | 42267220 |  | 
| 42 |  |  |  |  |  |  |  | 
| 43 |  |  |  |  |  |  | subtest $t{name} => sub { | 
| 44 |  |  |  |  |  |  |  | 
| 45 | 176 |  |  | 176 |  | 504143 | for my $std ('stdout', 'stderr') { | 
| 46 | 352 | 50 | 66 |  |  | 216067 | next if (exists $t{$std} and not defined $t{$std}); # set to undef to skip test | 
| 47 | 352 | 100 |  |  |  | 3596 | $t{$std} = '' unless (exists $t{$std});             # silence expected by default | 
| 48 |  |  |  |  |  |  |  | 
| 49 | 352 |  |  |  |  | 3221 | my $desc = uc($std) . " check for $t{name}: [" . join(" ", @{$t{cmd}}) ."]"; | 
|  | 352 |  |  |  |  | 2868 |  | 
| 50 | 352 | 100 |  |  |  | 2025 | my $data = $std eq 'stdout' ? $out : $err; | 
| 51 |  |  |  |  |  |  |  | 
| 52 | 352 | 100 |  |  |  | 2500 | if (ref $t{$std} eq 'CODE') { | 
|  |  | 100 |  |  |  |  |  | 
| 53 | 79 |  |  |  |  | 624 | ok($t{$std}->($data), $desc); | 
| 54 |  |  |  |  |  |  | } elsif (ref $t{$std} eq 'Regexp') { | 
| 55 | 32 |  |  |  |  | 369 | like($data, $t{$std}, $desc); | 
| 56 |  |  |  |  |  |  | } else { | 
| 57 | 241 |  |  |  |  | 1811 | is($data, $t{$std}, $desc); | 
| 58 |  |  |  |  |  |  | } | 
| 59 |  |  |  |  |  |  | } | 
| 60 |  |  |  |  |  |  |  | 
| 61 | 176 | 50 | 66 |  |  | 112874 | if (not exists $t{exit} or defined $t{exit}) {  # set to undef to skip test | 
| 62 | 176 | 100 |  |  |  | 2013 | $t{exit} = 0 unless exists $t{exit};        # defailt exit code | 
| 63 |  |  |  |  |  |  | is( | 
| 64 |  |  |  |  |  |  | $exit >> 8, $t{exit}, | 
| 65 | 176 |  |  |  |  | 1706 | "Exit code check for $t{name}: [" . join(" ", @{$t{cmd}}) ."]" | 
|  | 176 |  |  |  |  | 2084 |  | 
| 66 |  |  |  |  |  |  | ); | 
| 67 |  |  |  |  |  |  | } | 
| 68 |  |  |  |  |  |  |  | 
| 69 | 176 | 100 |  |  |  | 105735 | $t{test}->() if (exists $t{test}); | 
| 70 |  |  |  |  |  |  |  | 
| 71 | 176 | 50 | 33 |  |  | 81495 | if (exists $t{post} and not $t{post}->()) { | 
| 72 | 0 |  |  |  |  | 0 | fail("Post hook for '$t{name}' failed"); | 
| 73 | 0 |  |  |  |  | 0 | return; | 
| 74 |  |  |  |  |  |  | } | 
| 75 |  |  |  |  |  |  |  | 
| 76 | 176 | 50 | 66 |  |  | 1283 | if (not exists $t{clean} or defined $t{clean}) { # set to undef to skip | 
| 77 | 176 | 100 |  |  |  | 1165 | @{$t{clean}} = "$t{name}.got" unless exists $t{clean}; | 
|  | 169 |  |  |  |  | 2719 |  | 
| 78 | 176 | 100 |  |  |  | 695 | map { unlink $_ if (-f $_) } @{$t{clean}}; | 
|  | 183 |  |  |  |  | 14240 |  | 
|  | 176 |  |  |  |  | 845 |  | 
| 79 |  |  |  |  |  |  | } | 
| 80 |  |  |  |  |  |  |  | 
| 81 | 176 |  |  |  |  | 2044 | done_testing(); | 
| 82 |  |  |  |  |  |  | } | 
| 83 | 176 |  |  |  |  | 363646 | } | 
| 84 |  |  |  |  |  |  |  | 
| 85 |  |  |  |  |  |  | sub t_ab_cmp { | 
| 86 | 0 |  |  | 0 | 0 | 0 | return "GOT: " . t_dump(shift) . "\nEXP: " . t_dump(shift); | 
| 87 |  |  |  |  |  |  | } | 
| 88 |  |  |  |  |  |  |  | 
| 89 |  |  |  |  |  |  | sub t_dir { | 
| 90 | 11 |  | 33 | 11 | 0 | 1066 | my $tfile = shift || (caller)[1]; | 
| 91 | 11 |  |  |  |  | 290 | substr($tfile, 0, length($tfile) - 1) . "d"; | 
| 92 |  |  |  |  |  |  | } | 
| 93 |  |  |  |  |  |  |  | 
| 94 |  |  |  |  |  |  | sub t_dump { | 
| 95 | 0 |  |  | 0 | 0 |  | return Data::Dumper->new([shift])->Terse(1)->Sortkeys(1)->Quotekeys(0)->Indent(0)->Deepcopy(1)->Dump(); | 
| 96 |  |  |  |  |  |  | } | 
| 97 |  |  |  |  |  |  |  | 
| 98 |  |  |  |  |  |  | 1; |