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
@@ -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