couchrest_model 1.1.0.beta5 → 1.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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