File Coverage

blib/lib/Test/Double/Mock/Expectation.pm
Criterion Covered Total %
statement 85 85 100.0
branch 29 30 96.6
condition n/a
subroutine 28 28 100.0
pod 7 9 77.7
total 149 152 98.0


line stmt bran cond sub pod time code
1             package Test::Double::Mock::Expectation;
2              
3 9     9   119 use strict;
  9         14  
  9         262  
4 9     9   40 use warnings;
  9         15  
  9         235  
5 9     9   7759 use List::MoreUtils qw(each_array);
  9         10652  
  9         805  
6 9     9   8582 use Test::Deep qw(cmp_details);
  9         212122  
  9         1013  
7 9     9   7906 use Test::More;
  9         46961  
  9         91  
8              
9             sub new {
10 32     32 0 96 my ($class, %args) = @_;
11             bless {
12 9     9   16 behavior => sub {},
13 32         280 %args,
14             called => 0,
15             }, $class;
16             }
17              
18             sub with {
19 9     9 1 20 my ($self, @args) = @_;
20 9         24 $self->{with_args} = \@args;
21 9         32 $self;
22             }
23              
24             sub at_least {
25 6     6 1 11 my ($self, $at_least) = @_;
26 6         26 $self->{at_least} = $at_least;
27 6         35 return $self;
28             }
29              
30             sub at_most {
31 5     5 1 8 my ($self, $at_most) = @_;
32 5         21 $self->{at_most} = $at_most;
33 5         25 return $self;
34             }
35              
36             sub times {
37 5     5 1 12 my ($self, $times) = @_;
38 5         12 $self->{times} = $times;
39 5         15 return $self;
40             }
41              
42             sub returns {
43 27     27 1 45 my ($self, $behavior) = @_;
44 27 50       68 if (defined $behavior) {
45 27 100   32   124 $self->{behavior} = ref($behavior) eq 'CODE' ? $behavior : sub { $behavior };
  32         90  
46             }
47 27         102 $self;
48             }
49              
50             sub behavior {
51 32     32 0 2235 my $self = shift;
52             return sub {
53 43     43   80 my ($instance, @args) = @_;
        45      
        17      
        6      
        6      
        6      
        6      
        6      
54 43         63 $self->{called}++;
55 43 100       128 if ($self->{with_args}) {
56 9         36 $self->_check_with($self->{called}, @args)
57             }
58 43         94 return $self->{behavior}->();
59 32         252 };
60             }
61              
62             sub _check_with {
63 9     9   15 my ($self, $counter, @args) = @_;
64 9 100       12 if (scalar @args != scalar @{$self->{with_args}}) {
  9         30  
65 2         8 $self->{with}->{$counter} = 0;
66 2         5 return;
67             }
68 7         17 my $ea = each_array(@{$self->{with_args}}, @args);
  7         81  
69 7         40 while (my ($with_arg, $arg) = $ea->()) {
70 11         36 my ($ok, $stack) = cmp_details($arg, $with_arg);
71 11 100       16539 if ($ok) {
72 8         111 $self->{with}->{$counter} = 1;
73             } else {
74 3         10 $self->{with}->{$counter} = 0;
75 3         34 return;
76             }
77             }
78             }
79              
80             sub _check_at_least {
81 6     6   8 my $self = shift;
82 6 100       37 return $self->{called} < $self->{at_least} ? 0 : 1;
83             }
84              
85             sub _check_at_most {
86 5     5   7 my $self = shift;
87 5 100       26 return $self->{called} > $self->{at_most} ? 0 : 1;
88             }
89              
90             sub _check_at_times {
91 5     5   8 my $self = shift;
92 5 100       27 return $self->{called} != $self->{times} ? 0 : 1;
93             }
94              
95             sub verify_result {
96 31     31 1 37 my $self = shift;
97              
98 31 100       84 if ($self->{at_least}) {
99 6         17 $self->{result}->{at_least} = $self->_check_at_least;
100             }
101 31 100       79 if ($self->{at_most}) {
102 5         14 $self->{result}->{at_most} = $self->_check_at_most;
103             }
104 31 100       76 if ($self->{times}) {
105 5         12 $self->{result}->{times} = $self->_check_at_times;
106             }
107 31         36 for (keys %{$self->{with}}) {
  31         116  
108 15         67 $self->{result}->{with}->{$_} = $self->{with}->{$_};
109             }
110              
111 31         70 return $self->{result};
112              
113             }
114              
115             sub verify {
116 21     21 1 30 my $self = shift;
117              
118 21         54 $self->verify_result;
119 21 100       53 if ($self->{at_least}) {
120 2         14 ok $self->{result}->{at_least},
121             "Expected method must be called at least " . $self->{at_least};
122             }
123 21 100       592 if ($self->{at_most}) {
124 3         17 ok $self->{result}->{at_most},
125             "Expected method must be called at most " . $self->{at_most};
126             }
127 21 100       890 if ($self->{times}) {
128 2         14 ok $self->{result}->{times},
129             "Expected method must be called " . $self->{times} . " times";
130             }
131 21         750 for (keys %{$self->{with}}) {
  21         81  
132 16 100       88 ok $self->{result}->{with}->{$_},
133             "Expected method must be called with "
134 14         97 . join " ", map { ref $_ ? ref $_ : $_ } @{$self->{with_args}};
  14         26  
135             }
136             }
137              
138             1;
139             __END__