File Coverage

blib/lib/Test/MockCommand/Result.pm
Criterion Covered Total %
statement 67 72 93.0
branch 25 32 78.1
condition 7 13 53.8
subroutine 14 15 93.3
pod 6 6 100.0
total 119 138 86.2


line stmt bran cond sub pod time code
1             package Test::MockCommand::Result;
2 18     18   97 use strict;
  18         34  
  18         404  
3 18     18   72 use warnings;
  18         29  
  18         383  
4              
5 18     18   68 use Carp qw(croak);
  18         27  
  18         594  
6 18     18   79 use Symbol;
  18         23  
  18         620  
7              
8 18     18   6038 use Test::MockCommand::TiedFH;
  18         38  
  18         811  
9              
10             # create some accessor subroutines on the fly
11             my @ACCESSORS = qw(command function arguments return_value cwd
12             input_data output_data exit_code all_results);
13 18     18   127 no strict 'refs';
  18         32  
  18         1502  
14             for my $attrib (@ACCESSORS) {
15             my $method = __PACKAGE__ . '::' . $attrib;
16             next if *$method{CODE};
17             *$method = sub {
18 658 100   658   11824 $_[0]->{$attrib} = $_[1] if @_ > 1;
19 658         20042 return $_[0]->{$attrib};
20             };
21             }
22 18     18   107 use strict 'refs';
  18         30  
  18         7197  
23              
24             sub new {
25 50     50 1 321 my $class = shift;
26 50 50       307 croak "odd number of parameters" if @_ % 2;
27 50         198 my %args = @_;
28             my $self = {
29             command => $args{command},
30             function => $args{function},
31 50         137 arguments => [ @{$args{arguments}} ] # copy rather than reference
  50         263  
32             };
33              
34             # turn the first argument to open() to undef, always
35 50 100       192 $self->{arguments}->[0] = undef if $self->{function} eq 'open';
36              
37 50         337 return bless $self, $class;
38             }
39              
40             sub matches {
41 340     340 1 1026 my $self = shift;
42 340 50       1127 croak "odd number of parameters" if @_ % 2;
43 340         1459 my %args = @_;
44              
45             # function and command have already been matched
46              
47             # check the arguments match exactly
48 340 100       1739 if (exists $args{arguments}) {
49 273 100       459 return 0 if @{$args{arguments}} != @{$self->{arguments}};
  273         485  
  273         928  
50 261         659 for (my $i = 0; $i < @{$args{arguments}}; $i++) {
  640         1817  
51             next if not defined $args{arguments}->[$i] and
52 385 50 66     3587 not defined $self->{arguments}->[$i];
53             return 0 if not defined $args{arguments}->[$i] or
54 261 100 66     2420 not defined $self->{arguments}->[$i];
55 260 100       1032 return 0 if $args{arguments}->[$i] ne $self->{arguments}->[$i];
56             }
57             }
58              
59             # result matches. award more points if cwd matches too
60 322 100       1678212 my $cwd = defined $args{cwd} ? $args{cwd} : Cwd::cwd();
61 322 100       7370 return $self->cwd() eq $cwd ? 2 : 1;
62             }
63              
64             sub handle {
65 29     29 1 89 my $self = shift;
66 29 50       135 croak "odd number of parameters" if @_ % 2;
67 29         1642 my %args = @_;
68              
69             # check arguments
70 29         133 for (qw(command function arguments caller)) {
71 116 50       261 croak "no $_ parameter" unless exists $args{$_};
72             }
73              
74             # check function is one we know
75             croak "unknown function $args{function}"
76 29 50       653 unless $args{function} =~ /^(open|readpipe|system|exec)$/;
77              
78             # set the list of all results
79 29         194 $self->all_results($args{all_results});
80              
81             # handle open() emulation
82 29 100 66     240 if ($args{function} eq 'open' && $self->return_value()) {
83              
84             # make our own filehandle and tie it to ourselves
85 13         65 my $fh = $self->create_tied_fh();
86              
87             # create the requested filehandle
88 13 50       82 if (defined $args{arguments}->[0]) {
89 18     18   131 no strict 'refs';
  18         58  
  18         3860  
90             # file handle is a bareword symbol reference
91 0         0 my $sym = Symbol::qualify($args{arguments}->[0], $args{caller}->[0]);
92 0         0 *$sym = $fh;
93             }
94             else {
95 13         72 $args{arguments}->[0] = $fh;
96             }
97             }
98              
99             # set the exit code
100 29         167 $? = $self->exit_code();
101              
102             # return the result
103 29         137 return $self->return_value();
104             }
105              
106             sub create_tied_fh {
107 13     13 1 36 my $self = shift;
108 13         144 my $fh = gensym();
109 13         2011 tie *$fh, 'Test::MockCommand::TiedFH', 0, undef, $self;
110 13         80 return $fh;
111             }
112              
113             sub append_input_data {
114 0     0 1 0 my $self = shift;
115 0   0     0 $self->{input_data} ||= '';
116 0         0 $self->{input_data} .= $_[0];
117             }
118              
119             sub append_output_data {
120 14     14 1 28 my $self = shift;
121 14   50     167 $self->{output_data} ||= '';
122 14         60 $self->{output_data} .= $_[0];
123             }
124              
125             1;
126              
127             __END__