| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | # -*- Perl -*- | 
| 2 |  |  |  |  |  |  | # | 
| 3 |  |  |  |  |  |  | # Test::UnixCmdWrap - test unix commands with various assumptions | 
| 4 |  |  |  |  |  |  |  | 
| 5 |  |  |  |  |  |  | package Test::UnixCmdWrap; | 
| 6 |  |  |  |  |  |  |  | 
| 7 | 2 |  |  | 2 |  | 150691 | use 5.24.0; | 
|  | 2 |  |  |  |  | 10 |  | 
| 8 | 2 |  |  | 2 |  | 10 | use warnings; | 
|  | 2 |  |  |  |  | 2 |  | 
|  | 2 |  |  |  |  | 57 |  | 
| 9 | 2 |  |  | 2 |  | 28 | use Cwd qw(getcwd); | 
|  | 2 |  |  |  |  | 2 |  | 
|  | 2 |  |  |  |  | 80 |  | 
| 10 | 2 |  |  | 2 |  | 20 | use Carp qw(croak); | 
|  | 2 |  |  |  |  | 4 |  | 
|  | 2 |  |  |  |  | 109 |  | 
| 11 | 2 |  |  | 2 |  | 941 | use File::Spec::Functions qw(catfile); | 
|  | 2 |  |  |  |  | 1508 |  | 
|  | 2 |  |  |  |  | 121 |  | 
| 12 | 2 |  |  | 2 |  | 1056 | use Moo; | 
|  | 2 |  |  |  |  | 44868 |  | 
|  | 2 |  |  |  |  | 10 |  | 
| 13 | 2 |  |  | 2 |  | 3963 | use Test::Cmd (); | 
|  | 2 |  |  |  |  | 23116 |  | 
|  | 2 |  |  |  |  | 96 |  | 
| 14 | 2 |  |  | 2 |  | 625 | use Test::Differences qw(eq_or_diff); | 
|  | 2 |  |  |  |  | 20405 |  | 
|  | 2 |  |  |  |  | 145 |  | 
| 15 | 2 |  |  | 2 |  | 14 | use Test::More; | 
|  | 2 |  |  |  |  | 18 |  | 
|  | 2 |  |  |  |  | 29 |  | 
| 16 | 2 |  |  | 2 |  | 1764 | use Test::UnixExit qw(exit_is exit_is_nonzero); | 
|  | 2 |  |  |  |  | 1347 |  | 
|  | 2 |  |  |  |  | 1343 |  | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | our $VERSION = '0.04'; | 
| 19 |  |  |  |  |  |  |  | 
| 20 |  |  |  |  |  |  | has cmd => ( | 
| 21 |  |  |  |  |  |  | is      => 'rwp', | 
| 22 |  |  |  |  |  |  | default => sub { | 
| 23 |  |  |  |  |  |  | # t/foo.t -> ./foo with restrictive sanity checks on what is | 
| 24 |  |  |  |  |  |  | # consided valid for a command name--"foo.sh" is not a valid | 
| 25 |  |  |  |  |  |  | # command name, get rid of that dangly thing at the end, or | 
| 26 |  |  |  |  |  |  | # manually supply your own Test::Cmd object. 38 characters is | 
| 27 |  |  |  |  |  |  | # the longest command name I can find on my OpenBSD 6.5 system | 
| 28 |  |  |  |  |  |  | if ( $0 =~ m{^t/([A-Za-z0-9_][A-Za-z0-9_-]{0,127})\.t$} ) { | 
| 29 |  |  |  |  |  |  | my $file = $1; | 
| 30 |  |  |  |  |  |  | return Test::Cmd->new( prog => catfile( getcwd(), $1 ), workdir => '' ); | 
| 31 |  |  |  |  |  |  | } else { | 
| 32 |  |  |  |  |  |  | croak "could not extract command name from $0"; | 
| 33 |  |  |  |  |  |  | } | 
| 34 |  |  |  |  |  |  | }, | 
| 35 |  |  |  |  |  |  | ); | 
| 36 |  |  |  |  |  |  | has prog => ( is => 'lazy', ); | 
| 37 |  |  |  |  |  |  |  | 
| 38 | 1 |  |  | 1 |  | 62 | sub _build_prog { $_[0]->cmd->prog } | 
| 39 |  |  |  |  |  |  |  | 
| 40 |  |  |  |  |  |  | sub BUILD { | 
| 41 | 4 |  |  | 4 | 1 | 51462 | my ( $self, $args ) = @_; | 
| 42 | 4 | 100 | 100 |  |  | 85 | if ( exists $args->{cmd} and !ref $args->{cmd} ) { | 
| 43 |  |  |  |  |  |  | # TODO may need to fully qualify this path depending on how that | 
| 44 |  |  |  |  |  |  | # interacts with chdir (or if the caller is making any of those) | 
| 45 | 2 |  |  |  |  | 23 | $self->_set_cmd( Test::Cmd->new( prog => $args->{cmd}, workdir => '' ) ); | 
| 46 |  |  |  |  |  |  | } | 
| 47 |  |  |  |  |  |  | # TODO better way to apply Devel::Cover to only the script runs? | 
| 48 | 4 | 50 |  |  |  | 22452 | if ( $ENV{DEVEL_COVER} ) { | 
| 49 | 0 |  |  |  |  | 0 | diag "coverage enabled... (slow)"; | 
| 50 | 0 |  |  |  |  | 0 | `cover -delete`; | 
| 51 | 0 |  |  |  |  | 0 | $ENV{PERL5OPT} = '-MDevel::Cover'; | 
| 52 |  |  |  |  |  |  | } | 
| 53 |  |  |  |  |  |  | } | 
| 54 |  |  |  |  |  |  |  | 
| 55 |  |  |  |  |  |  | sub run { | 
| 56 | 8 |  |  | 8 | 1 | 2665 | my ( $self, %p ) = @_; | 
| 57 |  |  |  |  |  |  |  | 
| 58 | 8 |  | 100 |  |  | 118 | $p{env} //= {}; | 
| 59 |  |  |  |  |  |  | # no news is good news. and here it is the default | 
| 60 | 8 |  | 100 |  |  | 109 | $p{status} //= 0; | 
| 61 | 8 |  | 66 |  |  | 149 | $p{stderr} //= qr/^$/; | 
| 62 | 8 |  | 66 |  |  | 125 | $p{stdout} //= qr/^$/; | 
| 63 |  |  |  |  |  |  |  | 
| 64 | 8 |  |  |  |  | 43 | my $cmd  = $self->cmd; | 
| 65 | 8 | 100 |  |  |  | 57 | my $name = $cmd->prog . ( exists $p{args} ? ' ' . $p{args} : '' ); | 
| 66 |  |  |  |  |  |  |  | 
| 67 | 8 |  |  |  |  | 158 | local @ENV{ keys $p{env}->%* } = values $p{env}->%*; | 
| 68 |  |  |  |  |  |  |  | 
| 69 | 8 | 100 |  |  |  | 41 | $cmd->run( map { exists $p{$_} ? ( $_ => $p{$_} ) : () } qw(args chdir stdin) ); | 
|  | 24 |  |  |  |  | 116 |  | 
| 70 |  |  |  |  |  |  |  | 
| 71 |  |  |  |  |  |  | # tests relative to the caller so the test failures don't point at | 
| 72 |  |  |  |  |  |  | # lines of this function | 
| 73 | 8 |  |  |  |  | 155037 | local $Test::Builder::Level = $Test::Builder::Level + 1; | 
| 74 |  |  |  |  |  |  |  | 
| 75 |  |  |  |  |  |  | # probably should be paired with { status => 1 } and that the | 
| 76 |  |  |  |  |  |  | # process being tested is expected to die (with some unknown | 
| 77 |  |  |  |  |  |  | # status code) | 
| 78 | 8 |  |  |  |  | 84 | my $status = $?; | 
| 79 | 8 | 100 |  |  |  | 85 | $status = exit_is_nonzero( $status ) if $p{munge_status}; | 
| 80 |  |  |  |  |  |  |  | 
| 81 | 8 |  |  |  |  | 263 | exit_is( $status, $p{status}, "STATUS $name" ); | 
| 82 |  |  |  |  |  |  | # for some commands a regex suffices but for others want to compare | 
| 83 |  |  |  |  |  |  | # expected lines NOTE this is sloppy about trailing whitespace which | 
| 84 |  |  |  |  |  |  | # many but not all things may be forgiving of | 
| 85 | 8 | 100 |  |  |  | 9244 | if ( ref $p{stdout} eq 'ARRAY' ) { | 
| 86 | 2 |  |  |  |  | 214 | eq_or_diff( [ map { s/\s+$//r } split $/, $cmd->stdout ], | 
| 87 | 1 |  |  |  |  | 43 | $p{stdout}, 'STDOUT ' . $name ); | 
| 88 |  |  |  |  |  |  | } else { | 
| 89 | 7 | 100 |  |  |  | 92 | ok( $cmd->stdout =~ m/$p{stdout}/, 'STDOUT ' . $name ) | 
| 90 |  |  |  |  |  |  | or diag 'STDOUT ' . $cmd->stdout; | 
| 91 |  |  |  |  |  |  | } | 
| 92 | 8 | 100 |  |  |  | 6648 | ok( $cmd->stderr =~ m/$p{stderr}/, 'STDERR ' . $name ) | 
| 93 |  |  |  |  |  |  | or diag 'STDERR ' . $cmd->stderr; | 
| 94 |  |  |  |  |  |  |  | 
| 95 |  |  |  |  |  |  | # for when the caller needs to poke at the results for something not | 
| 96 |  |  |  |  |  |  | # covered by the above | 
| 97 | 8 |  |  |  |  | 4515 | return $cmd; | 
| 98 |  |  |  |  |  |  | } | 
| 99 |  |  |  |  |  |  |  | 
| 100 |  |  |  |  |  |  | 1; | 
| 101 |  |  |  |  |  |  | __END__ |