File Coverage

blib/lib/SQL/Abstract/Test.pm
Criterion Covered Total %
statement 87 106 82.0
branch 41 54 75.9
condition 25 38 65.7
subroutine 14 19 73.6
pod 6 9 66.6
total 173 226 76.5


line stmt bran cond sub pod time code
1             package SQL::Abstract::Test; # see doc at end of file
2              
3 14     14   658509 use strict;
  14         116  
  14         357  
4 14     14   61 use warnings;
  14         24  
  14         344  
5 14     14   61 use base qw(Test::Builder::Module Exporter);
  14         33  
  14         1842  
6 14     14   84 use Test::Builder;
  14         27  
  14         295  
7 14     14   7073 use Test::Deep ();
  14         125515  
  14         352  
8 14     14   6093 use SQL::Abstract::Tree;
  14         80  
  14         15563  
9              
10             our @EXPORT_OK = qw(
11             is_same_sql_bind is_same_sql is_same_bind
12             eq_sql_bind eq_sql eq_bind dumper diag_where
13             $case_sensitive $sql_differ
14             );
15              
16             my $sqlat = SQL::Abstract::Tree->new;
17              
18             our $case_sensitive = 0;
19             our $parenthesis_significant = 0;
20             our $order_by_asc_significant = 0;
21              
22             our $sql_differ; # keeps track of differing portion between SQLs
23             our $tb = __PACKAGE__->builder;
24              
25             sub _unpack_arrayrefref {
26              
27 538     538   781 my @args;
28 538         994 for (1,2) {
29 1076         1616 my $chunk = shift @_;
30              
31 1076 100 66     2376 if (ref $chunk eq 'REF' and ref $$chunk eq 'ARRAY') {
32 3         9 my ($sql, @bind) = @$$chunk;
33 3         8 push @args, ($sql, \@bind);
34             }
35             else {
36 1073         2111 push @args, $chunk, shift @_;
37             }
38              
39             }
40              
41             # maybe $msg and ... stuff
42 538         751 push @args, @_;
43              
44 538         1499 @args;
45             }
46              
47             sub is_same_sql_bind {
48 534     534 1 122163 my ($sql1, $bind_ref1, $sql2, $bind_ref2, $msg) = &_unpack_arrayrefref;
49              
50             # compare
51 534         1252 my $same_sql = eq_sql($sql1, $sql2);
52 534         1008 my $same_bind = eq_bind($bind_ref1, $bind_ref2);
53              
54             # call Test::Builder::ok
55 534   33     646117 my $ret = $tb->ok($same_sql && $same_bind, $msg);
56              
57             # add debugging info
58 534 50       132932 if (!$same_sql) {
59 0         0 _sql_differ_diag($sql1, $sql2);
60             }
61 534 50       1139 if (!$same_bind) {
62 0         0 _bind_differ_diag($bind_ref1, $bind_ref2);
63             }
64              
65             # pass ok() result further
66 534         2920 return $ret;
67             }
68              
69             sub is_same_sql {
70 35     35 1 3983 my ($sql1, $sql2, $msg) = @_;
71              
72             # compare
73 35         75 my $same_sql = eq_sql($sql1, $sql2);
74              
75             # call Test::Builder::ok
76 35         138 my $ret = $tb->ok($same_sql, $msg);
77              
78             # add debugging info
79 35 50       9478 if (!$same_sql) {
80 0         0 _sql_differ_diag($sql1, $sql2);
81             }
82              
83             # pass ok() result further
84 35         99 return $ret;
85             }
86              
87             sub is_same_bind {
88 1     1 1 6 my ($bind_ref1, $bind_ref2, $msg) = @_;
89              
90             # compare
91 1         5 my $same_bind = eq_bind($bind_ref1, $bind_ref2);
92              
93             # call Test::Builder::ok
94 1         881 my $ret = $tb->ok($same_bind, $msg);
95              
96             # add debugging info
97 1 50       244 if (!$same_bind) {
98 0         0 _bind_differ_diag($bind_ref1, $bind_ref2);
99             }
100              
101             # pass ok() result further
102 1         3 return $ret;
103             }
104              
105             sub dumper {
106             # FIXME
107             # if we save the instance, we will end up with $VARx references
108             # no time to figure out how to avoid this (Deepcopy is *not* an option)
109 0     0 0 0 require Data::Dumper;
110 0         0 Data::Dumper->new([])->Terse(1)->Indent(1)->Useqq(1)->Deparse(1)->Quotekeys(0)->Sortkeys(1)->Maxdepth(0)
111             ->Values([@_])->Dump;
112             }
113              
114             sub diag_where{
115 0     0 0 0 $tb->diag("Search term:\n" . &dumper);
116             }
117              
118             sub _sql_differ_diag {
119 0   0 0   0 my $sql1 = shift || '';
120 0   0     0 my $sql2 = shift || '';
121              
122 0 0       0 $tb->${\($tb->in_todo ? 'note' : 'diag')} (
  0         0  
123             "SQL expressions differ\n"
124             ." got: $sql1\n"
125             ."want: $sql2\n"
126             ."\nmismatch around\n$sql_differ\n"
127             );
128             }
129              
130             sub _bind_differ_diag {
131 0     0   0 my ($bind_ref1, $bind_ref2) = @_;
132              
133 0 0       0 $tb->${\($tb->in_todo ? 'note' : 'diag')} (
  0         0  
134             "BIND values differ " . dumper({ got => $bind_ref1, want => $bind_ref2 })
135             );
136             }
137              
138             sub eq_sql_bind {
139 4     4 1 3030 my ($sql1, $bind_ref1, $sql2, $bind_ref2) = &_unpack_arrayrefref;
140              
141 4   100     10 return eq_sql($sql1, $sql2) && eq_bind($bind_ref1, $bind_ref2);
142             }
143              
144              
145 667     667 1 235969 sub eq_bind { goto &Test::Deep::eq_deeply };
146              
147             sub eq_sql {
148 2211     2211 1 441094 my ($sql1, $sql2) = @_;
149              
150             # parse
151 2211         6592 my $tree1 = $sqlat->parse($sql1);
152 2211         5605 my $tree2 = $sqlat->parse($sql2);
153              
154 2211         3903 undef $sql_differ;
155 2211 100       4560 return 1 if _eq_sql($tree1, $tree2);
156             }
157              
158             sub _eq_sql {
159 39540     39540   52613 my ($left, $right) = @_;
160              
161             # one is defined the other not
162 39540 100 100     135134 if ((defined $left) xor (defined $right)) {
    100 100        
    100          
163 21 100       54 $sql_differ = sprintf ("[%s] != [%s]\n", map { defined $_ ? $sqlat->unparse($_) : 'N/A' } ($left, $right) );
  42         160  
164 21         62 return 0;
165             }
166              
167             # one is undefined, then so is the other
168             elsif (not defined $left) {
169 1044         1746 return 1;
170             }
171              
172             # both are empty
173             elsif (@$left == 0 and @$right == 0) {
174 18         34 return 1;
175             }
176              
177             # one is empty
178 38457 100 100     145393 if (@$left == 0 or @$right == 0) {
    50 50        
    100          
179 9 100       18 $sql_differ = sprintf ("left: %s\nright: %s\n", map { @$_ ? $sqlat->unparse($_) : 'N/A'} ($left, $right) );
  18         67  
180 9         23 return 0;
181             }
182              
183             # one is a list, the other is an op with a list
184             elsif (ref $left->[0] xor ref $right->[0]) {
185             $sql_differ = sprintf ("[%s] != [%s]\nleft: %s\nright: %s\n", map
186 0 0       0 { ref $_ ? $sqlat->unparse($_) : $_ }
  0         0  
187             ($left->[0], $right->[0], $left, $right)
188             );
189 0         0 return 0;
190             }
191              
192             # both are lists
193             elsif (ref $left->[0]) {
194 14373   100     29367 for (my $i = 0; $i <= $#$left or $i <= $#$right; $i++ ) {
195 23060 100       35469 if (not _eq_sql ($left->[$i], $right->[$i]) ) {
196 4348 100 66     16670 if (! $sql_differ or $sql_differ !~ /left\:\s .+ right:\s/xs) {
197 886   50     1562 $sql_differ ||= '';
198 886 50       2685 $sql_differ .= "\n" unless $sql_differ =~ /\n\z/;
199 886         1721 $sql_differ .= sprintf ("left: %s\nright: %s\n", map { $sqlat->unparse($_) } ($left, $right) );
  1772         3597  
200             }
201 4348         21797 return 0;
202             }
203             }
204 10025         22630 return 1;
205             }
206              
207             # both are ops
208             else {
209              
210             # unroll parenthesis if possible/allowed
211 24075 100       35042 unless ($parenthesis_significant) {
212 23818         51502 $sqlat->_parenthesis_unroll($_) for $left, $right;
213             }
214              
215             # unroll ASC order by's
216 24075 100       35635 unless ($order_by_asc_significant) {
217 24057         47198 $sqlat->_strip_asc_from_order_by($_) for $left, $right;
218             }
219              
220 24075 100       47086 if ($left->[0] ne $right->[0]) {
    100          
221 378         1159 $sql_differ = sprintf "OP [$left->[0]] != [$right->[0]] in\nleft: %s\nright: %s\n",
222             $sqlat->unparse($left),
223             $sqlat->unparse($right)
224             ;
225 378         1044 return 0;
226             }
227              
228             # literals have a different arg-sig
229             elsif ($left->[0] eq '-LITERAL') {
230 9428         42459 (my $l = " $left->[1][0] " ) =~ s/\s+/ /g;
231 9428         27890 (my $r = " $right->[1][0] ") =~ s/\s+/ /g;
232 9428 50       21054 my $eq = $case_sensitive ? $l eq $r : uc($l) eq uc($r);
233 9428 100       15119 $sql_differ = "[$l] != [$r]\n" if not $eq;
234 9428         33261 return $eq;
235             }
236              
237             # if operators are identical, compare operands
238             else {
239 14269         23746 my $eq = _eq_sql($left->[1], $right->[1]);
240 14269 100 33     22242 $sql_differ ||= sprintf ("left: %s\nright: %s\n", map { $sqlat->unparse($_) } ($left, $right) ) if not $eq;
  0         0  
241 14269         31463 return $eq;
242             }
243             }
244             }
245              
246 0     0 0   sub parse { $sqlat->parse(@_) }
247             1;
248              
249              
250             __END__