sequel 4.1.1 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +32 -0
  3. data/doc/opening_databases.rdoc +4 -0
  4. data/doc/release_notes/4.2.0.txt +129 -0
  5. data/lib/sequel/adapters/jdbc/hsqldb.rb +5 -0
  6. data/lib/sequel/adapters/mysql2.rb +2 -1
  7. data/lib/sequel/adapters/postgres.rb +8 -4
  8. data/lib/sequel/adapters/shared/db2.rb +5 -0
  9. data/lib/sequel/adapters/shared/mssql.rb +15 -4
  10. data/lib/sequel/adapters/shared/mysql.rb +1 -0
  11. data/lib/sequel/adapters/shared/oracle.rb +1 -1
  12. data/lib/sequel/adapters/shared/postgres.rb +10 -0
  13. data/lib/sequel/adapters/shared/sqlite.rb +5 -0
  14. data/lib/sequel/database/features.rb +6 -1
  15. data/lib/sequel/database/schema_methods.rb +3 -7
  16. data/lib/sequel/dataset/actions.rb +3 -4
  17. data/lib/sequel/dataset/features.rb +5 -0
  18. data/lib/sequel/dataset/misc.rb +28 -3
  19. data/lib/sequel/dataset/mutation.rb +37 -11
  20. data/lib/sequel/dataset/prepared_statements.rb +1 -3
  21. data/lib/sequel/dataset/query.rb +12 -3
  22. data/lib/sequel/dataset/sql.rb +12 -6
  23. data/lib/sequel/deprecated.rb +1 -1
  24. data/lib/sequel/extensions/columns_introspection.rb +1 -1
  25. data/lib/sequel/extensions/core_extensions.rb +0 -2
  26. data/lib/sequel/extensions/empty_array_ignore_nulls.rb +1 -1
  27. data/lib/sequel/extensions/filter_having.rb +1 -1
  28. data/lib/sequel/extensions/from_block.rb +31 -0
  29. data/lib/sequel/extensions/graph_each.rb +1 -1
  30. data/lib/sequel/extensions/hash_aliases.rb +1 -1
  31. data/lib/sequel/extensions/mssql_emulate_lateral_with_apply.rb +78 -0
  32. data/lib/sequel/extensions/pagination.rb +1 -1
  33. data/lib/sequel/extensions/pg_loose_count.rb +32 -0
  34. data/lib/sequel/extensions/pg_static_cache_updater.rb +133 -0
  35. data/lib/sequel/extensions/pretty_table.rb +1 -1
  36. data/lib/sequel/extensions/query.rb +3 -1
  37. data/lib/sequel/extensions/query_literals.rb +1 -1
  38. data/lib/sequel/extensions/select_remove.rb +1 -1
  39. data/lib/sequel/extensions/sequel_3_dataset_methods.rb +1 -1
  40. data/lib/sequel/extensions/set_overrides.rb +1 -1
  41. data/lib/sequel/model.rb +1 -1
  42. data/lib/sequel/model/base.rb +20 -6
  43. data/lib/sequel/model/exceptions.rb +1 -1
  44. data/lib/sequel/plugins/composition.rb +9 -0
  45. data/lib/sequel/plugins/dirty.rb +19 -8
  46. data/lib/sequel/plugins/instance_filters.rb +9 -0
  47. data/lib/sequel/plugins/serialization.rb +9 -0
  48. data/lib/sequel/plugins/serialization_modification_detection.rb +9 -0
  49. data/lib/sequel/plugins/static_cache.rb +96 -28
  50. data/lib/sequel/version.rb +2 -2
  51. data/spec/adapters/mssql_spec.rb +1 -1
  52. data/spec/adapters/postgres_spec.rb +70 -0
  53. data/spec/core/dataset_spec.rb +58 -1
  54. data/spec/core/deprecated_spec.rb +1 -1
  55. data/spec/core/schema_spec.rb +18 -0
  56. data/spec/extensions/composition_spec.rb +7 -0
  57. data/spec/extensions/dirty_spec.rb +9 -0
  58. data/spec/extensions/from_block_spec.rb +21 -0
  59. data/spec/extensions/instance_filters_spec.rb +6 -0
  60. data/spec/extensions/pg_loose_count_spec.rb +17 -0
  61. data/spec/extensions/pg_static_cache_updater_spec.rb +80 -0
  62. data/spec/extensions/query_spec.rb +8 -0
  63. data/spec/extensions/serialization_modification_detection_spec.rb +9 -0
  64. data/spec/extensions/serialization_spec.rb +7 -0
  65. data/spec/extensions/set_overrides_spec.rb +12 -0
  66. data/spec/extensions/static_cache_spec.rb +314 -154
  67. data/spec/integration/dataset_test.rb +12 -2
  68. data/spec/integration/schema_test.rb +13 -0
  69. data/spec/model/record_spec.rb +74 -0
  70. metadata +13 -3
@@ -1,195 +1,355 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
- describe "Sequel::Plugins::StaticCache" do
3
+ describe "Sequel::Plugins::StaticCache with :frozen=>false option" do
4
4
  before do
5
5
  @db = Sequel.mock
6
6
  @db.fetch = [{:id=>1}, {:id=>2}]
7
+ @db.numrows = 1
7
8
  @c = Class.new(Sequel::Model(@db[:t]))
8
- @c.columns :id
9
- @c.plugin :static_cache
10
- @c1 = @c.cache[1]
11
- @c2 = @c.cache[2]
12
- @db.sqls
9
+ @c.columns :id, :name
13
10
  end
14
11
 
15
- it "should use a ruby hash as a cache of all model instances" do
16
- @c.cache.should == {1=>@c.load(:id=>1), 2=>@c.load(:id=>2)}
17
- end
12
+ shared_examples_for "Sequel::Plugins::StaticCache" do
13
+ it "should use a ruby hash as a cache of all model instances" do
14
+ @c.cache.should == {1=>@c.load(:id=>1), 2=>@c.load(:id=>2)}
15
+ @c.cache[1].should equal(@c1)
16
+ @c.cache[2].should equal(@c2)
17
+ end
18
18
 
19
- it "should work correctly with composite keys" do
20
- @db.fetch = [{:id=>1, :id2=>1}, {:id=>2, :id2=>1}]
21
- @c = Class.new(Sequel::Model(@db[:t]))
22
- @c.columns :id, :id2
23
- @c.set_primary_key([:id, :id2])
24
- @c.plugin :static_cache
25
- @db.sqls
26
- @c1 = @c.cache[[1, 2]]
27
- @c2 = @c.cache[[2, 1]]
28
- @c[[1, 2]].should equal(@c1)
29
- @c[[2, 1]].should equal(@c2)
30
- @db.sqls.should == []
31
- end
19
+ it "should make .[] method with primary key use the cache" do
20
+ @c[1].should == @c1
21
+ @c[2].should == @c2
22
+ @c[3].should be_nil
23
+ @c[[1, 2]].should be_nil
24
+ @c[nil].should be_nil
25
+ @c[].should be_nil
26
+ @db.sqls.should == []
27
+ end
32
28
 
33
- it "should make .[] method with primary key use the cache" do
34
- @c[1].should equal(@c1)
35
- @c[2].should equal(@c2)
36
- @c[3].should be_nil
37
- @c[[1, 2]].should be_nil
38
- @c[nil].should be_nil
39
- @c[].should be_nil
40
- @db.sqls.should == []
41
- end
29
+ it "should have .[] with a hash not use the cache" do
30
+ @db.fetch = {:id=>2}
31
+ @c[:id=>2].should == @c2
32
+ @db.sqls.should == ['SELECT * FROM t WHERE (id = 2) LIMIT 1']
33
+ end
42
34
 
43
- it "should have .[] with a hash not use the cache" do
44
- @db.fetch = {:id=>2}
45
- @c[:id=>2].should == @c2
46
- @db.sqls.should == ['SELECT * FROM t WHERE (id = 2) LIMIT 1']
47
- end
35
+ it "should support cache_get_pk" do
36
+ @c.cache_get_pk(1).should == @c1
37
+ @c.cache_get_pk(2).should == @c2
38
+ @c.cache_get_pk(3).should be_nil
39
+ @db.sqls.should == []
40
+ end
48
41
 
49
- it "should support cache_get_pk" do
50
- @c.cache_get_pk(1).should equal(@c1)
51
- @c.cache_get_pk(2).should equal(@c2)
52
- @c.cache_get_pk(3).should be_nil
53
- @db.sqls.should == []
54
- end
42
+ it "should have each just iterate over the hash's values without sending a query" do
43
+ a = []
44
+ @c.each{|o| a << o}
45
+ a = a.sort_by{|o| o.id}
46
+ a.first.should == @c1
47
+ a.last.should == @c2
48
+ @db.sqls.should == []
49
+ end
55
50
 
56
- it "should have each just iterate over the hash's values without sending a query" do
57
- a = []
58
- @c.each{|o| a << o}
59
- a = a.sort_by{|o| o.id}
60
- a.first.should equal(@c1)
61
- a.last.should equal(@c2)
62
- @db.sqls.should == []
63
- end
51
+ it "should have map just iterate over the hash's values without sending a query if no argument is given" do
52
+ @c.map{|v| v.id}.sort.should == [1, 2]
53
+ @db.sqls.should == []
54
+ end
64
55
 
65
- it "should have map just iterate over the hash's values without sending a query if no argument is given" do
66
- @c.map{|v| v.id}.sort.should == [1, 2]
67
- @db.sqls.should == []
68
- end
56
+ it "should have count with no argument or block not issue a query" do
57
+ @c.count.should == 2
58
+ @db.sqls.should == []
59
+ end
69
60
 
70
- it "should have count with no argument or block not issue a query" do
71
- @c.count.should == 2
72
- @db.sqls.should == []
73
- end
61
+ it "should have count with argument or block not issue a query" do
62
+ @db.fetch = [[{:count=>1}], [{:count=>2}]]
63
+ @c.count(:a).should == 1
64
+ @c.count{b}.should == 2
65
+ @db.sqls.should == ["SELECT count(a) AS count FROM t LIMIT 1", "SELECT count(b) AS count FROM t LIMIT 1"]
66
+ end
74
67
 
75
- it "should have count with argument or block not issue a query" do
76
- @db.fetch = [[{:count=>1}], [{:count=>2}]]
77
- @c.count(:a).should == 1
78
- @c.count{b}.should == 2
79
- @db.sqls.should == ["SELECT count(a) AS count FROM t LIMIT 1", "SELECT count(b) AS count FROM t LIMIT 1"]
80
- end
68
+ it "should have map not send a query if given an argument" do
69
+ @c.map(:id).sort.should == [1, 2]
70
+ @db.sqls.should == []
71
+ @c.map([:id,:id]).sort.should == [[1,1], [2,2]]
72
+ @db.sqls.should == []
73
+ end
81
74
 
82
- it "should have map not send a query if given an argument" do
83
- @c.map(:id).sort.should == [1, 2]
84
- @db.sqls.should == []
85
- @c.map([:id,:id]).sort.should == [[1,1], [2,2]]
86
- @db.sqls.should == []
87
- end
75
+ it "should have map without a block or argument not raise an exception or issue a query" do
76
+ @c.map.to_a.should == @c.all
77
+ @db.sqls.should == []
78
+ end
88
79
 
89
- it "should have map without a block or argument not raise an exception or issue a query" do
90
- @c.map.to_a.should == @c.all
91
- @db.sqls.should == []
92
- end
80
+ it "should have map without a block not return a frozen object" do
81
+ @c.map.frozen?.should be_false
82
+ end
93
83
 
94
- it "should have map without a block not return a frozen object" do
95
- @c.map.frozen?.should be_false
96
- end
84
+ it "should have map with a block and argument raise" do
85
+ proc{@c.map(:id){}}.should raise_error(Sequel::Error)
86
+ end
97
87
 
98
- it "should have map with a block and argument raise" do
99
- proc{@c.map(:id){}}.should raise_error(Sequel::Error)
100
- end
88
+ it "should have other enumerable methods work without sending a query" do
89
+ a = @c.sort_by{|o| o.id}
90
+ a.first.should == @c1
91
+ a.last.should == @c2
92
+ @db.sqls.should == []
93
+ end
101
94
 
102
- it "should have other enumerable methods work without sending a query" do
103
- a = @c.sort_by{|o| o.id}
104
- a.first.should equal(@c1)
105
- a.last.should equal(@c2)
106
- @db.sqls.should == []
107
- end
95
+ it "should have all return all objects" do
96
+ a = @c.all.sort_by{|o| o.id}
97
+ a.first.should == @c1
98
+ a.last.should == @c2
99
+ @db.sqls.should == []
100
+ end
108
101
 
109
- it "should have all just return the cached values" do
110
- a = @c.all.sort_by{|o| o.id}
111
- a.first.should equal(@c1)
112
- a.last.should equal(@c2)
113
- @db.sqls.should == []
114
- end
102
+ it "should have all not return a frozen object" do
103
+ @c.all.frozen?.should be_false
104
+ end
115
105
 
116
- it "should have all not return a frozen object" do
117
- @c.all.frozen?.should be_false
118
- end
106
+ it "should have all return things in dataset order" do
107
+ @c.all.should == [@c1, @c2]
108
+ end
119
109
 
120
- it "should have all return things in dataset order" do
121
- @c.all.should == [@c1, @c2]
122
- end
110
+ it "should have to_hash without arguments run without a query" do
111
+ a = @c.to_hash
112
+ a.should == {1=>@c1, 2=>@c2}
113
+ a[1].should == @c1
114
+ a[2].should == @c2
115
+ @db.sqls.should == []
116
+ end
123
117
 
124
- it "should have to_hash without arguments return the cached objects without a query" do
125
- a = @c.to_hash
126
- a.should == {1=>@c1, 2=>@c2}
127
- a[1].should equal(@c1)
128
- a[2].should equal(@c2)
129
- @db.sqls.should == []
130
- end
118
+ it "should have to_hash with arguments return results without a query" do
119
+ a = @c.to_hash(:id)
120
+ a.should == {1=>@c1, 2=>@c2}
121
+ a[1].should == @c1
122
+ a[2].should == @c2
131
123
 
132
- it "should have to_hash with arguments return the cached objects without a query" do
133
- a = @c.to_hash(:id)
134
- a.should == {1=>@c1, 2=>@c2}
135
- a[1].should equal(@c1)
136
- a[2].should equal(@c2)
124
+ a = @c.to_hash([:id])
125
+ a.should == {[1]=>@c1, [2]=>@c2}
126
+ a[[1]].should == @c1
127
+ a[[2]].should == @c2
137
128
 
138
- a = @c.to_hash([:id])
139
- a.should == {[1]=>@c1, [2]=>@c2}
140
- a[[1]].should equal(@c1)
141
- a[[2]].should equal(@c2)
129
+ @c.to_hash(:id, :id).should == {1=>1, 2=>2}
130
+ @c.to_hash([:id], :id).should == {[1]=>1, [2]=>2}
131
+ @c.to_hash(:id, [:id]).should == {1=>[1], 2=>[2]}
132
+ @c.to_hash([:id], [:id]).should == {[1]=>[1], [2]=>[2]}
142
133
 
143
- @c.to_hash(:id, :id).should == {1=>1, 2=>2}
144
- @c.to_hash([:id], :id).should == {[1]=>1, [2]=>2}
145
- @c.to_hash(:id, [:id]).should == {1=>[1], 2=>[2]}
146
- @c.to_hash([:id], [:id]).should == {[1]=>[1], [2]=>[2]}
134
+ @db.sqls.should == []
135
+ end
147
136
 
148
- @db.sqls.should == []
149
- end
137
+ it "should have to_hash not return a frozen object" do
138
+ @c.to_hash.frozen?.should be_false
139
+ end
150
140
 
151
- it "should have to_hash not return a frozen object" do
152
- @c.to_hash.frozen?.should be_false
153
- end
141
+ it "should have to_hash_groups without arguments return the cached objects without a query" do
142
+ a = @c.to_hash_groups(:id)
143
+ a.should == {1=>[@c1], 2=>[@c2]}
144
+ a[1].first.should == @c1
145
+ a[2].first.should == @c2
154
146
 
155
- it "should have to_hash_groups without arguments return the cached objects without a query" do
156
- a = @c.to_hash_groups(:id)
157
- a.should == {1=>[@c1], 2=>[@c2]}
158
- a[1].first.should equal(@c1)
159
- a[2].first.should equal(@c2)
147
+ a = @c.to_hash_groups([:id])
148
+ a.should == {[1]=>[@c1], [2]=>[@c2]}
149
+ a[[1]].first.should == @c1
150
+ a[[2]].first.should == @c2
160
151
 
161
- a = @c.to_hash_groups([:id])
162
- a.should == {[1]=>[@c1], [2]=>[@c2]}
163
- a[[1]].first.should equal(@c1)
164
- a[[2]].first.should equal(@c2)
152
+ @c.to_hash_groups(:id, :id).should == {1=>[1], 2=>[2]}
153
+ @c.to_hash_groups([:id], :id).should == {[1]=>[1], [2]=>[2]}
154
+ @c.to_hash_groups(:id, [:id]).should == {1=>[[1]], 2=>[[2]]}
155
+ @c.to_hash_groups([:id], [:id]).should == {[1]=>[[1]], [2]=>[[2]]}
165
156
 
166
- @c.to_hash_groups(:id, :id).should == {1=>[1], 2=>[2]}
167
- @c.to_hash_groups([:id], :id).should == {[1]=>[1], [2]=>[2]}
168
- @c.to_hash_groups(:id, [:id]).should == {1=>[[1]], 2=>[[2]]}
169
- @c.to_hash_groups([:id], [:id]).should == {[1]=>[[1]], [2]=>[[2]]}
157
+ @db.sqls.should == []
158
+ end
170
159
 
171
- @db.sqls.should == []
172
- end
160
+ it "subclasses should work correctly" do
161
+ c = Class.new(@c)
162
+ c.all.should == [c.load(:id=>1), c.load(:id=>2)]
163
+ c.to_hash.should == {1=>c.load(:id=>1), 2=>c.load(:id=>2)}
164
+ @db.sqls.should == ['SELECT * FROM t']
165
+ end
173
166
 
174
- it "all of the static cache values (model instances) should be frozen" do
175
- @c.all.all?{|o| o.frozen?}.should be_true
167
+ it "set_dataset should work correctly" do
168
+ ds = @c.dataset.from(:t2)
169
+ ds.instance_variable_set(:@columns, [:id])
170
+ ds._fetch = {:id=>3}
171
+ @c.dataset = ds
172
+ @c.all.should == [@c.load(:id=>3)]
173
+ @c.to_hash.should == {3=>@c.load(:id=>3)}
174
+ @c.to_hash[3].should == @c.all.first
175
+ @db.sqls.should == ['SELECT * FROM t2']
176
+ end
176
177
  end
177
178
 
178
- it "subclasses should work correctly" do
179
- c = Class.new(@c)
180
- c.all.should == [c.load(:id=>1), c.load(:id=>2)]
181
- c.to_hash.should == {1=>c.load(:id=>1), 2=>c.load(:id=>2)}
182
- @db.sqls.should == ['SELECT * FROM t']
179
+ describe "without options" do
180
+ before do
181
+ @c.plugin :static_cache
182
+ @c1 = @c.cache[1]
183
+ @c2 = @c.cache[2]
184
+ @db.sqls
185
+ end
186
+
187
+ it_should_behave_like "Sequel::Plugins::StaticCache"
188
+
189
+ it "should work correctly with composite keys" do
190
+ @db.fetch = [{:id=>1, :id2=>1}, {:id=>2, :id2=>1}]
191
+ @c = Class.new(Sequel::Model(@db[:t]))
192
+ @c.columns :id, :id2
193
+ @c.set_primary_key([:id, :id2])
194
+ @c.plugin :static_cache
195
+ @db.sqls
196
+ @c1 = @c.cache[[1, 2]]
197
+ @c2 = @c.cache[[2, 1]]
198
+ @c[[1, 2]].should equal(@c1)
199
+ @c[[2, 1]].should equal(@c2)
200
+ @db.sqls.should == []
201
+ end
202
+
203
+ it "all of the static cache values (model instances) should be frozen" do
204
+ @c.all.all?{|o| o.frozen?}.should be_true
205
+ end
206
+
207
+ it "should make .[] method with primary key return cached instances" do
208
+ @c[1].should equal(@c1)
209
+ @c[2].should equal(@c2)
210
+ end
211
+
212
+ it "should have cache_get_pk return cached instances" do
213
+ @c.cache_get_pk(1).should equal(@c1)
214
+ @c.cache_get_pk(2).should equal(@c2)
215
+ end
216
+
217
+ it "should have each yield cached objects" do
218
+ a = []
219
+ @c.each{|o| a << o}
220
+ a = a.sort_by{|o| o.id}
221
+ a.first.should equal(@c1)
222
+ a.last.should equal(@c2)
223
+ end
224
+
225
+ it "should have other enumerable methods work yield cached objects" do
226
+ a = @c.sort_by{|o| o.id}
227
+ a.first.should equal(@c1)
228
+ a.last.should equal(@c2)
229
+ end
230
+
231
+ it "should have all return cached instances" do
232
+ a = @c.all.sort_by{|o| o.id}
233
+ a.first.should equal(@c1)
234
+ a.last.should equal(@c2)
235
+ end
236
+
237
+ it "should have to_hash without arguments use cached instances" do
238
+ a = @c.to_hash
239
+ a[1].should equal(@c1)
240
+ a[2].should equal(@c2)
241
+ end
242
+
243
+ it "should have to_hash with arguments return cached instances" do
244
+ a = @c.to_hash(:id)
245
+ a[1].should equal(@c1)
246
+ a[2].should equal(@c2)
247
+
248
+ a = @c.to_hash([:id])
249
+ a[[1]].should equal(@c1)
250
+ a[[2]].should equal(@c2)
251
+ end
252
+
253
+ it "should have to_hash_groups without single argument return the cached instances" do
254
+ a = @c.to_hash_groups(:id)
255
+ a[1].first.should equal(@c1)
256
+ a[2].first.should equal(@c2)
257
+
258
+ a = @c.to_hash_groups([:id])
259
+ a[[1]].first.should equal(@c1)
260
+ a[[2]].first.should equal(@c2)
261
+ end
262
+
263
+ it "should not allow the saving of new objects" do
264
+ proc{@c.create}.should raise_error(Sequel::BeforeHookFailed)
265
+ end
266
+
267
+ it "should not allow the saving of existing objects" do
268
+ @db.fetch = {:id=>1}
269
+ proc{@c.first(:id=>1).save}.should raise_error(Sequel::BeforeHookFailed)
270
+ end
271
+
272
+ it "should not allow the destroying of existing objects" do
273
+ @db.fetch = {:id=>1}
274
+ proc{@c.first(:id=>1).destroy}.should raise_error(Sequel::BeforeHookFailed)
275
+ end
183
276
  end
184
277
 
185
- it "set_dataset should work correctly" do
186
- ds = @c.dataset.from(:t2)
187
- ds.instance_variable_set(:@columns, [:id])
188
- ds._fetch = {:id=>3}
189
- @c.dataset = ds
190
- @c.all.should == [@c.load(:id=>3)]
191
- @c.to_hash.should == {3=>@c.load(:id=>3)}
192
- @c.to_hash[3].should equal(@c.all.first)
193
- @db.sqls.should == ['SELECT * FROM t2']
278
+ describe "with :frozen=>false option" do
279
+ before do
280
+ @c.plugin :static_cache, :frozen=>false
281
+ @c1 = @c.cache[1]
282
+ @c2 = @c.cache[2]
283
+ @db.sqls
284
+ end
285
+
286
+ it_should_behave_like "Sequel::Plugins::StaticCache"
287
+
288
+ it "record retrieved by primary key should not be frozen" do
289
+ @c[1].frozen?.should be_false
290
+ @c.cache_get_pk(1).frozen?.should be_false
291
+ end
292
+
293
+ it "none of values returned in #all should be frozen" do
294
+ @c.all.all?{|o| !o.frozen?}.should be_true
295
+ end
296
+
297
+ it "none of values yielded by each should be frozen" do
298
+ a = []
299
+ @c.each{|o| a << o}
300
+ a.all?{|o| !o.frozen?}.should be_true
301
+ end
302
+
303
+ it "none of values yielded by Enumerable method should be frozen" do
304
+ @c.sort_by{|o| o.id}.all?{|o| !o.frozen?}.should be_true
305
+ end
306
+
307
+ it "none of values returned by map without an argument or block should be frozen" do
308
+ @c.map{|o| o}.all?{|o| !o.frozen?}.should be_true
309
+ @c.map.all?{|o| !o.frozen?}.should be_true
310
+ end
311
+
312
+ it "none of values in the hash returned by to_hash without an argument should be frozen" do
313
+ @c.to_hash.values.all?{|o| !o.frozen?}.should be_true
314
+ end
315
+
316
+ it "none of values in the hash returned by to_hash with a single argument should be frozen" do
317
+ @c.to_hash(:id).values.all?{|o| !o.frozen?}.should be_true
318
+ end
319
+
320
+ it "none of values in the hash returned by to_hash with a single array argument should be frozen" do
321
+ @c.to_hash([:id, :id]).values.all?{|o| !o.frozen?}.should be_true
322
+ end
323
+
324
+ it "none of values in the hash returned by to_hash_groups with a single argument should be frozen" do
325
+ @c.to_hash_groups(:id).values.flatten.all?{|o| !o.frozen?}.should be_true
326
+ end
327
+
328
+ it "none of values in the hash returned by to_hash_groups with a single array argument should be frozen" do
329
+ @c.to_hash_groups([:id, :id]).values.flatten.all?{|o| !o.frozen?}.should be_true
330
+ end
331
+
332
+ it "should not automatically update the cache when creating new model objects" do
333
+ o = @c.new
334
+ o.id = 3
335
+ @db.autoid = 3
336
+ @db.fetch = [[{:id=>1}, {:id=>2}, {:id=>3}], [{:id=>3}]]
337
+ o.save
338
+ @c[3].should == nil
339
+ end
340
+
341
+ it "should not automatically update the cache when updating model objects" do
342
+ o = @c[2]
343
+ @db.fetch = [[{:id=>1}, {:id=>2, :name=>'a'}]]
344
+ o.update(:name=>'a')
345
+ @c[2].values.should == {:id=>2}
346
+ end
347
+
348
+ it "should not automatically update the cache when updating model objects" do
349
+ o = @c[2]
350
+ @db.fetch = [[{:id=>1}]]
351
+ o.destroy
352
+ @c[2].should == @c2
353
+ end
194
354
  end
195
355
  end