File Coverage

blib/lib/Evo/Test/Mock.pm
Criterion Covered Total %
statement 70 70 100.0
branch 22 30 73.3
condition 3 3 100.0
subroutine 15 15 100.0
pod 0 4 0.0
total 110 122 90.1


line stmt bran cond sub pod time code
1             package Evo::Test::Mock;
2 3     3   1914 use Evo '-Class *; -Export; Carp croak; -Lib eval_want strict_opts; /::Call';
  3         9  
  3         26  
3 3     3   1758 use Hash::Util::FieldHash 'fieldhash';
  3         2369  
  3         533  
4              
5             fieldhash my %REG;
6              
7             has 'original_sub';
8             has 'original_name';
9             has 'calls';
10             has 'sub';
11              
12             our $ORIGINAL;
13              
14 6 50   6 0 25 sub get_original() : prototype() : Export {
  6         10  
15 6 50       21 $ORIGINAL or die "Not in mocked subroutine";
16 3     3   24 }
  3         6  
  3         24  
17              
18 3     3 0 552 sub call_original : Export { get_original->(@_); }
  3     5   7  
  3         12  
  5         22  
19              
20 12 50   12 0 86 sub create_mock ($me, $name, @args) {
  12         25  
  12         18  
  12         35  
  12         23  
21 12         17 my %args;
22 12 100       44 %args = @args == 1 ? (patch => $args[0]) : @args;
23 12         50 my ($patch, $rethrow) = strict_opts \%args, [qw(patch rethrow)], 2;
24              
25 3     3   611 no strict 'refs'; ## no critic
  3         7  
  3         819  
26 12 100       24 my $orig = *{$name}{CODE} or die "No sub $name";
  12         55  
27 11 100       223 croak "$name was already mocked" if $REG{$orig};
28              
29 10 100   2   41 my $mock_sub = ref $patch eq 'CODE' ? $patch : $patch ? sub { call_original(@_) } : sub { };
  2 100       7  
30              
31 10         17 my $calls = [];
32             my $sub = sub {
33 10     10   1263 local $ORIGINAL = $orig;
34 10         33 my $rfn = eval_want wantarray, @_, $mock_sub;
35 10         39 my $err = $@;
36 10         73 my $call = Evo::Test::Call->new(args => \@_, exception => $err, result_fn => $rfn);
37 10         25 push $calls->@*, $call;
38 10 100 100     162 croak $err if !$rfn && $rethrow;
39 9 100       24 return unless $rfn;
40 7         16 $rfn->();
41 10         34 };
42              
43 10         116 my $mock = $me->new(original_sub => $orig, original_name => $name, sub => $sub, calls => $calls);
44              
45 3     3   22 no warnings 'redefine';
  3         7  
  3         554  
46 10         55 $REG{$sub}++;
47 10         18 *{$name} = $sub;
  10         29  
48 10         34 $mock;
49             }
50              
51 7 50   7 0 28 sub get_call ($self, $n) {
  7 50       19  
  7         14  
  7         11  
  7         10  
52 7 50       29 return unless exists $self->calls->[$n];
53 7         60 $self->calls->[$n];
54             }
55              
56 10 50   10   3668 sub DESTROY($self) {
  10 50       26  
  10         18  
  10         15  
57             ## no critic;
58 3     3   21 no strict 'refs';
  3         17  
  3         86  
59 3     3   17 no warnings 'redefine';
  3         8  
  3         275  
60 10         29 *{${\$self->original_name}} = $self->original_sub;
  10         15  
  10         160  
61             }
62              
63              
64             1;
65              
66             __END__