pod4 0.7.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+