File Coverage

blib/lib/DBD/Mock/Session.pm
Criterion Covered Total %
statement 81 82 98.7
branch 33 34 97.0
condition 25 27 92.5
subroutine 17 17 100.0
pod 0 8 0.0
total 156 168 92.8


line stmt bran cond sub pod time code
1             package DBD::Mock::Session;
2              
3 39     39   284 use strict;
  39         76  
  39         1149  
4 39     39   196 use warnings;
  39         82  
  39         43121  
5              
6             my $INSTANCE_COUNT = 1;
7              
8             # - Class - #
9              
10             sub new {
11 35     35 0 12568 my $class = shift;
12 35 100       145 my $name = ref( $_[0] ) ? "Session $INSTANCE_COUNT" : shift;
13 35         67 $INSTANCE_COUNT++;
14              
15 35         477 $class->_verify_states( $name, @_ );
16              
17 26         179 bless {
18             name => $name,
19             states => \@_,
20             state_index => 0
21             }, $class;
22             }
23              
24             sub _verify_state {
25 55     55   126 my ( $class, $state, $index, $name ) = @_;
26              
27 55 100       159 die "You must specify session states as HASH refs"
28             if ref($state) ne 'HASH';
29              
30             die "Bad state '$index' in DBD::Mock::Session ($name)"
31             if not exists $state->{statement}
32 52 100 100     243 or not exists $state->{results};
33              
34 49         96 my $stmt = $state->{statement};
35 49         75 my $ref = ref $stmt;
36              
37 49 100 100     227 die "Bad 'statement' value '$stmt' in DBD::Mock::Session ($name)",
      100        
38             if ref($stmt) ne ''
39             and $ref ne 'CODE'
40             and $ref ne 'Regexp';
41             }
42              
43             sub _verify_states {
44 35     35   120 my ( $class, $name, @states ) = @_;
45              
46 35 100       187 die "You must specify at least one session state"
47             if scalar @states == 0;
48              
49 33         152 for ( 0 .. scalar @states - 1 ) {
50 55         178 $class->_verify_state( $states[$_], $_, $name );
51             }
52             }
53              
54             # - Instance - #
55              
56             sub name {
57 6     6 0 2316 my $self = shift;
58 6         37 $self->{name};
59             }
60              
61             sub reset {
62 1     1 0 971 my $self = shift;
63 1         3 $self->{state_index} = 0;
64             }
65              
66             sub current_state {
67 138     138 0 205 my $self = shift;
68 138         227 my $idx = $self->{state_index};
69 138         259 return $self->{states}[$idx];
70             }
71              
72             sub has_states_left {
73 66     66 0 103 my $self = shift;
74 66         146 return $self->{state_index} < $self->_num_states;
75             }
76              
77             sub verify_statement {
78 52     52 0 126 my ( $self, $got ) = @_;
79              
80 52 100       126 unless ( $self->has_states_left ) {
81 6         15 die "Session states exhausted, only '"
82             . $self->_num_states
83             . "' in DBD::Mock::Session ($self->name})";
84             }
85              
86 46         113 my $state = $self->current_state;
87 46         88 my $expected = $state->{statement};
88 46         88 my $ref = ref($expected);
89              
90 46 100 100     194 if ( $ref eq 'Regexp' and $got !~ /$expected/ ) {
91 1         18 die "Statement does not match current state (with Regexp) in "
92             . "DBD::Mock::Session ($self->{name})\n"
93             . " got: $got\n"
94             . " expected: $expected",
95              
96             }
97              
98 45 100 100     161 if ( $ref eq 'CODE' and not $expected->( $got, $state ) ) {
99 1         15 die "Statement does not match current state (with CODE ref) in "
100             . "DBD::Mock::Session ($self->{name})";
101             }
102              
103 44 100 100     239 if ( not $ref and $got ne $expected ) {
104 1         20 die "Statement does not match current state in "
105             . "DBD::Mock::Session ($self->{name})\n"
106             . " got: $got\n"
107             . " expected: $expected";
108             }
109             }
110              
111             sub results_for {
112 46     46 0 100 my ( $self, $statment ) = @_;
113 46         117 $self->_find_state_for($statment)->{results};
114             }
115              
116             sub verify_bound_params {
117 43     43 0 93 my ( $self, $params ) = @_;
118              
119 43         98 my $current_state = $self->current_state;
120 43 100       67 if ( exists ${$current_state}{bound_params} ) {
  43         129  
121 21         49 my $expected = $current_state->{bound_params};
122              
123 21 100       78 if ( scalar @$expected != scalar @$params ) {
124 1         4 die "Not the same number of bound params in current state in "
125             . "DBD::Mock::Session ($self->{name})\n"
126 1         7 . " got: @{$params}"
127 1         12 . " expected: @{$expected}";
128             }
129              
130 20         34 for ( 0 .. scalar @{$params} - 1 ) {
  20         72  
131 26         76 $self->_verify_bound_param( $params->[$_], $expected->[$_], $_ );
132             }
133              
134             }
135              
136             # and make sure we go to
137             # the next statement
138 40         95 $self->{state_index}++;
139             }
140              
141             sub _find_state_for {
142 46     46   90 my ( $self, $statement ) = @_;
143              
144 46         129 foreach ( $self->_remaining_states ) {
145 42         95 my $stmt = $_->{statement};
146 42         77 my $ref = ref($stmt);
147              
148 42 100 100     216 return $_ if ( $ref eq 'Regexp' and $statement =~ /$stmt/ );
149 35 100 66     108 return $_ if ( $ref eq 'CODE' and $stmt->( $statement, $_ ) );
150 31 100 66     219 return $_ if ( not $ref and $stmt eq $statement );
151             }
152              
153 5         63 die "Statement '$statement' not found in session ($self->{name})";
154             }
155              
156             sub _num_states {
157 118     118   163 my $self = shift;
158 118         166 scalar @{ $self->{states} };
  118         1569  
159             }
160              
161             sub _remaining_states {
162 46     46   87 my $self = shift;
163 46         87 my $start_index = $self->{state_index};
164 46         108 my $end_index = $self->_num_states - 1;
165 46         98 @{ $self->{states} }[ $start_index .. $end_index ];
  46         221  
166             }
167              
168             sub _verify_bound_param {
169 26     26   55 my ( $self, $got, $expected, $index ) = @_;
170 39     39   338 no warnings;
  39         97  
  39         7405  
171              
172 26         54 my $ref = ref $expected;
173              
174 26 100       104 if ( $ref eq 'Regexp' ) {
    100          
175              
176 1 50       10 if ( $got !~ /$expected/ ) {
177 0         0 die "Bound param $index do not match (using regexp) "
178             . "in current state in DBD::Mock::Session ($self->{name})"
179             . " got: $got\n"
180             . " expected: $expected";
181             }
182              
183             } elsif ( $got ne $expected ) {
184 2         29 die "Bound param $index do not match "
185             . "in current state in DBD::Mock::Session ($self->{name})\n"
186             . " got: $got\n"
187             . " expected: $expected";
188             }
189             }
190              
191             1;