norr-couchrest 0.33.02 → 0.33.06

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,7 @@
1
1
  require File.expand_path("../../../spec_helper", __FILE__)
2
2
  require File.join(FIXTURE_PATH, 'more', 'article')
3
3
  require File.join(FIXTURE_PATH, 'more', 'course')
4
+ require File.join(FIXTURE_PATH, 'more', 'cat')
4
5
 
5
6
 
6
7
  describe "ExtendedDocument" do
@@ -17,8 +18,11 @@ describe "ExtendedDocument" do
17
18
  end
18
19
 
19
20
  class WithCallBacks < CouchRest::ExtendedDocument
21
+ include ::CouchRest::Validation
20
22
  use_database TEST_SERVER.default_database
21
23
  property :name
24
+ property :run_before_validate
25
+ property :run_after_validate
22
26
  property :run_before_save
23
27
  property :run_after_save
24
28
  property :run_before_create
@@ -26,24 +30,56 @@ describe "ExtendedDocument" do
26
30
  property :run_before_update
27
31
  property :run_after_update
28
32
 
29
- save_callback :before do |object|
33
+ before_validate do |object|
34
+ object.run_before_validate = true
35
+ end
36
+ after_validate do |object|
37
+ object.run_after_validate = true
38
+ end
39
+ before_save do |object|
30
40
  object.run_before_save = true
31
41
  end
32
- save_callback :after do |object|
42
+ after_save do |object|
33
43
  object.run_after_save = true
34
44
  end
35
- create_callback :before do |object|
45
+ before_create do |object|
36
46
  object.run_before_create = true
37
47
  end
38
- create_callback :after do |object|
48
+ after_create do |object|
39
49
  object.run_after_create = true
40
50
  end
41
- update_callback :before do |object|
51
+ before_update do |object|
42
52
  object.run_before_update = true
43
53
  end
44
- update_callback :after do |object|
54
+ after_update do |object|
45
55
  object.run_after_update = true
46
56
  end
57
+
58
+ property :run_one
59
+ property :run_two
60
+ property :run_three
61
+
62
+ before_save :run_one_method, :run_two_method do |object|
63
+ object.run_three = true
64
+ end
65
+ def run_one_method
66
+ self.run_one = true
67
+ end
68
+ def run_two_method
69
+ self.run_two = true
70
+ end
71
+
72
+ attr_accessor :run_it
73
+ property :conditional_one
74
+ property :conditional_two
75
+
76
+ before_save :conditional_one_method, :conditional_two_method, :if => proc { self.run_it }
77
+ def conditional_one_method
78
+ self.conditional_one = true
79
+ end
80
+ def conditional_two_method
81
+ self.conditional_two = true
82
+ end
47
83
  end
48
84
 
49
85
  class WithTemplateAndUniqueID < CouchRest::ExtendedDocument
@@ -85,15 +121,12 @@ describe "ExtendedDocument" do
85
121
  end
86
122
 
87
123
  describe "a new model" do
88
- it "should be a new_record" do
89
- @obj = Basic.new
90
- @obj.rev.should be_nil
91
- @obj.should be_a_new_record
92
- end
93
- it "should be a new_document" do
124
+ it "should be a new document" do
94
125
  @obj = Basic.new
95
126
  @obj.rev.should be_nil
96
- @obj.should be_a_new_document
127
+ @obj.should be_new
128
+ @obj.should be_new_document
129
+ @obj.should be_new_record
97
130
  end
98
131
  end
99
132
 
@@ -101,7 +134,7 @@ describe "ExtendedDocument" do
101
134
  it "should instantialize and save a document" do
102
135
  article = Article.create(:title => 'my test')
103
136
  article.title.should == 'my test'
104
- article.should_not be_new_document
137
+ article.should_not be_new
105
138
  end
106
139
 
107
140
  it "should trigger the create callbacks" do
@@ -125,6 +158,27 @@ describe "ExtendedDocument" do
125
158
  @art.update_attributes_without_saving('date' => Time.now, :title => "super danger")
126
159
  @art['title'].should == "super danger"
127
160
  end
161
+ it "should silently ignore _id" do
162
+ @art.update_attributes_without_saving('_id' => 'foobar')
163
+ @art['_id'].should_not == 'foobar'
164
+ end
165
+ it "should silently ignore _rev" do
166
+ @art.update_attributes_without_saving('_rev' => 'foobar')
167
+ @art['_rev'].should_not == 'foobar'
168
+ end
169
+ it "should silently ignore created_at" do
170
+ @art.update_attributes_without_saving('created_at' => 'foobar')
171
+ @art['created_at'].should_not == 'foobar'
172
+ end
173
+ it "should silently ignore updated_at" do
174
+ @art.update_attributes_without_saving('updated_at' => 'foobar')
175
+ @art['updated_at'].should_not == 'foobar'
176
+ end
177
+ it "should also work using attributes= alias" do
178
+ @art.respond_to?(:attributes=).should be_true
179
+ @art.attributes = {'date' => Time.now, :title => "something else"}
180
+ @art['title'].should == "something else"
181
+ end
128
182
 
129
183
  it "should flip out if an attribute= method is missing" do
130
184
  lambda {
@@ -419,7 +473,7 @@ describe "ExtendedDocument" do
419
473
  end
420
474
 
421
475
  it "should be a new document" do
422
- @art.should be_a_new_document
476
+ @art.should be_new
423
477
  @art.title.should be_nil
424
478
  end
425
479
 
@@ -527,12 +581,46 @@ describe "ExtendedDocument" do
527
581
  @doc = WithCallBacks.new
528
582
  end
529
583
 
584
+
585
+ describe "validate" do
586
+ it "should run before_validate before validating" do
587
+ @doc.run_before_validate.should be_nil
588
+ @doc.should be_valid
589
+ @doc.run_before_validate.should be_true
590
+ end
591
+ it "should run after_validate after validating" do
592
+ @doc.run_after_validate.should be_nil
593
+ @doc.should be_valid
594
+ @doc.run_after_validate.should be_true
595
+ end
596
+ end
530
597
  describe "save" do
531
598
  it "should run the after filter after saving" do
532
599
  @doc.run_after_save.should be_nil
533
600
  @doc.save.should be_true
534
601
  @doc.run_after_save.should be_true
535
602
  end
603
+ it "should run the grouped callbacks before saving" do
604
+ @doc.run_one.should be_nil
605
+ @doc.run_two.should be_nil
606
+ @doc.run_three.should be_nil
607
+ @doc.save.should be_true
608
+ @doc.run_one.should be_true
609
+ @doc.run_two.should be_true
610
+ @doc.run_three.should be_true
611
+ end
612
+ it "should not run conditional callbacks" do
613
+ @doc.run_it = false
614
+ @doc.save.should be_true
615
+ @doc.conditional_one.should be_nil
616
+ @doc.conditional_two.should be_nil
617
+ end
618
+ it "should run conditional callbacks" do
619
+ @doc.run_it = true
620
+ @doc.save.should be_true
621
+ @doc.conditional_one.should be_true
622
+ @doc.conditional_two.should be_true
623
+ end
536
624
  end
537
625
  describe "create" do
538
626
  it "should run the before save filter when creating" do
@@ -585,4 +673,49 @@ describe "ExtendedDocument" do
585
673
  @doc.other_arg.should == "foo-foo"
586
674
  end
587
675
  end
676
+
677
+ describe "recursive validation on an extended document" do
678
+ before :each do
679
+ reset_test_db!
680
+ @cat = Cat.new(:name => 'Sockington')
681
+ end
682
+
683
+ it "should not save if a nested casted model is invalid" do
684
+ @cat.favorite_toy = CatToy.new
685
+ @cat.should_not be_valid
686
+ @cat.save.should be_false
687
+ lambda{@cat.save!}.should raise_error
688
+ end
689
+
690
+ it "should save when nested casted model is valid" do
691
+ @cat.favorite_toy = CatToy.new(:name => 'Squeaky')
692
+ @cat.should be_valid
693
+ @cat.save.should be_true
694
+ lambda{@cat.save!}.should_not raise_error
695
+ end
696
+
697
+ it "should not save when nested collection contains an invalid casted model" do
698
+ @cat.toys = [CatToy.new(:name => 'Feather'), CatToy.new]
699
+ @cat.should_not be_valid
700
+ @cat.save.should be_false
701
+ lambda{@cat.save!}.should raise_error
702
+ end
703
+
704
+ it "should save when nested collection contains valid casted models" do
705
+ @cat.toys = [CatToy.new(:name => 'feather'), CatToy.new(:name => 'ball-o-twine')]
706
+ @cat.should be_valid
707
+ @cat.save.should be_true
708
+ lambda{@cat.save!}.should_not raise_error
709
+ end
710
+
711
+ it "should not fail if the nested casted model doesn't have validation" do
712
+ Cat.property :trainer, :cast_as => 'Person'
713
+ Cat.validates_present :name
714
+ cat = Cat.new(:name => 'Mr Bigglesworth')
715
+ cat.trainer = Person.new
716
+ cat.trainer.validatable?.should be_false
717
+ cat.should be_valid
718
+ cat.save.should be_true
719
+ end
720
+ end
588
721
  end
@@ -348,12 +348,19 @@ describe "ExtendedDocument views" do
348
348
  describe "with a collection" do
349
349
  before(:all) do
350
350
  reset_test_db!
351
- @titles = ["very uniq one", "really interesting", "some fun",
351
+ titles = ["very uniq one", "really interesting", "some fun",
352
352
  "really awesome", "crazy bob", "this rocks", "super rad"]
353
- @titles.each_with_index do |title,i|
353
+ titles.each_with_index do |title,i|
354
354
  a = Article.new(:title => title, :date => Date.today)
355
355
  a.save
356
356
  end
357
+
358
+ titles = ["yesterday very uniq one", "yesterday really interesting", "yesterday some fun",
359
+ "yesterday really awesome", "yesterday crazy bob", "yesterday this rocks"]
360
+ titles.each_with_index do |title,i|
361
+ a = Article.new(:title => title, :date => Date.today - 1)
362
+ a.save
363
+ end
357
364
  end
358
365
  require 'date'
359
366
  it "should return a proxy that looks like an array of 7 Article objects" do
@@ -373,10 +380,6 @@ describe "ExtendedDocument views" do
373
380
  a.should_not be_nil
374
381
  end
375
382
  end
376
- it "should have the amount of paginated pages" do
377
- articles = Article.by_date :key => Date.today
378
- articles.paginate(:per_page => 3).amount_pages.should == 3
379
- end
380
383
  it "should provide a class method to access the collection directly" do
381
384
  articles = Article.collection_proxy_for('Article', 'by_date', :descending => true,
382
385
  :key => Date.today, :include_docs => true)
@@ -421,6 +424,14 @@ describe "ExtendedDocument views" do
421
424
  lambda{Article.collection_proxy_for('Article', nil)}.should raise_error
422
425
  lambda{Article.paginate(:design_doc => 'Article')}.should raise_error
423
426
  end
427
+ it "should be able to span multiple keys" do
428
+ articles = Article.by_date :startkey => Date.today, :endkey => Date.today - 1
429
+ articles.paginate(:page => 1, :per_page => 3).size.should == 3
430
+ articles.paginate(:page => 2, :per_page => 3).size.should == 3
431
+ articles.paginate(:page => 3, :per_page => 3).size.should == 3
432
+ articles.paginate(:page => 4, :per_page => 3).size.should == 3
433
+ articles.paginate(:page => 5, :per_page => 3).size.should == 1
434
+ end
424
435
  end
425
436
 
426
437
  end
@@ -4,6 +4,7 @@ require File.join(FIXTURE_PATH, 'more', 'card')
4
4
  require File.join(FIXTURE_PATH, 'more', 'invoice')
5
5
  require File.join(FIXTURE_PATH, 'more', 'service')
6
6
  require File.join(FIXTURE_PATH, 'more', 'event')
7
+ require File.join(FIXTURE_PATH, 'more', 'cat')
7
8
 
8
9
 
9
10
  describe "ExtendedDocument properties" do
@@ -94,7 +95,7 @@ describe "ExtendedDocument properties" do
94
95
  @invoice.location = nil
95
96
  @invoice.should_not be_valid
96
97
  @invoice.save.should be_false
97
- @invoice.should be_new_document
98
+ @invoice.should be_new
98
99
  end
99
100
  end
100
101
 
@@ -191,5 +192,69 @@ describe "ExtendedDocument properties" do
191
192
  end
192
193
 
193
194
  end
195
+ end
196
+
197
+ describe "a newly created casted model" do
198
+ before(:each) do
199
+ reset_test_db!
200
+ @cat = Cat.new(:name => 'Toonces')
201
+ @squeaky_mouse = CatToy.new(:name => 'Squeaky')
202
+ end
203
+
204
+ describe "assigned assigned to a casted property" do
205
+ it "should have casted_by set to its parent" do
206
+ @squeaky_mouse.casted_by.should be_nil
207
+ @cat.favorite_toy = @squeaky_mouse
208
+ @squeaky_mouse.casted_by.should === @cat
209
+ end
210
+ end
211
+
212
+ describe "appended to a casted collection" do
213
+ it "should have casted_by set to its parent" do
214
+ @squeaky_mouse.casted_by.should be_nil
215
+ @cat.toys << @squeaky_mouse
216
+ @squeaky_mouse.casted_by.should === @cat
217
+ @cat.save
218
+ @cat.toys.first.casted_by.should === @cat
219
+ end
220
+ end
194
221
 
222
+ describe "list assigned to a casted collection" do
223
+ it "should have casted_by set on all elements" do
224
+ toy1 = CatToy.new(:name => 'Feather')
225
+ toy2 = CatToy.new(:name => 'Mouse')
226
+ @cat.toys = [toy1, toy2]
227
+ toy1.casted_by.should === @cat
228
+ toy2.casted_by.should === @cat
229
+ @cat.save
230
+ @cat = Cat.get(@cat.id)
231
+ @cat.toys[0].casted_by.should === @cat
232
+ @cat.toys[1].casted_by.should === @cat
233
+ end
234
+ end
195
235
  end
236
+
237
+ describe "a casted model retrieved from the database" do
238
+ before(:each) do
239
+ reset_test_db!
240
+ @cat = Cat.new(:name => 'Stimpy')
241
+ @cat.favorite_toy = CatToy.new(:name => 'Stinky')
242
+ @cat.toys << CatToy.new(:name => 'Feather')
243
+ @cat.toys << CatToy.new(:name => 'Mouse')
244
+ @cat.save
245
+ @cat = Cat.get(@cat.id)
246
+ end
247
+
248
+ describe "as a casted property" do
249
+ it "should already be casted_by its parent" do
250
+ @cat.favorite_toy.casted_by.should === @cat
251
+ end
252
+ end
253
+
254
+ describe "from a casted collection" do
255
+ it "should already be casted_by its parent" do
256
+ @cat.toys[0].casted_by.should === @cat
257
+ @cat.toys[1].casted_by.should === @cat
258
+ end
259
+ end
260
+ end
@@ -26,9 +26,9 @@ class Article < CouchRest::ExtendedDocument
26
26
 
27
27
  timestamps!
28
28
 
29
- save_callback :before, :generate_slug_from_title
29
+ before_save :generate_slug_from_title
30
30
 
31
31
  def generate_slug_from_title
32
- self['slug'] = title.downcase.gsub(/[^a-z0-9]/,'-').squeeze('-').gsub(/^\-|\-$/,'') if new_document?
32
+ self['slug'] = title.downcase.gsub(/[^a-z0-9]/,'-').squeeze('-').gsub(/^\-|\-$/,'') if new?
33
33
  end
34
34
  end
@@ -6,6 +6,7 @@ class Cat < CouchRest::ExtendedDocument
6
6
 
7
7
  property :name
8
8
  property :toys, :cast_as => ['CatToy'], :default => []
9
+ property :favorite_toy, :cast_as => 'CatToy'
9
10
  end
10
11
 
11
12
  class CatToy < Hash
@@ -1,6 +1,7 @@
1
1
  class Person < Hash
2
2
  include ::CouchRest::CastedModel
3
3
  property :name
4
+ property :pet, :cast_as => 'Cat'
4
5
 
5
6
  def last_name
6
7
  name.last
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: norr-couchrest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.33.02
4
+ version: 0.33.06
5
5
  platform: ruby
6
6
  authors:
7
7
  - J. Chris Anderson
@@ -172,7 +172,6 @@ files:
172
172
  - utils/subset.rb
173
173
  has_rdoc: false
174
174
  homepage: http://github.com/jchris/couchrest
175
- licenses:
176
175
  post_install_message:
177
176
  rdoc_options: []
178
177
 
@@ -193,7 +192,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
193
192
  requirements: []
194
193
 
195
194
  rubyforge_project:
196
- rubygems_version: 1.3.5
195
+ rubygems_version: 1.2.0
197
196
  signing_key:
198
197
  specification_version: 3
199
198
  summary: Lean and RESTful interface to CouchDB.