mattetti-couchrest 0.33 → 0.34

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.
@@ -66,7 +66,7 @@ describe "ExtendedDocument attachments" do
66
66
 
67
67
  it 'should set the content-type if passed' do
68
68
  @obj.create_attachment(:file => @file_ext, :name => @attachment_name, :content_type => @content_type)
69
- @obj['_attachments'][@attachment_name]['content-type'].should == @content_type
69
+ @obj['_attachments'][@attachment_name]['content_type'].should == @content_type
70
70
  end
71
71
  end
72
72
 
@@ -100,7 +100,7 @@ describe "ExtendedDocument attachments" do
100
100
  file = File.open(FIXTURE_PATH + '/attachments/README')
101
101
  @file.should_not == file
102
102
  @obj.update_attachment(:file => file, :name => @attachment_name, :content_type => @content_type)
103
- @obj['_attachments'][@attachment_name]['content-type'].should == @content_type
103
+ @obj['_attachments'][@attachment_name]['content_type'].should == @content_type
104
104
  end
105
105
 
106
106
  it 'should delete an attachment that exists' do
@@ -1,7 +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
-
4
+ require File.join(FIXTURE_PATH, 'more', 'cat')
5
5
 
6
6
  describe "ExtendedDocument" do
7
7
 
@@ -17,8 +17,11 @@ describe "ExtendedDocument" do
17
17
  end
18
18
 
19
19
  class WithCallBacks < CouchRest::ExtendedDocument
20
+ include ::CouchRest::Validation
20
21
  use_database TEST_SERVER.default_database
21
22
  property :name
23
+ property :run_before_validate
24
+ property :run_after_validate
22
25
  property :run_before_save
23
26
  property :run_after_save
24
27
  property :run_before_create
@@ -26,24 +29,56 @@ describe "ExtendedDocument" do
26
29
  property :run_before_update
27
30
  property :run_after_update
28
31
 
29
- save_callback :before do |object|
32
+ before_validate do |object|
33
+ object.run_before_validate = true
34
+ end
35
+ after_validate do |object|
36
+ object.run_after_validate = true
37
+ end
38
+ before_save do |object|
30
39
  object.run_before_save = true
31
40
  end
32
- save_callback :after do |object|
41
+ after_save do |object|
33
42
  object.run_after_save = true
34
43
  end
35
- create_callback :before do |object|
44
+ before_create do |object|
36
45
  object.run_before_create = true
37
46
  end
38
- create_callback :after do |object|
47
+ after_create do |object|
39
48
  object.run_after_create = true
40
49
  end
41
- update_callback :before do |object|
50
+ before_update do |object|
42
51
  object.run_before_update = true
43
52
  end
44
- update_callback :after do |object|
53
+ after_update do |object|
45
54
  object.run_after_update = true
46
55
  end
56
+
57
+ property :run_one
58
+ property :run_two
59
+ property :run_three
60
+
61
+ before_save :run_one_method, :run_two_method do |object|
62
+ object.run_three = true
63
+ end
64
+ def run_one_method
65
+ self.run_one = true
66
+ end
67
+ def run_two_method
68
+ self.run_two = true
69
+ end
70
+
71
+ attr_accessor :run_it
72
+ property :conditional_one
73
+ property :conditional_two
74
+
75
+ before_save :conditional_one_method, :conditional_two_method, :if => proc { self.run_it }
76
+ def conditional_one_method
77
+ self.conditional_one = true
78
+ end
79
+ def conditional_two_method
80
+ self.conditional_two = true
81
+ end
47
82
  end
48
83
 
49
84
  class WithTemplateAndUniqueID < CouchRest::ExtendedDocument
@@ -85,15 +120,12 @@ describe "ExtendedDocument" do
85
120
  end
86
121
 
87
122
  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
123
+ it "should be a new document" do
94
124
  @obj = Basic.new
95
125
  @obj.rev.should be_nil
96
- @obj.should be_a_new_document
126
+ @obj.should be_new
127
+ @obj.should be_new_document
128
+ @obj.should be_new_record
97
129
  end
98
130
  end
99
131
 
@@ -101,7 +133,7 @@ describe "ExtendedDocument" do
101
133
  it "should instantialize and save a document" do
102
134
  article = Article.create(:title => 'my test')
103
135
  article.title.should == 'my test'
104
- article.should_not be_new_document
136
+ article.should_not be_new
105
137
  end
106
138
 
107
139
  it "should trigger the create callbacks" do
@@ -125,6 +157,27 @@ describe "ExtendedDocument" do
125
157
  @art.update_attributes_without_saving('date' => Time.now, :title => "super danger")
126
158
  @art['title'].should == "super danger"
127
159
  end
160
+ it "should silently ignore _id" do
161
+ @art.update_attributes_without_saving('_id' => 'foobar')
162
+ @art['_id'].should_not == 'foobar'
163
+ end
164
+ it "should silently ignore _rev" do
165
+ @art.update_attributes_without_saving('_rev' => 'foobar')
166
+ @art['_rev'].should_not == 'foobar'
167
+ end
168
+ it "should silently ignore created_at" do
169
+ @art.update_attributes_without_saving('created_at' => 'foobar')
170
+ @art['created_at'].should_not == 'foobar'
171
+ end
172
+ it "should silently ignore updated_at" do
173
+ @art.update_attributes_without_saving('updated_at' => 'foobar')
174
+ @art['updated_at'].should_not == 'foobar'
175
+ end
176
+ it "should also work using attributes= alias" do
177
+ @art.respond_to?(:attributes=).should be_true
178
+ @art.attributes = {'date' => Time.now, :title => "something else"}
179
+ @art['title'].should == "something else"
180
+ end
128
181
 
129
182
  it "should flip out if an attribute= method is missing" do
130
183
  lambda {
@@ -409,6 +462,25 @@ describe "ExtendedDocument" do
409
462
  it "should set the type" do
410
463
  @sobj['couchrest-type'].should == 'Basic'
411
464
  end
465
+
466
+ describe "save!" do
467
+
468
+ before(:each) do
469
+ @sobj = Card.new(:first_name => "Marcos", :last_name => "Tapajós")
470
+ end
471
+
472
+ it "should return true if save the document" do
473
+ @sobj.save!.should == true
474
+ end
475
+
476
+ it "should raise error if don't save the document" do
477
+ @sobj.first_name = nil
478
+ lambda { @sobj.save!.should == true }.should raise_error(RuntimeError)
479
+ end
480
+
481
+ end
482
+
483
+
412
484
  end
413
485
 
414
486
  describe "saving a model with a unique_id configured" do
@@ -419,7 +491,7 @@ describe "ExtendedDocument" do
419
491
  end
420
492
 
421
493
  it "should be a new document" do
422
- @art.should be_a_new_document
494
+ @art.should be_new
423
495
  @art.title.should be_nil
424
496
  end
425
497
 
@@ -527,12 +599,46 @@ describe "ExtendedDocument" do
527
599
  @doc = WithCallBacks.new
528
600
  end
529
601
 
602
+
603
+ describe "validate" do
604
+ it "should run before_validate before validating" do
605
+ @doc.run_before_validate.should be_nil
606
+ @doc.should be_valid
607
+ @doc.run_before_validate.should be_true
608
+ end
609
+ it "should run after_validate after validating" do
610
+ @doc.run_after_validate.should be_nil
611
+ @doc.should be_valid
612
+ @doc.run_after_validate.should be_true
613
+ end
614
+ end
530
615
  describe "save" do
531
616
  it "should run the after filter after saving" do
532
617
  @doc.run_after_save.should be_nil
533
618
  @doc.save.should be_true
534
619
  @doc.run_after_save.should be_true
535
620
  end
621
+ it "should run the grouped callbacks before saving" do
622
+ @doc.run_one.should be_nil
623
+ @doc.run_two.should be_nil
624
+ @doc.run_three.should be_nil
625
+ @doc.save.should be_true
626
+ @doc.run_one.should be_true
627
+ @doc.run_two.should be_true
628
+ @doc.run_three.should be_true
629
+ end
630
+ it "should not run conditional callbacks" do
631
+ @doc.run_it = false
632
+ @doc.save.should be_true
633
+ @doc.conditional_one.should be_nil
634
+ @doc.conditional_two.should be_nil
635
+ end
636
+ it "should run conditional callbacks" do
637
+ @doc.run_it = true
638
+ @doc.save.should be_true
639
+ @doc.conditional_one.should be_true
640
+ @doc.conditional_two.should be_true
641
+ end
536
642
  end
537
643
  describe "create" do
538
644
  it "should run the before save filter when creating" do
@@ -585,4 +691,49 @@ describe "ExtendedDocument" do
585
691
  @doc.other_arg.should == "foo-foo"
586
692
  end
587
693
  end
694
+
695
+ describe "recursive validation on an extended document" do
696
+ before :each do
697
+ reset_test_db!
698
+ @cat = Cat.new(:name => 'Sockington')
699
+ end
700
+
701
+ it "should not save if a nested casted model is invalid" do
702
+ @cat.favorite_toy = CatToy.new
703
+ @cat.should_not be_valid
704
+ @cat.save.should be_false
705
+ lambda{@cat.save!}.should raise_error
706
+ end
707
+
708
+ it "should save when nested casted model is valid" do
709
+ @cat.favorite_toy = CatToy.new(:name => 'Squeaky')
710
+ @cat.should be_valid
711
+ @cat.save.should be_true
712
+ lambda{@cat.save!}.should_not raise_error
713
+ end
714
+
715
+ it "should not save when nested collection contains an invalid casted model" do
716
+ @cat.toys = [CatToy.new(:name => 'Feather'), CatToy.new]
717
+ @cat.should_not be_valid
718
+ @cat.save.should be_false
719
+ lambda{@cat.save!}.should raise_error
720
+ end
721
+
722
+ it "should save when nested collection contains valid casted models" do
723
+ @cat.toys = [CatToy.new(:name => 'feather'), CatToy.new(:name => 'ball-o-twine')]
724
+ @cat.should be_valid
725
+ @cat.save.should be_true
726
+ lambda{@cat.save!}.should_not raise_error
727
+ end
728
+
729
+ it "should not fail if the nested casted model doesn't have validation" do
730
+ Cat.property :trainer, :cast_as => 'Person'
731
+ Cat.validates_present :name
732
+ cat = Cat.new(:name => 'Mr Bigglesworth')
733
+ cat.trainer = Person.new
734
+ cat.trainer.validatable?.should be_false
735
+ cat.should be_valid
736
+ cat.save.should be_true
737
+ end
738
+ end
588
739
  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
 
@@ -132,14 +133,17 @@ describe "ExtendedDocument properties" do
132
133
  describe "casting" do
133
134
  describe "cast keys to any type" do
134
135
  before(:all) do
135
- event_doc = { :subject => "Some event", :occurs_at => Time.now }
136
+ event_doc = { :subject => "Some event", :occurs_at => Time.now, :end_date => Date.today }
136
137
  e = Event.database.save_doc event_doc
137
138
 
138
139
  @event = Event.get e['id']
139
140
  end
140
- it "should cast created_at to Time" do
141
+ it "should cast occurs_at to Time" do
141
142
  @event['occurs_at'].should be_an_instance_of(Time)
142
143
  end
144
+ it "should cast end_date to Date" do
145
+ @event['end_date'].should be_an_instance_of(Date)
146
+ end
143
147
  end
144
148
 
145
149
  describe "casting to Float object" do
@@ -191,5 +195,69 @@ describe "ExtendedDocument properties" do
191
195
  end
192
196
 
193
197
  end
198
+ end
199
+
200
+ describe "a newly created casted model" do
201
+ before(:each) do
202
+ reset_test_db!
203
+ @cat = Cat.new(:name => 'Toonces')
204
+ @squeaky_mouse = CatToy.new(:name => 'Squeaky')
205
+ end
206
+
207
+ describe "assigned assigned to a casted property" do
208
+ it "should have casted_by set to its parent" do
209
+ @squeaky_mouse.casted_by.should be_nil
210
+ @cat.favorite_toy = @squeaky_mouse
211
+ @squeaky_mouse.casted_by.should === @cat
212
+ end
213
+ end
214
+
215
+ describe "appended to a casted collection" do
216
+ it "should have casted_by set to its parent" do
217
+ @squeaky_mouse.casted_by.should be_nil
218
+ @cat.toys << @squeaky_mouse
219
+ @squeaky_mouse.casted_by.should === @cat
220
+ @cat.save
221
+ @cat.toys.first.casted_by.should === @cat
222
+ end
223
+ end
194
224
 
225
+ describe "list assigned to a casted collection" do
226
+ it "should have casted_by set on all elements" do
227
+ toy1 = CatToy.new(:name => 'Feather')
228
+ toy2 = CatToy.new(:name => 'Mouse')
229
+ @cat.toys = [toy1, toy2]
230
+ toy1.casted_by.should === @cat
231
+ toy2.casted_by.should === @cat
232
+ @cat.save
233
+ @cat = Cat.get(@cat.id)
234
+ @cat.toys[0].casted_by.should === @cat
235
+ @cat.toys[1].casted_by.should === @cat
236
+ end
237
+ end
195
238
  end
239
+
240
+ describe "a casted model retrieved from the database" do
241
+ before(:each) do
242
+ reset_test_db!
243
+ @cat = Cat.new(:name => 'Stimpy')
244
+ @cat.favorite_toy = CatToy.new(:name => 'Stinky')
245
+ @cat.toys << CatToy.new(:name => 'Feather')
246
+ @cat.toys << CatToy.new(:name => 'Mouse')
247
+ @cat.save
248
+ @cat = Cat.get(@cat.id)
249
+ end
250
+
251
+ describe "as a casted property" do
252
+ it "should already be casted_by its parent" do
253
+ @cat.favorite_toy.casted_by.should === @cat
254
+ end
255
+ end
256
+
257
+ describe "from a casted collection" do
258
+ it "should already be casted_by its parent" do
259
+ @cat.toys[0].casted_by.should === @cat
260
+ @cat.toys[1].casted_by.should === @cat
261
+ end
262
+ end
263
+ 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