couchrest_model 1.1.0.beta5 → 1.1.0.rc1

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 (37) hide show
  1. data/Rakefile +9 -12
  2. data/VERSION +1 -1
  3. data/couchrest_model.gemspec +6 -6
  4. data/history.md +23 -0
  5. data/lib/couchrest/model/associations.rb +50 -54
  6. data/lib/couchrest/model/base.rb +10 -15
  7. data/lib/couchrest/model/casted_array.rb +16 -0
  8. data/lib/couchrest/model/class_proxy.rb +8 -1
  9. data/lib/couchrest/model/collection.rb +1 -0
  10. data/lib/couchrest/model/design_doc.rb +0 -2
  11. data/lib/couchrest/model/document_queries.rb +8 -8
  12. data/lib/couchrest/model/errors.rb +2 -0
  13. data/lib/couchrest/model/persistence.rb +20 -15
  14. data/lib/couchrest/model/properties.rb +17 -29
  15. data/lib/couchrest/model/property.rb +23 -7
  16. data/lib/couchrest/model/proxyable.rb +11 -4
  17. data/lib/couchrest/model/support/couchrest_database.rb +13 -0
  18. data/lib/couchrest/model/support/couchrest_design.rb +1 -1
  19. data/lib/couchrest/model/typecast.rb +1 -2
  20. data/lib/couchrest/model/validations/uniqueness.rb +29 -14
  21. data/lib/couchrest_model.rb +1 -1
  22. data/spec/couchrest/assocations_spec.rb +28 -1
  23. data/spec/couchrest/base_spec.rb +64 -26
  24. data/spec/couchrest/class_proxy_spec.rb +29 -0
  25. data/spec/couchrest/collection_spec.rb +6 -7
  26. data/spec/couchrest/design_doc_spec.rb +5 -1
  27. data/spec/couchrest/dirty_spec.rb +52 -0
  28. data/spec/couchrest/inherited_spec.rb +23 -30
  29. data/spec/couchrest/persistence_spec.rb +40 -18
  30. data/spec/couchrest/property_spec.rb +90 -4
  31. data/spec/couchrest/proxyable_spec.rb +14 -7
  32. data/spec/couchrest/validations_spec.rb +18 -1
  33. data/spec/fixtures/base.rb +4 -3
  34. data/spec/fixtures/more/article.rb +1 -0
  35. data/spec/fixtures/more/cat.rb +4 -0
  36. data/spec/fixtures/more/key_chain.rb +5 -0
  37. metadata +22 -21
@@ -3,7 +3,7 @@
3
3
  module CouchRest
4
4
  module Model
5
5
  module Validations
6
-
6
+
7
7
  # Validates if a field is unique
8
8
  class UniquenessValidator < ActiveModel::EachValidator
9
9
 
@@ -11,29 +11,33 @@ module CouchRest
11
11
  # or add one if necessary.
12
12
  def setup(model)
13
13
  @model = model
14
+ if options[:view].blank?
15
+ attributes.each do |attribute|
16
+ opts = merge_view_options(attribute)
17
+
18
+ if model.respond_to?(:has_view?) && !model.has_view?(opts[:view_name])
19
+ opts[:keys] << {:allow_nil => true}
20
+ model.view_by(*opts[:keys])
21
+ end
22
+ end
23
+ end
14
24
  end
15
25
 
16
26
  def validate_each(document, attribute, value)
17
- keys = [attribute]
18
- unless options[:scope].nil?
19
- keys = (options[:scope].is_a?(Array) ? options[:scope] : [options[:scope]]) + keys
20
- end
21
- values = keys.map{|k| document.send(k)}
22
- values = values.first if values.length == 1
27
+ opts = merge_view_options(attribute)
23
28
 
24
- view_name = options[:view].nil? ? "by_#{keys.join('_and_')}" : options[:view]
29
+ values = opts[:keys].map{|k| document.send(k)}
30
+ values = values.first if values.length == 1
25
31
 
26
32
  model = (document.respond_to?(:model_proxy) && document.model_proxy ? document.model_proxy : @model)
27
33
  # Determine the base of the search
28
- base = options[:proxy].nil? ? model : document.instance_eval(options[:proxy])
34
+ base = opts[:proxy].nil? ? model : document.instance_eval(opts[:proxy])
29
35
 
30
- if base.respond_to?(:has_view?) && !base.has_view?(view_name)
31
- raise "View #{document.class.name}.#{options[:view]} does not exist!" unless options[:view].nil?
32
- keys << {:allow_nil => true}
33
- model.view_by(*keys)
36
+ if base.respond_to?(:has_view?) && !base.has_view?(opts[:view_name])
37
+ raise "View #{document.class.name}.#{opts[:view_name]} does not exist for validation!"
34
38
  end
35
39
 
36
- rows = base.view(view_name, :key => values, :limit => 2, :include_docs => false)['rows']
40
+ rows = base.view(opts[:view_name], :key => values, :limit => 2, :include_docs => false)['rows']
37
41
  return if rows.empty?
38
42
 
39
43
  unless document.new?
@@ -47,6 +51,17 @@ module CouchRest
47
51
  end
48
52
  end
49
53
 
54
+ private
55
+
56
+ def merge_view_options(attr)
57
+ keys = [attr]
58
+ keys.unshift(*options[:scope]) unless options[:scope].nil?
59
+
60
+ view_name = options[:view].nil? ? "by_#{keys.join('_and_')}" : options[:view]
61
+
62
+ options.merge({:keys => keys, :view_name => view_name})
63
+ end
64
+
50
65
  end
51
66
 
52
67
  end
@@ -1,7 +1,6 @@
1
1
  require 'active_model'
2
2
  require "active_model/callbacks"
3
3
  require "active_model/conversion"
4
- require "active_model/deprecated_error_methods"
5
4
  require "active_model/errors"
6
5
  require "active_model/naming"
7
6
  require "active_model/serialization"
@@ -52,6 +51,7 @@ require "couchrest/model/designs/view"
52
51
 
53
52
  # Monkey patches applied to couchrest
54
53
  require "couchrest/model/support/couchrest_design"
54
+ require "couchrest/model/support/couchrest_database"
55
55
 
56
56
  # Core Extensions
57
57
  require "couchrest/model/core_extensions/hash"
@@ -101,7 +101,7 @@ describe "Assocations" do
101
101
  it "should create an associated property and collection proxy" do
102
102
  @invoice.respond_to?('entry_ids').should be_true
103
103
  @invoice.respond_to?('entry_ids=').should be_true
104
- @invoice.entries.class.should eql(::CouchRest::CollectionOfProxy)
104
+ @invoice.entries.class.should eql(::CouchRest::Model::CollectionOfProxy)
105
105
  end
106
106
 
107
107
  it "should allow replacement of objects" do
@@ -154,6 +154,33 @@ describe "Assocations" do
154
154
  @invoice.entries.should be_empty
155
155
  end
156
156
 
157
+ # Account for dirty tracking
158
+ describe "dirty tracking" do
159
+ it "should register changes on push" do
160
+ @invoice.changed?.should be_false
161
+ @invoice.entries << @entries[0]
162
+ @invoice.changed?.should be_true
163
+ end
164
+ it "should register changes on pop" do
165
+ @invoice.entries << @entries[0]
166
+ @invoice.save
167
+ @invoice.changed?.should be_false
168
+ @invoice.entries.pop
169
+ @invoice.changed?.should be_true
170
+ end
171
+ it "should register id changes on push" do
172
+ @invoice.entry_ids << @entries[0].id
173
+ @invoice.changed?.should be_true
174
+ end
175
+ it "should register id changes on pop" do
176
+ @invoice.entry_ids << @entries[0].id
177
+ @invoice.save
178
+ @invoice.changed?.should be_false
179
+ @invoice.entry_ids.pop
180
+ @invoice.changed?.should be_true
181
+ end
182
+ end
183
+
157
184
  describe "proxy" do
158
185
 
159
186
  it "should ensure new entries to proxy are matched" do
@@ -44,8 +44,39 @@ describe "Model Base" do
44
44
  @obj.database.should eql('database')
45
45
  end
46
46
 
47
+ it "should support initialization block" do
48
+ @obj = Basic.new {|b| b.database = 'database'}
49
+ @obj.database.should eql('database')
50
+ end
51
+
52
+ it "should only set defined properties" do
53
+ @doc = WithDefaultValues.new(:name => 'test', :foo => 'bar')
54
+ @doc['name'].should eql('test')
55
+ @doc['foo'].should be_nil
56
+ end
57
+
58
+ it "should set all properties with :directly_set_attributes option" do
59
+ @doc = WithDefaultValues.new({:name => 'test', :foo => 'bar'}, :directly_set_attributes => true)
60
+ @doc['name'].should eql('test')
61
+ @doc['foo'].should eql('bar')
62
+ end
63
+
64
+ it "should set the model type" do
65
+ @doc = WithDefaultValues.new()
66
+ @doc[WithDefaultValues.model_type_key].should eql('WithDefaultValues')
67
+ end
68
+
69
+ it "should call after_initialize method if available" do
70
+ @doc = WithAfterInitializeMethod.new
71
+ @doc['some_value'].should eql('value')
72
+ end
73
+
74
+ it "should call after_initialize after block" do
75
+ @doc = WithAfterInitializeMethod.new {|d| d.some_value = "foo"}
76
+ @doc['some_value'].should eql('foo')
77
+ end
47
78
  end
48
-
79
+
49
80
  describe "ActiveModel compatability Basic" do
50
81
 
51
82
  before(:each) do
@@ -104,9 +135,23 @@ describe "Model Base" do
104
135
  end
105
136
  end
106
137
 
138
+ describe "#destroyed?" do
139
+ it "should be present" do
140
+ @obj.should respond_to(:destroyed?)
141
+ end
142
+ it "should return false with new object" do
143
+ @obj.destroyed?.should be_false
144
+ end
145
+ it "should return true after destroy" do
146
+ @obj.save
147
+ @obj.destroy
148
+ @obj.destroyed?.should be_true
149
+ end
150
+ end
151
+
107
152
 
108
153
  end
109
-
154
+
110
155
  describe "update attributes without saving" do
111
156
  before(:each) do
112
157
  a = Article.get "big-bad-danger" rescue nil
@@ -147,7 +192,7 @@ describe "Model Base" do
147
192
  }.should_not raise_error
148
193
  @art.slug.should == "big-bad-danger"
149
194
  end
150
-
195
+
151
196
  #it "should not change other attributes if there is an error" do
152
197
  # lambda {
153
198
  # @art.update_attributes_without_saving('slug' => "new-slug", :title => "super danger")
@@ -155,7 +200,7 @@ describe "Model Base" do
155
200
  # @art['title'].should == "big bad danger"
156
201
  #end
157
202
  end
158
-
203
+
159
204
  describe "update attributes" do
160
205
  before(:each) do
161
206
  a = Article.get "big-bad-danger" rescue nil
@@ -170,7 +215,7 @@ describe "Model Base" do
170
215
  loaded['title'].should == "super danger"
171
216
  end
172
217
  end
173
-
218
+
174
219
  describe "with default" do
175
220
  it "should have the default value set at initalization" do
176
221
  @obj.preset.should == {:right => 10, :top_align => false}
@@ -227,7 +272,7 @@ describe "Model Base" do
227
272
  WithTemplateAndUniqueID.all.map{|o| o.destroy}
228
273
  WithTemplateAndUniqueID.database.bulk_delete
229
274
  @tmpl = WithTemplateAndUniqueID.new
230
- @tmpl2 = WithTemplateAndUniqueID.new(:preset => 'not_value', 'important-field' => '1')
275
+ @tmpl2 = WithTemplateAndUniqueID.new(:preset => 'not_value', 'slug' => '1')
231
276
  end
232
277
  it "should have fields set when new" do
233
278
  @tmpl.preset.should == 'value'
@@ -248,10 +293,10 @@ describe "Model Base" do
248
293
  before(:all) do
249
294
  WithTemplateAndUniqueID.all.map{|o| o.destroy}
250
295
  WithTemplateAndUniqueID.database.bulk_delete
251
- WithTemplateAndUniqueID.new('important-field' => '1').save
252
- WithTemplateAndUniqueID.new('important-field' => '2').save
253
- WithTemplateAndUniqueID.new('important-field' => '3').save
254
- WithTemplateAndUniqueID.new('important-field' => '4').save
296
+ WithTemplateAndUniqueID.new('slug' => '1').save
297
+ WithTemplateAndUniqueID.new('slug' => '2').save
298
+ WithTemplateAndUniqueID.new('slug' => '3').save
299
+ WithTemplateAndUniqueID.new('slug' => '4').save
255
300
  end
256
301
  it "should find all" do
257
302
  rs = WithTemplateAndUniqueID.all
@@ -269,9 +314,9 @@ describe "Model Base" do
269
314
  end
270
315
 
271
316
  it ".count should return the number of documents" do
272
- WithTemplateAndUniqueID.new('important-field' => '1').save
273
- WithTemplateAndUniqueID.new('important-field' => '2').save
274
- WithTemplateAndUniqueID.new('important-field' => '3').save
317
+ WithTemplateAndUniqueID.new('slug' => '1').save
318
+ WithTemplateAndUniqueID.new('slug' => '2').save
319
+ WithTemplateAndUniqueID.new('slug' => '3').save
275
320
 
276
321
  WithTemplateAndUniqueID.count.should == 3
277
322
  end
@@ -280,14 +325,14 @@ describe "Model Base" do
280
325
  describe "finding the first instance of a model" do
281
326
  before(:each) do
282
327
  @db = reset_test_db!
283
- WithTemplateAndUniqueID.new('important-field' => '1').save
284
- WithTemplateAndUniqueID.new('important-field' => '2').save
285
- WithTemplateAndUniqueID.new('important-field' => '3').save
286
- WithTemplateAndUniqueID.new('important-field' => '4').save
328
+ WithTemplateAndUniqueID.new('slug' => '1').save
329
+ WithTemplateAndUniqueID.new('slug' => '2').save
330
+ WithTemplateAndUniqueID.new('slug' => '3').save
331
+ WithTemplateAndUniqueID.new('slug' => '4').save
287
332
  end
288
333
  it "should find first" do
289
334
  rs = WithTemplateAndUniqueID.first
290
- rs['important-field'].should == "1"
335
+ rs['slug'].should == "1"
291
336
  end
292
337
  it "should return nil if no instances are found" do
293
338
  WithTemplateAndUniqueID.all.each {|obj| obj.destroy }
@@ -365,14 +410,7 @@ describe "Model Base" do
365
410
  end
366
411
  end
367
412
 
368
- describe "initialization" do
369
- it "should call after_initialize method if available" do
370
- @doc = WithAfterInitializeMethod.new
371
- @doc['some_value'].should eql('value')
372
- end
373
- end
374
-
375
- describe "recursive validation on a model" do
413
+ describe "recursive validation on a model" do
376
414
  before :each do
377
415
  reset_test_db!
378
416
  @cat = Cat.new(:name => 'Sockington')
@@ -123,6 +123,35 @@ describe "Proxy Class" do
123
123
  u.respond_to?(:database).should be_false
124
124
  end
125
125
  end
126
+
127
+ describe "#get!" do
128
+ it "raises exception when passed a nil" do
129
+ expect { @us.get!(nil)}.to raise_error(CouchRest::Model::DocumentNotFound)
130
+ end
131
+
132
+ it "raises exception when passed an empty string " do
133
+ expect { @us.get!("")}.to raise_error(CouchRest::Model::DocumentNotFound)
134
+ end
135
+
136
+ it "raises exception when document with provided id does not exist" do
137
+ expect { @us.get!("thisisnotreallyadocumentid")}.to raise_error(CouchRest::Model::DocumentNotFound)
138
+ end
139
+ end
140
+
141
+ describe "#find!" do
142
+ it "raises exception when passed a nil" do
143
+ expect { @us.find!(nil)}.to raise_error(CouchRest::Model::DocumentNotFound)
144
+ end
145
+
146
+ it "raises exception when passed an empty string " do
147
+ expect { @us.find!("")}.to raise_error(CouchRest::Model::DocumentNotFound)
148
+ end
149
+
150
+ it "raises exception when document with provided id does not exist" do
151
+ expect { @us.find!("thisisnotreallyadocumentid")}.to raise_error(CouchRest::Model::DocumentNotFound)
152
+ end
153
+ end
154
+
126
155
  # Sam Lown 2010-04-07
127
156
  # Removed as unclear why this should happen as before my changes
128
157
  # this happend by accident, not explicitly.
@@ -27,21 +27,20 @@ describe "Collections" do
27
27
  end
28
28
  it "should provide a class method for paginate" do
29
29
  articles = Article.paginate(:design_doc => 'Article', :view_name => 'by_date',
30
- :per_page => 3, :descending => true, :key => Date.today, :include_docs => true)
30
+ :per_page => 3, :descending => true, :key => Date.today)
31
31
  articles.size.should == 3
32
-
32
+
33
33
  articles = Article.paginate(:design_doc => 'Article', :view_name => 'by_date',
34
- :per_page => 3, :page => 2, :descending => true, :key => Date.today, :include_docs => true)
34
+ :per_page => 3, :page => 2, :descending => true, :key => Date.today)
35
35
  articles.size.should == 3
36
-
36
+
37
37
  articles = Article.paginate(:design_doc => 'Article', :view_name => 'by_date',
38
- :per_page => 3, :page => 3, :descending => true, :key => Date.today, :include_docs => true)
38
+ :per_page => 3, :page => 3, :descending => true, :key => Date.today)
39
39
  articles.size.should == 1
40
40
  end
41
41
  it "should provide a class method for paginated_each" do
42
42
  options = { :design_doc => 'Article', :view_name => 'by_date',
43
- :per_page => 3, :page => 1, :descending => true, :key => Date.today,
44
- :include_docs => true }
43
+ :per_page => 3, :page => 1, :descending => true, :key => Date.today }
45
44
  Article.paginated_each(options) do |a|
46
45
  a.should_not be_nil
47
46
  end
@@ -155,6 +155,10 @@ describe "Design Documents" do
155
155
  Article.by_date
156
156
  Article.stored_design_doc['_rev'].should eql(orig)
157
157
  end
158
+ it "should recreate the design doc if database deleted" do
159
+ Article.database.recreate!
160
+ lambda { Article.by_date }.should_not raise_error(RestClient::ResourceNotFound)
161
+ end
158
162
  end
159
163
 
160
164
  describe "when auto_update_design_doc false" do
@@ -198,7 +202,7 @@ describe "Design Documents" do
198
202
  describe "lazily refreshing the design document" do
199
203
  before(:all) do
200
204
  @db = reset_test_db!
201
- WithTemplateAndUniqueID.new('important-field' => '1').save
205
+ WithTemplateAndUniqueID.new('slug' => '1').save
202
206
  end
203
207
  it "should not save the design doc twice" do
204
208
  WithTemplateAndUniqueID.all
@@ -241,6 +241,14 @@ describe "Dirty" do
241
241
  end
242
242
  end
243
243
 
244
+ it "should report changes if an array is popped after reload" do
245
+ should_change_array do |array, obj|
246
+ obj.reload
247
+ obj.keywords.pop
248
+ end
249
+ end
250
+
251
+
244
252
  it "should report no changes if an empty array is popped" do
245
253
  should_not_change_array do |array, obj|
246
254
  array.clear
@@ -249,6 +257,50 @@ describe "Dirty" do
249
257
  end
250
258
  end
251
259
 
260
+ it "should report changes on deletion from an array" do
261
+ should_change_array do |array, obj|
262
+ array << "keyword"
263
+ obj.save!
264
+ array.delete_at(0)
265
+ end
266
+
267
+ should_change_array do |array, obj|
268
+ array << "keyword"
269
+ obj.save!
270
+ array.delete("keyword")
271
+ end
272
+ end
273
+
274
+ it "should report changes on deletion from an array after reload" do
275
+ should_change_array do |array, obj|
276
+ array << "keyword"
277
+ obj.save!
278
+ obj.reload
279
+ array.delete_at(0)
280
+ end
281
+
282
+ should_change_array do |array, obj|
283
+ array << "keyword"
284
+ obj.save!
285
+ obj.reload
286
+ array.delete("keyword")
287
+ end
288
+ end
289
+
290
+ it "should report no changes on deletion from an empty array" do
291
+ should_not_change_array do |array, obj|
292
+ array.clear
293
+ obj.save!
294
+ array.delete_at(0)
295
+ end
296
+
297
+ should_not_change_array do |array, obj|
298
+ array.clear
299
+ obj.save!
300
+ array.delete("keyword")
301
+ end
302
+ end
303
+
252
304
  it "should report changes if an array is pushed" do
253
305
  should_change_array do |array, obj|
254
306
  array.push("keyword")
@@ -1,40 +1,33 @@
1
1
  require File.expand_path('../../spec_helper', __FILE__)
2
2
 
3
- begin
4
- require 'rubygems' unless ENV['SKIP_RUBYGEMS']
5
- require 'active_support/json'
6
- ActiveSupport::JSON.backend = :JSONGem
7
-
8
- class PlainParent
9
- class_inheritable_accessor :foo
10
- self.foo = :bar
11
- end
3
+ class PlainParent
4
+ class_inheritable_accessor :foo
5
+ self.foo = :bar
6
+ end
12
7
 
13
- class PlainChild < PlainParent
14
- end
8
+ class PlainChild < PlainParent
9
+ end
15
10
 
16
- class ExtendedParent < CouchRest::Model::Base
17
- class_inheritable_accessor :foo
18
- self.foo = :bar
19
- end
11
+ class ExtendedParent < CouchRest::Model::Base
12
+ class_inheritable_accessor :foo
13
+ self.foo = :bar
14
+ end
20
15
 
21
- class ExtendedChild < ExtendedParent
22
- end
16
+ class ExtendedChild < ExtendedParent
17
+ end
23
18
 
24
- describe "Using chained inheritance without CouchRest::Model::Base" do
25
- it "should preserve inheritable attributes" do
26
- PlainParent.foo.should == :bar
27
- PlainChild.foo.should == :bar
28
- end
19
+ describe "Using chained inheritance without CouchRest::Model::Base" do
20
+ it "should preserve inheritable attributes" do
21
+ PlainParent.foo.should == :bar
22
+ PlainChild.foo.should == :bar
29
23
  end
24
+ end
30
25
 
31
- describe "Using chained inheritance with CouchRest::Model::Base" do
32
- it "should preserve inheritable attributes" do
33
- ExtendedParent.foo.should == :bar
34
- ExtendedChild.foo.should == :bar
35
- end
26
+ describe "Using chained inheritance with CouchRest::Model::Base" do
27
+ it "should preserve inheritable attributes" do
28
+ ExtendedParent.foo.should == :bar
29
+ ExtendedChild.foo.should == :bar
36
30
  end
37
-
38
- rescue LoadError
39
- puts "This spec requires 'active_support/json' to be loaded"
40
31
  end
32
+
33
+
@@ -5,6 +5,7 @@ require File.join(FIXTURE_PATH, 'more', 'cat')
5
5
  require File.join(FIXTURE_PATH, 'more', 'article')
6
6
  require File.join(FIXTURE_PATH, 'more', 'course')
7
7
  require File.join(FIXTURE_PATH, 'more', 'card')
8
+ require File.join(FIXTURE_PATH, 'more', 'event')
8
9
 
9
10
  describe "Model Persistence" do
10
11
 
@@ -34,11 +35,11 @@ describe "Model Persistence" do
34
35
  describe "basic saving and retrieving" do
35
36
  it "should work fine" do
36
37
  @obj.name = "should be easily saved and retrieved"
37
- @obj.save
38
- saved_obj = WithDefaultValues.get(@obj.id)
38
+ @obj.save!
39
+ saved_obj = WithDefaultValues.get!(@obj.id)
39
40
  saved_obj.should_not be_nil
40
41
  end
41
-
42
+
42
43
  it "should parse the Time attributes automatically" do
43
44
  @obj.name = "should parse the Time attributes automatically"
44
45
  @obj.set_by_proc.should be_an_instance_of(Time)
@@ -81,6 +82,18 @@ describe "Model Persistence" do
81
82
  article.should_not be_new
82
83
  end
83
84
 
85
+ it "yields new instance to block before saving (#create)" do
86
+ article = Article.create{|a| a.title = 'my create init block test'}
87
+ article.title.should == 'my create init block test'
88
+ article.should_not be_new
89
+ end
90
+
91
+ it "yields new instance to block before saving (#create!)" do
92
+ article = Article.create{|a| a.title = 'my create bang init block test'}
93
+ article.title.should == 'my create bang init block test'
94
+ article.should_not be_new
95
+ end
96
+
84
97
  it "should trigger the create callbacks" do
85
98
  doc = WithCallBacks.create(:name => 'my other test')
86
99
  doc.run_before_create.should be_true
@@ -210,57 +223,66 @@ describe "Model Persistence" do
210
223
 
211
224
  it "should require the field" do
212
225
  lambda{@templated.save}.should raise_error
213
- @templated['important-field'] = 'very-important'
226
+ @templated['slug'] = 'very-important'
214
227
  @templated.save.should be_true
215
228
  end
216
229
 
217
230
  it "should save with the id" do
218
- @templated['important-field'] = 'very-important'
231
+ @templated['slug'] = 'very-important'
219
232
  @templated.save.should be_true
220
233
  t = WithTemplateAndUniqueID.get('very-important')
221
234
  t.should == @templated
222
235
  end
223
236
 
224
237
  it "should not change the id on update" do
225
- @templated['important-field'] = 'very-important'
238
+ @templated['slug'] = 'very-important'
226
239
  @templated.save.should be_true
227
- @templated['important-field'] = 'not-important'
240
+ @templated['slug'] = 'not-important'
228
241
  @templated.save.should be_true
229
242
  t = WithTemplateAndUniqueID.get('very-important')
230
243
  t.id.should == @templated.id
231
244
  end
232
245
 
233
246
  it "should raise an error when the id is taken" do
234
- @templated['important-field'] = 'very-important'
247
+ @templated['slug'] = 'very-important'
235
248
  @templated.save.should be_true
236
- lambda{WithTemplateAndUniqueID.new('important-field' => 'very-important').save}.should raise_error
249
+ lambda{WithTemplateAndUniqueID.new('slug' => 'very-important').save}.should raise_error
237
250
  end
238
251
 
239
252
  it "should set the id" do
240
- @templated['important-field'] = 'very-important'
253
+ @templated['slug'] = 'very-important'
241
254
  @templated.save.should be_true
242
255
  @templated.id.should == 'very-important'
243
256
  end
244
257
  end
245
-
258
+
246
259
  describe "destroying an instance" do
247
260
  before(:each) do
248
- @dobj = Basic.new
261
+ @dobj = Event.new
249
262
  @dobj.save.should be_true
250
263
  end
251
264
  it "should return true" do
252
265
  result = @dobj.destroy
253
266
  result.should be_true
254
267
  end
255
- it "should be resavable" do
268
+ it "should make it go away" do
256
269
  @dobj.destroy
257
- @dobj.rev.should be_nil
258
- @dobj.id.should be_nil
259
- @dobj.save.should be_true
270
+ lambda{Basic.get!(@dobj.id)}.should raise_error(CouchRest::Model::DocumentNotFound)
260
271
  end
261
- it "should make it go away" do
272
+ it "should freeze the object" do
273
+ @dobj.destroy
274
+ # In Ruby 1.9.2 this raises RuntimeError, in 1.8.7 TypeError, D'OH!
275
+ lambda { @dobj.subject = "Test" }.should raise_error(StandardError)
276
+ end
277
+ it "trying to save after should fail" do
278
+ @dobj.destroy
279
+ lambda { @dobj.save }.should raise_error(StandardError)
280
+ lambda{Basic.get!(@dobj.id)}.should raise_error(CouchRest::Model::DocumentNotFound)
281
+ end
282
+ it "should make destroyed? true" do
283
+ @dobj.destroyed?.should be_false
262
284
  @dobj.destroy
263
- lambda{Basic.get!(@dobj.id)}.should raise_error
285
+ @dobj.destroyed?.should be_true
264
286
  end
265
287
  end
266
288