pod4 0.7.2 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,299 @@
1
+ require 'date'
2
+ require 'time'
3
+ require 'bigdecimal'
4
+ require 'pod4/sql_helper'
5
+
6
+ class SQLHelperTester1
7
+ include SQLHelper
8
+
9
+ def schema; "marco"; end
10
+ def table; "polo"; end
11
+ def id_fld; "foo"; end
12
+ end
13
+
14
+ class SQLHelperTester2
15
+ include SQLHelper
16
+
17
+ def table; "polo"; end
18
+ end
19
+
20
+
21
+ describe "SQLHelper" do
22
+
23
+ let(:tester1) {SQLHelperTester1.new}
24
+ let(:tester2) {SQLHelperTester2.new}
25
+
26
+
27
+ describe "quoted_table" do
28
+
29
+ it "will be quoted with double quotes" do
30
+ expect( tester2.quoted_table ).to eq %Q|"polo"|
31
+ end
32
+
33
+ it "will the schema plus the table if the schema is set" do
34
+ expect( tester1.quoted_table ).to eq %Q|"marco"."polo"|
35
+ end
36
+
37
+ end
38
+
39
+
40
+ describe "placeholder" do
41
+
42
+ it "will be the ruby sprintf string subst string" do
43
+ expect( tester1.send :placeholder ).to eq "%s"
44
+ end
45
+
46
+ end
47
+
48
+
49
+ describe "quote_field" do
50
+
51
+ it "will wrap the field in double quotes" do
52
+ expect( tester1.send :quote_field, "thing" ).to eq %Q|"thing"|
53
+ end
54
+
55
+ it "will raise an error for a non-string" do
56
+ expect{ tester1.send :quote_field, 12 }.to raise_error ArgumentError
57
+ expect{ tester1.send :quote_field }.to raise_error ArgumentError
58
+ end
59
+
60
+ it "will wrap the field in some other character if you pass that" do
61
+ expect( tester1.send :quote_field, "thing", nil ).to eq %Q|thing|
62
+ expect( tester1.send :quote_field, "thing", "x" ).to eq %Q|xthingx|
63
+ end
64
+
65
+ end
66
+
67
+
68
+ describe "quote" do
69
+ let(:datetime) { "2055-12-31 11:23:36+04" }
70
+ let(:dtmatch) { /'2055.12.31[T ]11.23.36 ?\+04:?00'/ }
71
+
72
+ it "returns a String wrapped in single quotes" do
73
+ expect( tester1.send :quote, "foo" ).to eq %Q|'foo'|
74
+ end
75
+
76
+ it "turns a single quote into a doubled single quote" do
77
+ expect( tester1.send :quote, "G'Kar" ).to eq %Q|'G''Kar'|
78
+ end
79
+
80
+ it "returns date wrapped in a single quote" do
81
+ dt = Date.parse("2055-12-31")
82
+ expect( tester1.send :quote, dt ).to eq %Q|'2055-12-31'|
83
+ end
84
+
85
+ it "returns datetime wrapped in a single quote" do
86
+ dtm = DateTime.parse(datetime)
87
+ expect( tester1.send :quote, dtm ).to match dtmatch
88
+ end
89
+
90
+ it "returns time wrapped in a single quote" do
91
+ tm = Time.parse(datetime)
92
+ expect( tester1.send :quote, tm ).to match dtmatch
93
+ end
94
+
95
+ it "returns a BigDecimal as a float" do
96
+ bd = BigDecimal.new("14.98")
97
+ expect( tester1.send :quote, bd ).to eq 14.98
98
+ end
99
+
100
+ it "returns nil as 'NULL'" do
101
+ expect( tester1.send :quote, nil ).to eq %Q|NULL|
102
+ end
103
+
104
+ it "will wrap the value in some other character if you pass that" do
105
+ bd = BigDecimal.new("14.98")
106
+ expect( tester1.send :quote, "thing", nil ).to eq %Q|thing|
107
+ expect( tester1.send :quote, "thing", "x" ).to eq %Q|xthingx|
108
+ expect( tester1.send :quote, bd ).to eq 14.98
109
+ expect( tester1.send :quote, "G'Kar", "a" ).to eq %Q|aG'Kaara|
110
+ end
111
+
112
+ end
113
+
114
+
115
+ describe "sql_where(selection)" do
116
+
117
+ it "returns an empty string and empty array for an empty selection hash" do
118
+ expect( tester1.send :sql_where, {} ).to eq( [ "", [] ] )
119
+ end
120
+
121
+
122
+ it "returns valid SQL and unchanged array of values for the selection hash" do
123
+ sql, vals = tester1.send :sql_where, {lambs: "baah", pigs: "moo"}
124
+
125
+ expect( sql ).to match %r|where\s+"lambs"\s*=\s*%s\s+and\s+"pigs"\s*=\s*%s|i
126
+ expect( vals ).to eq( [%q|baah|, %q|moo|] )
127
+ end
128
+
129
+ end
130
+
131
+
132
+ describe "sql_select" do
133
+
134
+ it "returns sql plus an array of values" do
135
+ sql, vals = tester1.send( :sql_select, %W|foo bar|, {one: 12} )
136
+ smatch = %r|select\s+"foo",\s*"bar"\s+from\s+"marco"\."polo"\s+where\s+"one"\s*=\s*%s\s*;|i
137
+
138
+ expect(sql).to match(smatch)
139
+ expect(vals).to eq( [12] )
140
+ end
141
+
142
+
143
+ it "copes with nil for fields to select *" do
144
+ sql, vals = tester1.send( :sql_select, nil, {one: 12} )
145
+ smatch = %r|select\s+\*\s*from\s+"marco"\."polo"\s*where\s+"one"\s*=\s*%s\s*;|
146
+
147
+ expect(sql).to match(smatch)
148
+ expect(vals).to eq( [12] )
149
+ end
150
+
151
+ it "copes with one field" do
152
+ sql, vals = tester1.send( :sql_select, "foo", {one: 12} )
153
+ smatch = %r|select\s+"foo"\s+from\s+"marco"\."polo"\s+where\s+"one"\s*=\s*%s\s*;|i
154
+
155
+ expect(sql).to match(smatch)
156
+ expect(vals).to eq( [12] )
157
+ end
158
+
159
+
160
+ it "copes with a selection list" do
161
+ sql, vals = tester1.send( :sql_select, nil, {one: 12, two: 23} )
162
+ smatch = %r|select\s+\*\s*from\s+"marco"\."polo"
163
+ \s+where\s+"one"\s*=\s*%s\s+and\s+"two"\s*=\s*%s\s*;|ix
164
+
165
+ expect(sql).to match(smatch)
166
+ expect(vals).to eq( [12,23] )
167
+ end
168
+
169
+ it "copes with no selection list" do
170
+ sql, vals = tester1.send( :sql_select, nil, nil )
171
+ smatch = %r|select\s+\*\s*from\s+"marco"\."polo"\s*;|i
172
+
173
+ expect(sql).to match(smatch)
174
+ expect(vals).to eq( [] )
175
+ end
176
+
177
+ end
178
+
179
+
180
+ describe "sql_insert" do
181
+
182
+ it "raises an exception if there is no column:value hash" do
183
+ expect{ tester1.send :sql_insert, {} }.to raise_error ArgumentError
184
+ end
185
+
186
+ it "returns the correct sql plus an array of values" do
187
+ sel = {bada: "bing", bar: "foop"}
188
+ smatch = %r|insert\s+into\s+"marco"\."polo"
189
+ \s+\(\s*"bada",\s*"bar"\s*\)
190
+ \s+values\(\s*%s,\s*%s\s*\)
191
+ \s+returning\s+"foo"\s*;|xi
192
+
193
+ sql, vals = tester1.send :sql_insert, sel
194
+
195
+ expect(sql).to match smatch
196
+ expect(vals).to eq( ['bing', 'foop'] )
197
+ end
198
+
199
+ end
200
+
201
+
202
+ describe "sql_update" do
203
+
204
+ it "raises an exception if there is no column:value hash" do
205
+ expect{ tester1.send :sql_update, {}, {} }.to raise_error ArgumentError
206
+ end
207
+
208
+ it "returns the correct SQL and values without a selection hash" do
209
+ fv = {mouse: 14, rat: "meow"}
210
+
211
+ smatch = %r|update\s+"marco"\."polo"\s+set
212
+ \s+"mouse"\s*=\s*%s\s*,
213
+ \s+"rat"\s*=\s*%s\s*;|xi
214
+
215
+ sql, vals = tester1.send :sql_update, fv, {}
216
+
217
+ expect(sql).to match smatch
218
+ expect(vals).to eq( [14, 'meow'] )
219
+ end
220
+
221
+
222
+ it "returns the correct SQL and values if there is a selection hash" do
223
+ fv = {mouse: 14, rat: "meow"}
224
+ sel = {row: 5, column: true}
225
+
226
+ smatch = %r|update\s+"marco"\."polo"\s+set
227
+ \s+"mouse"\s*=\s*%s\s*,
228
+ \s+"rat"\s*=\s*%s
229
+ \s+where\s+"row"\s*=\s*%s\s+and\s+"column"\s*=\s*%s\s*;|xi
230
+
231
+ sql, vals = tester1.send :sql_update, fv, sel
232
+
233
+ expect(sql).to match smatch
234
+ expect(vals).to eq( [14, 'meow', 5, true] )
235
+ end
236
+
237
+ end
238
+
239
+
240
+ describe "sql_delete(selection)" do
241
+
242
+ it "returns the correct SQL and values without a selection hash" do
243
+ sql, vals = tester1.send :sql_delete, {}
244
+
245
+ expect(sql).to match %r|delete\s+from\s+"marco"\."polo"\s*;|i
246
+ expect(vals).to eq( [] )
247
+ end
248
+
249
+
250
+ it "returns the correct SQL and values if there is a selection hash" do
251
+ sql, vals = tester1.send :sql_delete, {alice: 14, ted: "moo"}
252
+ smatch = %r|delete\s+from\s+"marco"\."polo"
253
+ \s+where\s+"alice"\s*=\s*%s\s+and\s+"ted"\s*=\s*%s\s*;|ix
254
+
255
+ expect(sql).to match smatch
256
+ expect(vals).to eq( [14, 'moo'] )
257
+ end
258
+
259
+ end
260
+
261
+
262
+ describe "sql_subst" do
263
+
264
+ it "raises ArgumentError unless it receives an SQL string" do
265
+ expect{ tester1.send :sql_subst, 19, "foo" }.to raise_error ArgumentError
266
+ end
267
+
268
+ it "returns the sql untouched when there are no values" do
269
+ expect( tester1.send :sql_subst, "foo" ).to eq "foo"
270
+ end
271
+
272
+ it "raises ArgumentError if the sql is blank" do
273
+ expect{ tester1.send :sql_subst, "", 'foo' }.to raise_error ArgumentError
274
+ end
275
+
276
+ it "raises ArgumentError if the # of sql markers and the # of values don't match" do
277
+ # (unless we only pass one value, see below)
278
+ expect{ tester1.send :sql_subst, %q|foo %s %s bar %s|, 1, 2 }.to raise_error ArgumentError
279
+ expect{ tester1.send :sql_subst, %q|foo %s bar %s|, 1, 2, 3 }.to raise_error ArgumentError
280
+ end
281
+
282
+ it "returns complete SQL for sql with markers and a single value" do
283
+ sql = %q|select * from "foo" where "bar" = %s and "baz" = %s;|
284
+ seq = %q|select * from "foo" where "bar" = 'boing' and "baz" = 'boing';|
285
+
286
+ expect( tester1.send :sql_subst, sql, %q|'boing'| ).to eq seq
287
+ end
288
+
289
+ it "returns complete SQL for sql with markers and the right number of values in the array" do
290
+ sql = %q|select * from "foo" where "bar" = %s and "baz" = %s;|
291
+ seq = %q|select * from "foo" where "bar" = 'boing' and "baz" = 'bop';|
292
+
293
+ expect( tester1.send :sql_subst, sql, %q|'boing'|, %q|'bop'| ).to eq seq
294
+ end
295
+
296
+ end
297
+
298
+ end
299
+