sequel 4.1.1 → 4.2.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.
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