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
@@ -1,5 +1,6 @@
1
1
  # encoding: utf-8
2
2
  require File.expand_path('../../spec_helper', __FILE__)
3
+ require File.join(FIXTURE_PATH, 'more', 'article')
3
4
  require File.join(FIXTURE_PATH, 'more', 'cat')
4
5
  require File.join(FIXTURE_PATH, 'more', 'person')
5
6
  require File.join(FIXTURE_PATH, 'more', 'card')
@@ -8,6 +9,7 @@ require File.join(FIXTURE_PATH, 'more', 'service')
8
9
  require File.join(FIXTURE_PATH, 'more', 'event')
9
10
  require File.join(FIXTURE_PATH, 'more', 'user')
10
11
  require File.join(FIXTURE_PATH, 'more', 'course')
12
+ require File.join(FIXTURE_PATH, "more", "key_chain")
11
13
 
12
14
 
13
15
  describe "Model properties" do
@@ -71,6 +73,24 @@ describe "Model properties" do
71
73
  @card.updated_at.should_not be_nil
72
74
  end
73
75
 
76
+ describe "#as_json" do
77
+
78
+ it "should provide a simple hash from model" do
79
+ @card.as_json.class.should eql(Hash)
80
+ end
81
+
82
+ it "should remove properties from Hash if value is nil" do
83
+ @card.last_name = nil
84
+ @card.as_json.keys.include?('last_name').should be_false
85
+ end
86
+
87
+ it "should pass options to Active Support's as_json" do
88
+ @card.last_name = "Aimonetti"
89
+ @card.as_json(:only => 'last_name').should eql('last_name' => 'Aimonetti')
90
+ end
91
+
92
+ end
93
+
74
94
  describe '#read_attribute' do
75
95
  it "should let you use read_attribute method" do
76
96
  @card.last_name = "Aimonetti"
@@ -220,6 +240,16 @@ describe "Model properties" do
220
240
 
221
241
  end
222
242
 
243
+ describe "properties of hash of casted models" do
244
+ it "should be able to assign a casted hash to a hash property" do
245
+ chain = KeyChain.new
246
+ keys = {"House" => "8==$", "Office" => "<>==U"}
247
+ chain.keys = keys
248
+ chain.keys = chain.keys
249
+ chain.keys.should == keys
250
+ end
251
+ end
252
+
223
253
  describe "properties of array of casted models" do
224
254
 
225
255
  before(:each) do
@@ -246,9 +276,9 @@ describe "properties of array of casted models" do
246
276
  end
247
277
 
248
278
  it "should allow attribute to be set from hash with ordered keys and sub-hashes" do
249
- @course.questions = { '0' => {:q => "Test1"}, '1' => {:q => 'Test2'} }
250
- @course.questions.length.should eql(2)
251
- @course.questions.last.q.should eql('Test2')
279
+ @course.questions = { '10' => {:q => 'Test10'}, '0' => {:q => "Test1"}, '1' => {:q => 'Test2'} }
280
+ @course.questions.length.should eql(3)
281
+ @course.questions.last.q.should eql('Test10')
252
282
  @course.questions.last.class.should eql(Question)
253
283
  end
254
284
 
@@ -265,7 +295,7 @@ describe "properties of array of casted models" do
265
295
  it "should raise an error if attempting to set single value for array type" do
266
296
  lambda {
267
297
  @course.questions = Question.new(:q => 'test1')
268
- }.should raise_error
298
+ }.should raise_error(/Expecting an array/)
269
299
  end
270
300
 
271
301
 
@@ -296,6 +326,28 @@ describe "a casted model retrieved from the database" do
296
326
  end
297
327
  end
298
328
 
329
+ describe "nested models (not casted)" do
330
+ before(:each) do
331
+ reset_test_db!
332
+ @cat = ChildCat.new(:name => 'Stimpy')
333
+ @cat.mother = {:name => 'Stinky'}
334
+ @cat.siblings = [{:name => 'Feather'}, {:name => 'Felix'}]
335
+ @cat.save
336
+ @cat = ChildCat.get(@cat.id)
337
+ end
338
+
339
+ it "should correctly save single relation" do
340
+ @cat.mother.name.should eql('Stinky')
341
+ @cat.mother.casted_by.should eql(@cat)
342
+ end
343
+
344
+ it "should correctly save collection" do
345
+ @cat.siblings.first.name.should eql("Feather")
346
+ @cat.siblings.last.casted_by.should eql(@cat)
347
+ end
348
+
349
+ end
350
+
299
351
  describe "Property Class" do
300
352
 
301
353
  it "should provide name as string" do
@@ -339,6 +391,28 @@ describe "Property Class" do
339
391
  property.init_method.should eql('parse')
340
392
  end
341
393
 
394
+ describe "#build" do
395
+ it "should allow instantiation of new object" do
396
+ property = CouchRest::Model::Property.new(:test, Date)
397
+ obj = property.build(2011, 05, 21)
398
+ obj.should eql(Date.new(2011, 05, 21))
399
+ end
400
+ it "should use init_method if provided" do
401
+ property = CouchRest::Model::Property.new(:test, Date, :init_method => 'parse')
402
+ obj = property.build("2011-05-21")
403
+ obj.should eql(Date.new(2011, 05, 21))
404
+ end
405
+ it "should use init_method Proc if provided" do
406
+ property = CouchRest::Model::Property.new(:test, Date, :init_method => Proc.new{|v| Date.parse(v)})
407
+ obj = property.build("2011-05-21")
408
+ obj.should eql(Date.new(2011, 05, 21))
409
+ end
410
+ it "should raise error if no class" do
411
+ property = CouchRest::Model::Property.new(:test)
412
+ lambda { property.build }.should raise_error(StandardError, /Cannot build/)
413
+ end
414
+ end
415
+
342
416
  ## Property Casting method. More thoroughly tested in typecast_spec.
343
417
 
344
418
  describe "casting" do
@@ -367,6 +441,18 @@ describe "Property Class" do
367
441
  property.cast(parent, ["2010-06-01", "2010-06-02"]).class.should eql(CouchRest::Model::CastedArray)
368
442
  end
369
443
 
444
+ it "should allow instantion of model via CastedArray#build" do
445
+ property = CouchRest::Model::Property.new(:dates, [Date])
446
+ parent = Article.new
447
+ ary = property.cast(parent, [])
448
+ obj = ary.build(2011, 05, 21)
449
+ ary.length.should eql(1)
450
+ ary.first.should eql(Date.new(2011, 05, 21))
451
+ obj = ary.build(2011, 05, 22)
452
+ ary.length.should eql(2)
453
+ ary.last.should eql(Date.new(2011, 05, 22))
454
+ end
455
+
370
456
  it "should raise and error if value is array when type is not" do
371
457
  property = CouchRest::Model::Property.new(:test, Date)
372
458
  parent = mock("FooClass")
@@ -87,7 +87,7 @@ describe "Proxyable" do
87
87
  DummyProxyable.proxy_for(:cats)
88
88
  @obj = DummyProxyable.new
89
89
  CouchRest::Model::Proxyable::ModelProxy.should_receive(:new).with(Cat, @obj, 'dummy_proxyable', 'db').and_return(true)
90
- @obj.should_receive('proxy_database').and_return('db')
90
+ @obj.should_receive(:proxy_database).and_return('db')
91
91
  @obj.cats
92
92
  end
93
93
 
@@ -165,15 +165,13 @@ describe "Proxyable" do
165
165
  end
166
166
 
167
167
  it "should proxy new call" do
168
- Cat.should_receive(:new).and_return({})
169
- @obj.should_receive(:proxy_update).and_return(true)
170
- @obj.new
168
+ @obj.should_receive(:proxy_block_update).with(:new, 'attrs', 'opts')
169
+ @obj.new('attrs', 'opts')
171
170
  end
172
171
 
173
172
  it "should proxy build_from_database" do
174
- Cat.should_receive(:build_from_database).and_return({})
175
- @obj.should_receive(:proxy_update).with({}).and_return(true)
176
- @obj.build_from_database
173
+ @obj.should_receive(:proxy_block_update).with(:build_from_database, 'attrs', 'opts')
174
+ @obj.build_from_database('attrs', 'opts')
177
175
  end
178
176
 
179
177
  describe "#method_missing" do
@@ -313,6 +311,15 @@ describe "Proxyable" do
313
311
  @obj.send(:proxy_update_all, docs)
314
312
  end
315
313
 
314
+ describe "#proxy_block_update" do
315
+ it "should proxy block updates" do
316
+ doc = { }
317
+ @obj.model.should_receive(:new).and_yield(doc)
318
+ @obj.should_receive(:proxy_update).with(doc)
319
+ @obj.send(:proxy_block_update, :new)
320
+ end
321
+ end
322
+
316
323
  end
317
324
 
318
325
  end
@@ -16,7 +16,11 @@ describe "Validations" do
16
16
  before(:all) do
17
17
  @objs = ['title 1', 'title 2', 'title 3'].map{|t| WithUniqueValidation.create(:title => t)}
18
18
  end
19
-
19
+
20
+ it "should create a new view if none defined before performing" do
21
+ WithUniqueValidation.has_view?(:by_title).should be_true
22
+ end
23
+
20
24
  it "should validate a new unique document" do
21
25
  @obj = WithUniqueValidation.create(:title => 'title 4')
22
26
  @obj.new?.should_not be_true
@@ -35,6 +39,7 @@ describe "Validations" do
35
39
  @obj.should be_valid
36
40
  end
37
41
 
42
+
38
43
  it "should allow own view to be specified" do
39
44
  # validates_uniqueness_of :code, :view => 'all'
40
45
  WithUniqueValidationView.create(:title => 'title 1', :code => '1234')
@@ -50,6 +55,13 @@ describe "Validations" do
50
55
  }.should raise_error
51
56
  end
52
57
 
58
+ it "should not try to create a defined view" do
59
+ WithUniqueValidationView.validates_uniqueness_of :title, :view => 'fooobar'
60
+ WithUniqueValidationView.has_view?('fooobar').should be_false
61
+ WithUniqueValidationView.has_view?('by_title').should be_false
62
+ end
63
+
64
+
53
65
  it "should not try to create new view when already defined" do
54
66
  @obj = @objs[1]
55
67
  @obj.class.should_not_receive('view_by')
@@ -60,6 +72,11 @@ describe "Validations" do
60
72
  end
61
73
 
62
74
  context "with a proxy parameter" do
75
+
76
+ it "should create a new view despite proxy" do
77
+ WithUniqueValidationProxy.has_view?(:by_title).should be_true
78
+ end
79
+
63
80
  it "should be used" do
64
81
  @obj = WithUniqueValidationProxy.new(:title => 'test 6')
65
82
  proxy = @obj.should_receive('proxy').and_return(@obj.class)
@@ -86,15 +86,16 @@ end
86
86
  class WithTemplateAndUniqueID < CouchRest::Model::Base
87
87
  use_database TEST_SERVER.default_database
88
88
  unique_id do |model|
89
- model['important-field']
89
+ model.slug
90
90
  end
91
+ property :slug
91
92
  property :preset, :default => 'value'
92
93
  property :has_no_default
93
94
  end
94
95
 
95
96
  class WithGetterAndSetterMethods < CouchRest::Model::Base
96
97
  use_database TEST_SERVER.default_database
97
-
98
+
98
99
  property :other_arg
99
100
  def arg
100
101
  other_arg
@@ -107,7 +108,7 @@ end
107
108
 
108
109
  class WithAfterInitializeMethod < CouchRest::Model::Base
109
110
  use_database TEST_SERVER.default_database
110
-
111
+
111
112
  property :some_value
112
113
 
113
114
  def after_initialize
@@ -22,6 +22,7 @@ class Article < CouchRest::Model::Base
22
22
 
23
23
  property :date, Date
24
24
  property :slug, :read_only => true
25
+ property :user_id
25
26
  property :title
26
27
  property :tags, [String]
27
28
 
@@ -17,3 +17,7 @@ class Cat < CouchRest::Model::Base
17
17
  property :number
18
18
  end
19
19
 
20
+ class ChildCat < Cat
21
+ property :mother, Cat
22
+ property :siblings, [Cat]
23
+ end
@@ -0,0 +1,5 @@
1
+ class KeyChain < CouchRest::Model::Base
2
+ use_database(DB)
3
+
4
+ property(:keys, Hash)
5
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: couchrest_model
3
3
  version: !ruby/object:Gem::Version
4
- hash: -1848230063
4
+ hash: 977940566
5
5
  prerelease: true
6
6
  segments:
7
7
  - 1
8
8
  - 1
9
9
  - 0
10
- - beta5
11
- version: 1.1.0.beta5
10
+ - rc1
11
+ version: 1.1.0.rc1
12
12
  platform: ruby
13
13
  authors:
14
14
  - J. Chris Anderson
@@ -31,13 +31,13 @@ dependencies:
31
31
  requirements:
32
32
  - - "="
33
33
  - !ruby/object:Gem::Version
34
- hash: -1876988167
34
+ hash: -1876988186
35
35
  segments:
36
36
  - 1
37
37
  - 1
38
38
  - 0
39
- - pre2
40
- version: 1.1.0.pre2
39
+ - pre3
40
+ version: 1.1.0.pre3
41
41
  type: :runtime
42
42
  version_requirements: *id001
43
43
  - !ruby/object:Gem::Dependency
@@ -67,8 +67,7 @@ dependencies:
67
67
  segments:
68
68
  - 3
69
69
  - 0
70
- - 0
71
- version: 3.0.0
70
+ version: "3.0"
72
71
  type: :runtime
73
72
  version_requirements: *id003
74
73
  - !ruby/object:Gem::Dependency
@@ -88,35 +87,35 @@ dependencies:
88
87
  type: :runtime
89
88
  version_requirements: *id004
90
89
  - !ruby/object:Gem::Dependency
91
- name: railties
90
+ name: rspec
92
91
  prerelease: false
93
92
  requirement: &id005 !ruby/object:Gem::Requirement
94
93
  none: false
95
94
  requirements:
96
95
  - - ~>
97
96
  - !ruby/object:Gem::Version
98
- hash: 7
97
+ hash: 23
99
98
  segments:
100
- - 3
101
- - 0
99
+ - 2
100
+ - 6
102
101
  - 0
103
- version: 3.0.0
104
- type: :runtime
102
+ version: 2.6.0
103
+ type: :development
105
104
  version_requirements: *id005
106
105
  - !ruby/object:Gem::Dependency
107
- name: rspec
106
+ name: json
108
107
  prerelease: false
109
108
  requirement: &id006 !ruby/object:Gem::Requirement
110
109
  none: false
111
110
  requirements:
112
- - - ">="
111
+ - - ~>
113
112
  - !ruby/object:Gem::Version
114
- hash: 15
113
+ hash: 1
115
114
  segments:
116
- - 2
117
- - 0
118
- - 0
119
- version: 2.0.0
115
+ - 1
116
+ - 5
117
+ - 1
118
+ version: 1.5.1
120
119
  type: :development
121
120
  version_requirements: *id006
122
121
  - !ruby/object:Gem::Dependency
@@ -184,6 +183,7 @@ files:
184
183
  - lib/couchrest/model/property.rb
185
184
  - lib/couchrest/model/property_protection.rb
186
185
  - lib/couchrest/model/proxyable.rb
186
+ - lib/couchrest/model/support/couchrest_database.rb
187
187
  - lib/couchrest/model/support/couchrest_design.rb
188
188
  - lib/couchrest/model/typecast.rb
189
189
  - lib/couchrest/model/validations.rb
@@ -232,6 +232,7 @@ files:
232
232
  - spec/fixtures/more/course.rb
233
233
  - spec/fixtures/more/event.rb
234
234
  - spec/fixtures/more/invoice.rb
235
+ - spec/fixtures/more/key_chain.rb
235
236
  - spec/fixtures/more/person.rb
236
237
  - spec/fixtures/more/question.rb
237
238
  - spec/fixtures/more/sale_entry.rb