sequel 0.2.1.1 → 0.3.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.
@@ -11,7 +11,20 @@ PGSQL_DB.create_table :test do
11
11
  index :value
12
12
  end
13
13
 
14
- context "A MySQL dataset" do
14
+ context "A PostgreSQL database" do
15
+ setup do
16
+ @db = PGSQL_DB
17
+ end
18
+
19
+ specify "should provide disconnect functionality" do
20
+ @db.tables
21
+ @db.pool.size.should == 1
22
+ @db.disconnect
23
+ @db.pool.size.should == 0
24
+ end
25
+ end
26
+
27
+ context "A PostgreSQL dataset" do
15
28
  setup do
16
29
  @d = PGSQL_DB[:test]
17
30
  @d.delete # remove all records
@@ -25,24 +38,19 @@ context "A MySQL dataset" do
25
38
  @d.count.should == 3
26
39
  end
27
40
 
28
- # specify "should return the last inserted id when inserting records" do
29
- # id = @d << {:name => 'abc', :value => 1.23}
30
- # id.should == @d.first[:id]
31
- # end
32
- #
33
-
34
- specify "should return all records" do
41
+ specify "should return the correct records" do
42
+ @d.to_a.should == []
35
43
  @d << {:name => 'abc', :value => 123}
36
44
  @d << {:name => 'abc', :value => 456}
37
45
  @d << {:name => 'def', :value => 789}
38
-
39
- @d.order(:value).all.should == [
46
+
47
+ @d.order(:value).to_a.should == [
40
48
  {:name => 'abc', :value => 123},
41
49
  {:name => 'abc', :value => 456},
42
50
  {:name => 'def', :value => 789}
43
51
  ]
44
52
  end
45
-
53
+
46
54
  specify "should update records correctly" do
47
55
  @d << {:name => 'abc', :value => 123}
48
56
  @d << {:name => 'abc', :value => 456}
@@ -84,4 +92,50 @@ context "A MySQL dataset" do
84
92
  @d.filter(:name => /bc/).count.should == 2
85
93
  @d.filter(:name => /^bc/).count.should == 1
86
94
  end
87
- end
95
+ end
96
+
97
+ context "A PostgreSQL dataset in array tuples mode" do
98
+ setup do
99
+ @d = PGSQL_DB[:test]
100
+ @d.delete # remove all records
101
+ Sequel.use_array_tuples
102
+ end
103
+
104
+ teardown do
105
+ Sequel.use_hash_tuples
106
+ end
107
+
108
+ specify "should return the correct records" do
109
+ @d.to_a.should == []
110
+ @d << {:name => 'abc', :value => 123}
111
+ @d << {:name => 'abc', :value => 456}
112
+ @d << {:name => 'def', :value => 789}
113
+
114
+ @d.order(:value).select(:name, :value).to_a.should == [
115
+ ['abc', 123],
116
+ ['abc', 456],
117
+ ['def', 789]
118
+ ]
119
+ end
120
+
121
+ specify "should work correctly with transforms" do
122
+ @d.transform(:value => [proc {|v| v.to_s}, proc {|v| v.to_i}])
123
+
124
+ @d.to_a.should == []
125
+ @d << {:name => 'abc', :value => 123}
126
+ @d << {:name => 'abc', :value => 456}
127
+ @d << {:name => 'def', :value => 789}
128
+
129
+ @d.order(:value).select(:name, :value).to_a.should == [
130
+ ['abc', '123'],
131
+ ['abc', '456'],
132
+ ['def', '789']
133
+ ]
134
+
135
+ a = @d.order(:value).first
136
+ a.values.should == ['abc', '123']
137
+ a.keys.should == [:name, :value]
138
+ a[:name].should == 'abc'
139
+ a[:value].should == '123'
140
+ end
141
+ end
@@ -72,6 +72,54 @@ context "An SQLite database" do
72
72
 
73
73
  @db[:t].order(:name).map(:name).should == ['abc', 'def']
74
74
  end
75
+
76
+ specify "should be able to execute transactions" do
77
+ @db.transaction do
78
+ @db.create_table(:t) {text :name}
79
+ end
80
+
81
+ @db.tables.should == [:t]
82
+
83
+ proc {@db.transaction do
84
+ @db.create_table(:u) {text :name}
85
+ raise ArgumentError
86
+ end}.should raise_error(ArgumentError)
87
+ # no commit
88
+ @db.tables.should == [:t]
89
+
90
+ proc {@db.transaction do
91
+ @db.create_table(:v) {text :name}
92
+ rollback!
93
+ end}.should_not raise_error
94
+ # no commit
95
+ @db.tables.should == [:t]
96
+ end
97
+
98
+ specify "should support nested transactions" do
99
+ @db.transaction do
100
+ @db.transaction do
101
+ @db.create_table(:t) {text :name}
102
+ end
103
+ end
104
+
105
+ @db.tables.should == [:t]
106
+
107
+ proc {@db.transaction do
108
+ @db.create_table(:v) {text :name}
109
+ @db.transaction do
110
+ rollback! # should roll back the top-level transaction
111
+ end
112
+ end}.should_not raise_error
113
+ # no commit
114
+ @db.tables.should == [:t]
115
+ end
116
+
117
+ specify "should provide disconnect functionality" do
118
+ @db.tables
119
+ @db.pool.size.should == 1
120
+ @db.disconnect
121
+ @db.pool.size.should == 0
122
+ end
75
123
  end
76
124
 
77
125
  context "An SQLite dataset" do
@@ -80,6 +128,18 @@ context "An SQLite dataset" do
80
128
  @d.delete # remove all records
81
129
  end
82
130
 
131
+ specify "should return the correct records" do
132
+ @d.to_a.should == []
133
+ @d << {:name => 'abc', :value => 1.23}
134
+ @d << {:name => 'abc', :value => 4.56}
135
+ @d << {:name => 'def', :value => 7.89}
136
+ @d.select(:name, :value).to_a.sort_by {|h| h[:value]}.should == [
137
+ {:name => 'abc', :value => 1.23},
138
+ {:name => 'abc', :value => 4.56},
139
+ {:name => 'def', :value => 7.89}
140
+ ]
141
+ end
142
+
83
143
  specify "should return the correct record count" do
84
144
  @d.count.should == 0
85
145
  @d << {:name => 'abc', :value => 1.23}
@@ -87,7 +147,7 @@ context "An SQLite dataset" do
87
147
  @d << {:name => 'def', :value => 7.89}
88
148
  @d.count.should == 3
89
149
  end
90
-
150
+
91
151
  specify "should return the last inserted id when inserting records" do
92
152
  id = @d << {:name => 'abc', :value => 1.23}
93
153
  id.should == @d.first[:id]
@@ -186,3 +246,55 @@ context "SQLite::Dataset#update" do
186
246
  end
187
247
  end
188
248
 
249
+ context "An SQLite dataset in array tuples mode" do
250
+ setup do
251
+ @d = SQLITE_DB[:items]
252
+ @d.delete # remove all records
253
+
254
+ Sequel.use_array_tuples
255
+ end
256
+
257
+ teardown do
258
+ Sequel.use_hash_tuples
259
+ end
260
+
261
+ specify "should return the correct records" do
262
+ @d.to_a.should == []
263
+ @d << {:name => 'abc', :value => 1.23}
264
+ @d << {:name => 'abc', :value => 4.56}
265
+ @d << {:name => 'def', :value => 7.89}
266
+ @d.select(:name, :value).to_a.sort_by {|h| h[:value]}.should == [
267
+ Array.from_hash({:name => 'abc', :value => 1.23}),
268
+ Array.from_hash({:name => 'abc', :value => 4.56}),
269
+ Array.from_hash({:name => 'def', :value => 7.89})
270
+ ]
271
+ end
272
+ end
273
+
274
+ context "SQLite dataset" do
275
+ setup do
276
+ SQLITE_DB.create_table :test do
277
+ integer :id, :primary_key => true, :auto_increment => true
278
+ text :name
279
+ float :value
280
+ end
281
+
282
+ @d = SQLITE_DB[:items]
283
+ @d.delete # remove all records
284
+ @d << {:name => 'abc', :value => 1.23}
285
+ @d << {:name => 'def', :value => 4.56}
286
+ @d << {:name => 'ghi', :value => 7.89}
287
+ end
288
+
289
+ teardown do
290
+ SQLITE_DB.drop_table :test
291
+ end
292
+
293
+ specify "should be able to insert from a subquery" do
294
+ SQLITE_DB[:test] << @d
295
+ SQLITE_DB[:test].count.should == 3
296
+ SQLITE_DB[:test].select(:name, :value).order(:value).to_a.should == \
297
+ @d.select(:name, :value).order(:value).to_a
298
+ end
299
+ end
300
+
@@ -0,0 +1,544 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ context "An array with symbol keys" do
4
+ setup do
5
+ @a = [1, 2, 3]
6
+ @a.keys = [:a, :b, :c]
7
+ end
8
+
9
+ specify "should provide subscript access" do
10
+ @a[0].should == 1
11
+ @a[0..1].should == [1, 2]
12
+
13
+ @a[1] = 4
14
+ @a.should == [1, 4, 3]
15
+ end
16
+
17
+ specify "should provide key access using symbols" do
18
+ @a[:a].should == 1
19
+ @a[:b].should == 2
20
+ @a[:B].should == nil
21
+
22
+ @a[:a] = 11
23
+ @a.should == [11, 2, 3]
24
+ @a[:a].should == 11
25
+
26
+ @a[:d] = 4
27
+ @a.should == [11, 2, 3, 4]
28
+ @a.keys.should == [:a, :b, :c, :d]
29
+ end
30
+
31
+ specify "should provide key acess using strings" do
32
+ @a['a'].should == 1
33
+ @a['A'].should be_nil
34
+
35
+ @a['d'] = 4
36
+ @a.should == [1, 2, 3, 4]
37
+ @a.keys.should == [:a, :b, :c, :d]
38
+ end
39
+
40
+ specify "should provide #store functionality" do
41
+ @a.store(:a, 11)
42
+ @a.should == [11, 2, 3]
43
+
44
+ @a.store(:d, 4)
45
+ @a.should == [11, 2, 3, 4]
46
+
47
+ @a.store('d', 44)
48
+ @a.should == [11, 2, 3, 44]
49
+ end
50
+
51
+ specify "should provide #to_hash/#to_h functionality" do
52
+ @a.to_hash.should == {:a => 1, :b => 2, :c => 3}
53
+ @a.to_h.should == {:a => 1, :b => 2, :c => 3}
54
+ end
55
+
56
+ specify "should provide #fields as alias to #keys" do
57
+ @a.fields.should == [:a, :b, :c]
58
+ @a.fields = [:x, :y, :z]
59
+
60
+ @a[:x].should == 1
61
+ end
62
+
63
+ specify "should provide #slice functionality with keys" do
64
+ s = @a.slice(0, 2)
65
+ s.should == [1, 2]
66
+ s.keys.should == [:a, :b]
67
+
68
+ s = @a.slice(1..2)
69
+ s.should == [2, 3]
70
+ s.keys.should == [:b, :c]
71
+ end
72
+
73
+ specify "should provide #each_pair iterator" do
74
+ pairs = []
75
+ @a.each_pair {|k, v| pairs << [k, v]}
76
+ pairs.should == [[:a, 1], [:b, 2], [:c, 3]]
77
+ end
78
+
79
+ specify "should provide stock #delete functionality for arrays without keys" do
80
+ a = [1, 2, 3]
81
+ a.delete(2)
82
+ a.should == [1, 3]
83
+ end
84
+
85
+ specify "should provide key-based #delete functionality" do
86
+ @a.delete(:b)
87
+ @a.should == [1, 3]
88
+ @a.keys.should == [:a, :c]
89
+ @a[:a].should == 1
90
+ @a[:c].should == 3
91
+ end
92
+
93
+ specify "should separate array keys after #delete/#delete_at" do
94
+ b = @a.dup
95
+
96
+ b.delete(:b)
97
+
98
+ @a.keys.should == [:a, :b, :c]
99
+ b.keys.should == [:a, :c]
100
+ @a.should == [1, 2, 3]
101
+ b.should == [1, 3]
102
+ @a[:b].should == 2
103
+ b[:b].should == nil
104
+ end
105
+
106
+ specify "should provide #each_key functionality" do
107
+ keys = []
108
+ @a.each_key {|k| keys << k}
109
+ keys.should == [:a, :b, :c]
110
+ end
111
+
112
+ specify "should provide #each_value functionality" do
113
+ values = []
114
+ @a.each_value {|v| values << v}
115
+ values.should == [1, 2, 3]
116
+ end
117
+
118
+ specify "should provide stock #include? functionality for arrays without keys" do
119
+ [1, 2, 3].include?(2).should be_true
120
+ [1, 2, 3].include?(4).should be_false
121
+ end
122
+
123
+ specify "should provide #has_key?/#member?/#key?/#include? functionality" do
124
+ @a.has_key?(:a).should be_true
125
+ @a.has_key?(:b).should be_true
126
+ @a.has_key?(:c).should be_true
127
+ @a.has_key?(:B).should be_false
128
+ @a.has_key?(:d).should be_false
129
+
130
+ @a.has_key?('a').should be_true
131
+ @a.has_key?('b').should be_true
132
+ @a.has_key?('c').should be_true
133
+ @a.has_key?('A').should be_false
134
+ @a.has_key?('d').should be_false
135
+
136
+ @a.key?(:a).should be_true
137
+ @a.key?(:b).should be_true
138
+ @a.key?(:c).should be_true
139
+ @a.key?(:B).should be_false
140
+ @a.key?(:d).should be_false
141
+
142
+ @a.key?('a').should be_true
143
+ @a.key?('b').should be_true
144
+ @a.key?('c').should be_true
145
+ @a.key?('A').should be_false
146
+ @a.key?('d').should be_false
147
+
148
+ @a.member?(:a).should be_true
149
+ @a.member?(:b).should be_true
150
+ @a.member?(:c).should be_true
151
+ @a.member?(:B).should be_false
152
+ @a.member?(:d).should be_false
153
+
154
+ @a.member?('a').should be_true
155
+ @a.member?('b').should be_true
156
+ @a.member?('c').should be_true
157
+ @a.member?('A').should be_false
158
+ @a.member?('d').should be_false
159
+
160
+ @a.include?(:a).should be_true
161
+ @a.include?(:b).should be_true
162
+ @a.include?(:c).should be_true
163
+ @a.include?(:B).should be_false
164
+ @a.include?(:d).should be_false
165
+
166
+ @a.include?('a').should be_true
167
+ @a.include?('b').should be_true
168
+ @a.include?('c').should be_true
169
+ @a.include?('A').should be_false
170
+ @a.include?('d').should be_false
171
+ end
172
+
173
+ specify "should provide original #include? functionality for arrays without keys" do
174
+ [1, 2, 3].include?(:a).should be_false
175
+ [1, 2, 3].include?(1).should be_true
176
+ end
177
+
178
+ specify "should provide #has_value?/#value? functionality" do
179
+ @a.has_value?(1).should be_true
180
+ @a.has_value?(2).should be_true
181
+ @a.has_value?(3).should be_true
182
+ @a.has_value?(4).should be_false
183
+
184
+ @a.value?(1).should be_true
185
+ @a.value?(2).should be_true
186
+ @a.value?(3).should be_true
187
+ @a.value?(4).should be_false
188
+ end
189
+
190
+ specify "should provide #fetch functionality" do
191
+ @a.fetch(:a).should == 1
192
+ @a.fetch(:b).should == 2
193
+ @a.fetch(:c).should == 3
194
+ proc {@a.fetch(:d)}.should raise_error(IndexError)
195
+ @a.fetch(:d, 4).should == 4
196
+ @a.fetch(:d, nil).should == nil
197
+
198
+ @a.fetch(:a) {|v| v.to_s}.should == '1'
199
+ @a.fetch(:d, 4) {|v| v.to_s}.should == '4'
200
+ end
201
+
202
+ specify "should provide #values functionality" do
203
+ @a.values.should == [1, 2, 3]
204
+ end
205
+
206
+ specify "should provide #dup functionality" do
207
+ b = @a.dup
208
+ b.should == [1, 2, 3]
209
+ b.keys.should == @a.keys
210
+
211
+ b[:a].should == 1
212
+ b[:b].should == 2
213
+ b[:c].should == 3
214
+ b[:d].should be_nil
215
+
216
+ @a.keys << :e
217
+ @a.keys.should == [:a, :b, :c, :e]
218
+ b.keys.should == @a.keys
219
+ end
220
+
221
+ specify "should provide #clone functionality" do
222
+ b = @a.clone
223
+ b.should == [1, 2, 3]
224
+ b.keys.should == @a.keys
225
+
226
+ b[:a].should == 1
227
+ b[:b].should == 2
228
+ b[:c].should == 3
229
+ b[:d].should be_nil
230
+
231
+ @a.keys << :e
232
+ @a.keys.should == [:a, :b, :c, :e]
233
+ b.keys.should_not == @a.keys
234
+ end
235
+
236
+ specify "should provide #merge functionality" do
237
+ @a.merge(@a).to_hash.should == {:a => 1, :b => 2, :c => 3}
238
+
239
+ @a.merge({:b => 22, :d => 4}).to_hash.should == {:a => 1, :b => 22, :c => 3, :d => 4}
240
+
241
+ b = [1, 2, 3]
242
+ b.keys = [:b, :c, :d]
243
+ @a.merge(b).to_hash.should == {:a => 1, :b => 1, :c => 2, :d => 3}
244
+
245
+ # call with a block. The block returns the old value passed to it
246
+ @a.merge(b) {|k, o, n| o}.to_hash.should == {:a => 1, :b => 2, :c => 3, :d => 3}
247
+ end
248
+
249
+ specify "should provide #merge!/#update!/#update functionality" do
250
+ @a.merge!(@a)
251
+ @a.to_hash.should == {:a => 1, :b => 2, :c => 3}
252
+
253
+ @a.update(:b => 22)
254
+ @a.to_hash.should == {:a => 1, :b => 22, :c => 3}
255
+
256
+ b = [1, 2, 3]
257
+ b.keys = [:b, :c, :d]
258
+ @a.update!(b)
259
+ @a.to_hash.should == {:a => 1, :b => 1, :c => 2, :d => 3}
260
+ end
261
+ end
262
+
263
+ context "An array with string keys" do
264
+ setup do
265
+ @a = [1, 2, 3]
266
+ @a.keys = ['a', 'b', 'c']
267
+ end
268
+
269
+ specify "should provide key access using symbols" do
270
+ @a[:a].should == 1
271
+ @a[:b].should == 2
272
+ @a[:B].should == nil
273
+
274
+ @a[:a] = 11
275
+ @a.should == [11, 2, 3]
276
+ @a[:a].should == 11
277
+
278
+ @a[:d] = 4
279
+ @a.should == [11, 2, 3, 4]
280
+ @a.keys.should == ['a', 'b', 'c', :d]
281
+ end
282
+
283
+ specify "should provide key acess using strings" do
284
+ @a['a'].should == 1
285
+ @a['A'].should be_nil
286
+
287
+ @a['d'] = 4
288
+ @a.should == [1, 2, 3, 4]
289
+ @a.keys.should == ['a', 'b', 'c', :d]
290
+ end
291
+
292
+ specify "should provide #store functionality" do
293
+ @a.store(:a, 11)
294
+ @a.should == [11, 2, 3]
295
+
296
+ @a.store(:d, 4)
297
+ @a.should == [11, 2, 3, 4]
298
+
299
+ @a.store('d', 44)
300
+ @a.should == [11, 2, 3, 44]
301
+ end
302
+
303
+ specify "should provide #to_hash/#to_h functionality" do
304
+ @a.to_hash.should == {:a => 1, :b => 2, :c => 3}
305
+ @a.to_h.should == {:a => 1, :b => 2, :c => 3}
306
+ end
307
+
308
+ specify "should provide #fields as alias to #keys" do
309
+ @a.fields.should == ['a', 'b', 'c']
310
+ @a.fields = [:x, :y, :z]
311
+
312
+ @a[:x].should == 1
313
+ end
314
+
315
+ specify "should provide #slice functionality with keys" do
316
+ s = @a.slice(0, 2)
317
+ s.should == [1, 2]
318
+ s.keys.should == ['a', 'b']
319
+
320
+ s = @a.slice(1..2)
321
+ s.should == [2, 3]
322
+ s.keys.should == ['b', 'c']
323
+ end
324
+
325
+ specify "should provide #each_pair iterator" do
326
+ pairs = []
327
+ @a.each_pair {|k, v| pairs << [k, v]}
328
+ pairs.should == [['a', 1], ['b', 2], ['c', 3]]
329
+ end
330
+
331
+ specify "should provide key-based #delete functionality" do
332
+ @a.delete(:b)
333
+ @a.should == [1, 3]
334
+ @a.keys.should == ['a', 'c']
335
+ @a[:a].should == 1
336
+ @a[:c].should == 3
337
+ end
338
+
339
+ specify "should provide #each_key functionality" do
340
+ keys = []
341
+ @a.each_key {|k| keys << k}
342
+ keys.should == ['a', 'b', 'c']
343
+ end
344
+
345
+ specify "should provide #each_value functionality" do
346
+ values = []
347
+ @a.each_value {|v| values << v}
348
+ values.should == [1, 2, 3]
349
+ end
350
+
351
+ specify "should provide #has_key?/#member?/#key?/#include? functionality" do
352
+ @a.has_key?(:a).should be_true
353
+ @a.has_key?(:b).should be_true
354
+ @a.has_key?(:c).should be_true
355
+ @a.has_key?(:B).should be_false
356
+ @a.has_key?(:d).should be_false
357
+
358
+ @a.has_key?('a').should be_true
359
+ @a.has_key?('b').should be_true
360
+ @a.has_key?('c').should be_true
361
+ @a.has_key?('A').should be_false
362
+ @a.has_key?('d').should be_false
363
+
364
+ @a.key?(:a).should be_true
365
+ @a.key?(:b).should be_true
366
+ @a.key?(:c).should be_true
367
+ @a.key?(:B).should be_false
368
+ @a.key?(:d).should be_false
369
+
370
+ @a.key?('a').should be_true
371
+ @a.key?('b').should be_true
372
+ @a.key?('c').should be_true
373
+ @a.key?('A').should be_false
374
+ @a.key?('d').should be_false
375
+
376
+ @a.member?(:a).should be_true
377
+ @a.member?(:b).should be_true
378
+ @a.member?(:c).should be_true
379
+ @a.member?(:B).should be_false
380
+ @a.member?(:d).should be_false
381
+
382
+ @a.member?('a').should be_true
383
+ @a.member?('b').should be_true
384
+ @a.member?('c').should be_true
385
+ @a.member?('A').should be_false
386
+ @a.member?('d').should be_false
387
+
388
+ @a.include?(:a).should be_true
389
+ @a.include?(:b).should be_true
390
+ @a.include?(:c).should be_true
391
+ @a.include?(:B).should be_false
392
+ @a.include?(:d).should be_false
393
+
394
+ @a.include?('a').should be_true
395
+ @a.include?('b').should be_true
396
+ @a.include?('c').should be_true
397
+ @a.include?('A').should be_false
398
+ @a.include?('d').should be_false
399
+ end
400
+
401
+ specify "should provide original #include? functionality for arrays without keys" do
402
+ [1, 2, 3].include?(:a).should be_false
403
+ [1, 2, 3].include?(1).should be_true
404
+ end
405
+
406
+ specify "should provide #has_value?/#value? functionality" do
407
+ @a.has_value?(1).should be_true
408
+ @a.has_value?(2).should be_true
409
+ @a.has_value?(3).should be_true
410
+ @a.has_value?(4).should be_false
411
+
412
+ @a.value?(1).should be_true
413
+ @a.value?(2).should be_true
414
+ @a.value?(3).should be_true
415
+ @a.value?(4).should be_false
416
+ end
417
+
418
+ specify "should provide #fetch functionality" do
419
+ @a.fetch(:a).should == 1
420
+ @a.fetch(:b).should == 2
421
+ @a.fetch(:c).should == 3
422
+ proc {@a.fetch(:d)}.should raise_error(IndexError)
423
+ @a.fetch(:d, 4).should == 4
424
+ @a.fetch(:d, nil).should == nil
425
+
426
+ @a.fetch(:a) {|v| v.to_s}.should == '1'
427
+ @a.fetch(:d, 4) {|v| v.to_s}.should == '4'
428
+ end
429
+
430
+ specify "should provide #values functionality" do
431
+ @a.values.should == [1, 2, 3]
432
+ end
433
+
434
+ specify "should provide #dup functionality" do
435
+ b = @a.dup
436
+ b.should == [1, 2, 3]
437
+ b.keys.should == @a.keys
438
+
439
+ b[:a].should == 1
440
+ b[:b].should == 2
441
+ b[:c].should == 3
442
+ b[:d].should be_nil
443
+
444
+ @a.keys << :e
445
+ @a.keys.should == ['a', 'b', 'c', :e]
446
+ b.keys.should == @a.keys
447
+ end
448
+
449
+ specify "should provide #clone functionality" do
450
+ b = @a.clone
451
+ b.should == [1, 2, 3]
452
+ b.keys.should == @a.keys
453
+
454
+ b[:a].should == 1
455
+ b[:b].should == 2
456
+ b[:c].should == 3
457
+ b[:d].should be_nil
458
+
459
+ @a.keys << :e
460
+ @a.keys.should == ['a', 'b', 'c', :e]
461
+ b.keys.should_not == @a.keys
462
+ end
463
+
464
+ specify "should provide #merge functionality" do
465
+ @a.merge(@a).to_hash.should == {:a => 1, :b => 2, :c => 3}
466
+
467
+ @a.merge({:b => 22, :d => 4}).to_hash.should == {:a => 1, :b => 22, :c => 3, :d => 4}
468
+
469
+ b = [1, 2, 3]
470
+ b.keys = [:b, :c, :d]
471
+ @a.merge(b).to_hash.should == {:a => 1, :b => 1, :c => 2, :d => 3}
472
+
473
+ # call with a block. The block returns the old value passed to it
474
+ @a.merge(b) {|k, o, n| o}.to_hash.should == {:a => 1, :b => 2, :c => 3, :d => 3}
475
+ end
476
+
477
+ specify "should provide #merge!/#update!/#update functionality" do
478
+ @a.merge!(@a)
479
+ @a.to_hash.should == {:a => 1, :b => 2, :c => 3}
480
+
481
+ @a.update(:b => 22)
482
+ @a.to_hash.should == {:a => 1, :b => 22, :c => 3}
483
+
484
+ b = [1, 2, 3]
485
+ b.keys = [:b, :c, :d]
486
+ @a.update!(b)
487
+ @a.to_hash.should == {:a => 1, :b => 1, :c => 2, :d => 3}
488
+ end
489
+ end
490
+
491
+ context "Array.from_hash" do
492
+ specify "should construct an array with keys from a hash" do
493
+ h = {:x => 1, :y => 2, :z => 3}
494
+ a = Array.from_hash(h)
495
+ a.to_hash.should == h
496
+ end
497
+ end
498
+
499
+ context "Sequel.use_array_tuples" do
500
+ setup do
501
+ @c = Class.new(Sequel::Dataset) do
502
+ def fetch_rows(sql, &block)
503
+ block[{:a => 1, :b => 2, :c => 3}]
504
+ end
505
+ end
506
+
507
+ @ds = @c.new(nil).from(:items)
508
+ end
509
+
510
+ teardown do
511
+ Sequel.use_hash_tuples
512
+ end
513
+
514
+ specify "should cause the dataset to return array tuples instead of hashes" do
515
+ @ds.first.should == {:a => 1, :b => 2, :c => 3}
516
+ Sequel.use_array_tuples
517
+ a = @ds.first
518
+ a.class.should == Array
519
+ a.values.sort.should == [1, 2, 3]
520
+ a.keys.map {|k| k.to_s}.sort.should == ['a', 'b', 'c']
521
+ a[:a].should == 1
522
+ a[:b].should == 2
523
+ a[:c].should == 3
524
+ a[:d].should == nil
525
+
526
+ @ds.transform(:a => [proc {|v| v.to_s}, proc {|v| v.to_i}])
527
+ a = @ds.first
528
+ a[:a].should == '1'
529
+
530
+ @ds.transform({})
531
+ a = @ds.first
532
+ a[:a].should == 1
533
+
534
+ @ds.set_model(Hash)
535
+ end
536
+
537
+ specify "should be reversible using Sequel.use_hash_tuples" do
538
+ Sequel.use_array_tuples
539
+ @ds.first.class.should == Array
540
+
541
+ Sequel.use_hash_tuples
542
+ @ds.first.should == {:a => 1, :b => 2, :c => 3}
543
+ end
544
+ end