will-couchrest 0.32.1

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 (98) hide show
  1. data/LICENSE +176 -0
  2. data/README.md +165 -0
  3. data/Rakefile +74 -0
  4. data/THANKS.md +18 -0
  5. data/examples/model/example.rb +144 -0
  6. data/examples/word_count/markov +38 -0
  7. data/examples/word_count/views/books/chunked-map.js +3 -0
  8. data/examples/word_count/views/books/united-map.js +1 -0
  9. data/examples/word_count/views/markov/chain-map.js +6 -0
  10. data/examples/word_count/views/markov/chain-reduce.js +7 -0
  11. data/examples/word_count/views/word_count/count-map.js +6 -0
  12. data/examples/word_count/views/word_count/count-reduce.js +3 -0
  13. data/examples/word_count/word_count.rb +46 -0
  14. data/examples/word_count/word_count_query.rb +40 -0
  15. data/examples/word_count/word_count_views.rb +26 -0
  16. data/history.txt +65 -0
  17. data/lib/couchrest.rb +199 -0
  18. data/lib/couchrest/commands/generate.rb +71 -0
  19. data/lib/couchrest/commands/push.rb +103 -0
  20. data/lib/couchrest/core/adapters/restclient.rb +35 -0
  21. data/lib/couchrest/core/database.rb +317 -0
  22. data/lib/couchrest/core/design.rb +79 -0
  23. data/lib/couchrest/core/document.rb +83 -0
  24. data/lib/couchrest/core/http_abstraction.rb +48 -0
  25. data/lib/couchrest/core/response.rb +16 -0
  26. data/lib/couchrest/core/server.rb +88 -0
  27. data/lib/couchrest/core/view.rb +4 -0
  28. data/lib/couchrest/helper/pager.rb +103 -0
  29. data/lib/couchrest/helper/streamer.rb +44 -0
  30. data/lib/couchrest/helper/upgrade.rb +51 -0
  31. data/lib/couchrest/mixins.rb +4 -0
  32. data/lib/couchrest/mixins/attachments.rb +31 -0
  33. data/lib/couchrest/mixins/callbacks.rb +483 -0
  34. data/lib/couchrest/mixins/class_proxy.rb +116 -0
  35. data/lib/couchrest/mixins/collection.rb +225 -0
  36. data/lib/couchrest/mixins/design_doc.rb +103 -0
  37. data/lib/couchrest/mixins/document_queries.rb +82 -0
  38. data/lib/couchrest/mixins/extended_attachments.rb +74 -0
  39. data/lib/couchrest/mixins/extended_document_mixins.rb +8 -0
  40. data/lib/couchrest/mixins/properties.rb +158 -0
  41. data/lib/couchrest/mixins/validation.rb +257 -0
  42. data/lib/couchrest/mixins/views.rb +173 -0
  43. data/lib/couchrest/monkeypatches.rb +113 -0
  44. data/lib/couchrest/more/casted_model.rb +29 -0
  45. data/lib/couchrest/more/extended_document.rb +246 -0
  46. data/lib/couchrest/more/property.rb +40 -0
  47. data/lib/couchrest/support/blank.rb +42 -0
  48. data/lib/couchrest/support/class.rb +176 -0
  49. data/lib/couchrest/support/rails.rb +35 -0
  50. data/lib/couchrest/validation/auto_validate.rb +161 -0
  51. data/lib/couchrest/validation/contextual_validators.rb +78 -0
  52. data/lib/couchrest/validation/validation_errors.rb +125 -0
  53. data/lib/couchrest/validation/validators/absent_field_validator.rb +74 -0
  54. data/lib/couchrest/validation/validators/confirmation_validator.rb +99 -0
  55. data/lib/couchrest/validation/validators/format_validator.rb +117 -0
  56. data/lib/couchrest/validation/validators/formats/email.rb +66 -0
  57. data/lib/couchrest/validation/validators/formats/url.rb +43 -0
  58. data/lib/couchrest/validation/validators/generic_validator.rb +120 -0
  59. data/lib/couchrest/validation/validators/length_validator.rb +134 -0
  60. data/lib/couchrest/validation/validators/method_validator.rb +89 -0
  61. data/lib/couchrest/validation/validators/numeric_validator.rb +104 -0
  62. data/lib/couchrest/validation/validators/required_field_validator.rb +109 -0
  63. data/spec/couchrest/core/couchrest_spec.rb +201 -0
  64. data/spec/couchrest/core/database_spec.rb +700 -0
  65. data/spec/couchrest/core/design_spec.rb +138 -0
  66. data/spec/couchrest/core/document_spec.rb +267 -0
  67. data/spec/couchrest/core/server_spec.rb +35 -0
  68. data/spec/couchrest/helpers/pager_spec.rb +122 -0
  69. data/spec/couchrest/helpers/streamer_spec.rb +23 -0
  70. data/spec/couchrest/more/casted_extended_doc_spec.rb +75 -0
  71. data/spec/couchrest/more/casted_model_spec.rb +177 -0
  72. data/spec/couchrest/more/extended_doc_attachment_spec.rb +135 -0
  73. data/spec/couchrest/more/extended_doc_spec.rb +588 -0
  74. data/spec/couchrest/more/extended_doc_subclass_spec.rb +98 -0
  75. data/spec/couchrest/more/extended_doc_view_spec.rb +426 -0
  76. data/spec/couchrest/more/property_spec.rb +169 -0
  77. data/spec/fixtures/attachments/README +3 -0
  78. data/spec/fixtures/attachments/couchdb.png +0 -0
  79. data/spec/fixtures/attachments/test.html +11 -0
  80. data/spec/fixtures/more/article.rb +34 -0
  81. data/spec/fixtures/more/card.rb +22 -0
  82. data/spec/fixtures/more/cat.rb +18 -0
  83. data/spec/fixtures/more/course.rb +14 -0
  84. data/spec/fixtures/more/event.rb +6 -0
  85. data/spec/fixtures/more/invoice.rb +17 -0
  86. data/spec/fixtures/more/person.rb +8 -0
  87. data/spec/fixtures/more/question.rb +6 -0
  88. data/spec/fixtures/more/service.rb +12 -0
  89. data/spec/fixtures/views/lib.js +3 -0
  90. data/spec/fixtures/views/test_view/lib.js +3 -0
  91. data/spec/fixtures/views/test_view/only-map.js +4 -0
  92. data/spec/fixtures/views/test_view/test-map.js +3 -0
  93. data/spec/fixtures/views/test_view/test-reduce.js +3 -0
  94. data/spec/spec.opts +6 -0
  95. data/spec/spec_helper.rb +37 -0
  96. data/utils/remap.rb +27 -0
  97. data/utils/subset.rb +30 -0
  98. metadata +198 -0
@@ -0,0 +1,98 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require File.join(FIXTURE_PATH, 'more', 'card')
3
+ require File.join(FIXTURE_PATH, 'more', 'course')
4
+
5
+ # add a default value
6
+ Card.property :bg_color, :default => '#ccc'
7
+
8
+ class BusinessCard < Card
9
+ property :extension_code
10
+ property :job_title
11
+ end
12
+
13
+ class DesignBusinessCard < BusinessCard
14
+ property :bg_color, :default => '#eee'
15
+ end
16
+
17
+ class OnlineCourse < Course
18
+ property :url
19
+ view_by :url
20
+ end
21
+
22
+ class Animal < CouchRest::ExtendedDocument
23
+ use_database TEST_SERVER.default_database
24
+ property :name
25
+ view_by :name
26
+ end
27
+
28
+ class Dog < Animal; end
29
+
30
+ describe "Subclassing an ExtendedDocument" do
31
+
32
+ before(:each) do
33
+ @card = BusinessCard.new
34
+ end
35
+
36
+ it "shouldn't messup the parent's properties" do
37
+ Card.properties.should_not == BusinessCard.properties
38
+ end
39
+
40
+ it "should share the same db default" do
41
+ @card.database.uri.should == Card.database.uri
42
+ end
43
+
44
+ it "should share the same autovalidation details" do
45
+ @card.auto_validation.should be_true
46
+ end
47
+
48
+ it "should have kept the validation details" do
49
+ @card.should_not be_valid
50
+ end
51
+
52
+ it "should have added the new validation details" do
53
+ validated_fields = @card.class.validators.contexts[:default].map{|v| v.field_name}
54
+ validated_fields.should include(:extension_code)
55
+ validated_fields.should include(:job_title)
56
+ end
57
+
58
+ it "should not add to the parent's validations" do
59
+ validated_fields = Card.validators.contexts[:default].map{|v| v.field_name}
60
+ validated_fields.should_not include(:extension_code)
61
+ validated_fields.should_not include(:job_title)
62
+ end
63
+
64
+ it "should inherit default property values" do
65
+ @card.bg_color.should == '#ccc'
66
+ end
67
+
68
+ it "should be able to overwrite a default property" do
69
+ DesignBusinessCard.new.bg_color.should == '#eee'
70
+ end
71
+
72
+ it "should have a design doc slug based on the subclass name" do
73
+ Course.refresh_design_doc
74
+ OnlineCourse.design_doc_slug.should =~ /^OnlineCourse/
75
+ end
76
+
77
+ it "should have its own design_doc_fresh" do
78
+ Animal.refresh_design_doc
79
+ Dog.design_doc_fresh.should_not == true
80
+ Dog.refresh_design_doc
81
+ Dog.design_doc_fresh.should == true
82
+ end
83
+
84
+ it "should not add views to the parent's design_doc" do
85
+ Course.design_doc['views'].keys.should_not include('by_url')
86
+ end
87
+
88
+ it "should not add the parent's views to its design doc" do
89
+ Course.refresh_design_doc
90
+ OnlineCourse.refresh_design_doc
91
+ OnlineCourse.design_doc['views'].keys.should_not include('by_title')
92
+ end
93
+
94
+ it "should have an all view with a guard clause for couchrest-type == subclass name in the map function" do
95
+ OnlineCourse.design_doc['views']['all']['map'].should =~ /if \(doc\['couchrest-type'\] == 'OnlineCourse'\)/
96
+ end
97
+ end
98
+
@@ -0,0 +1,426 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require File.join(FIXTURE_PATH, 'more', 'article')
3
+ require File.join(FIXTURE_PATH, 'more', 'course')
4
+
5
+ describe "ExtendedDocument views" do
6
+
7
+ class Unattached < CouchRest::ExtendedDocument
8
+ # Note: no use_database here
9
+ property :title
10
+ property :questions
11
+ property :professor
12
+ view_by :title
13
+ end
14
+
15
+ describe "a model with simple views and a default param" do
16
+ before(:all) do
17
+ Article.all.map{|a| a.destroy(true)}
18
+ Article.database.bulk_delete
19
+ written_at = Time.now - 24 * 3600 * 7
20
+ @titles = ["this and that", "also interesting", "more fun", "some junk"]
21
+ @titles.each do |title|
22
+ a = Article.new(:title => title)
23
+ a.date = written_at
24
+ a.save
25
+ written_at += 24 * 3600
26
+ end
27
+ end
28
+
29
+ it "should have a design doc" do
30
+ Article.design_doc["views"]["by_date"].should_not be_nil
31
+ end
32
+
33
+ it "should save the design doc" do
34
+ Article.by_date #rescue nil
35
+ doc = Article.database.get Article.design_doc.id
36
+ doc['views']['by_date'].should_not be_nil
37
+ end
38
+
39
+ it "should return the matching raw view result" do
40
+ view = Article.by_date :raw => true
41
+ view['rows'].length.should == 4
42
+ end
43
+
44
+ it "should not include non-Articles" do
45
+ Article.database.save_doc({"date" => 1})
46
+ view = Article.by_date :raw => true
47
+ view['rows'].length.should == 4
48
+ end
49
+
50
+ it "should return the matching objects (with default argument :descending => true)" do
51
+ articles = Article.by_date
52
+ articles.collect{|a|a.title}.should == @titles.reverse
53
+ end
54
+
55
+ it "should allow you to override default args" do
56
+ articles = Article.by_date :descending => false
57
+ articles.collect{|a|a.title}.should == @titles
58
+ end
59
+ end
60
+
61
+ describe "another model with a simple view" do
62
+ before(:all) do
63
+ reset_test_db!
64
+ %w{aaa bbb ddd eee}.each do |title|
65
+ Course.new(:title => title).save
66
+ end
67
+ end
68
+ it "should make the design doc upon first query" do
69
+ Course.by_title
70
+ doc = Course.design_doc
71
+ doc['views']['all']['map'].should include('Course')
72
+ end
73
+ it "should can query via view" do
74
+ # register methods with method-missing, for local dispatch. method
75
+ # missing lookup table, no heuristics.
76
+ view = Course.view :by_title
77
+ designed = Course.by_title
78
+ view.should == designed
79
+ end
80
+ it "should get them" do
81
+ rs = Course.by_title
82
+ rs.length.should == 4
83
+ end
84
+ it "should yield" do
85
+ courses = []
86
+ Course.view(:by_title) do |course|
87
+ courses << course
88
+ end
89
+ courses[0]["doc"]["title"].should =='aaa'
90
+ end
91
+ it "should yield with by_key method" do
92
+ courses = []
93
+ Course.by_title do |course|
94
+ courses << course
95
+ end
96
+ courses[0]["doc"]["title"].should =='aaa'
97
+ end
98
+ end
99
+
100
+
101
+ describe "a ducktype view" do
102
+ before(:all) do
103
+ reset_test_db!
104
+ @id = DB.save_doc({:dept => true})['id']
105
+ end
106
+ it "should setup" do
107
+ duck = Course.get(@id) # from a different db
108
+ duck["dept"].should == true
109
+ end
110
+ it "should make the design doc" do
111
+ @as = Course.by_dept
112
+ @doc = Course.design_doc
113
+ @doc["views"]["by_dept"]["map"].should_not include("couchrest")
114
+ end
115
+ it "should not look for class" do
116
+ @as = Course.by_dept
117
+ @as[0]['_id'].should == @id
118
+ end
119
+ end
120
+
121
+ describe "a model class not tied to a database" do
122
+ before(:all) do
123
+ reset_test_db!
124
+ @db = DB
125
+ %w{aaa bbb ddd eee}.each do |title|
126
+ u = Unattached.new(:title => title)
127
+ u.database = @db
128
+ u.save
129
+ @first_id ||= u.id
130
+ end
131
+ end
132
+ it "should barf on all if no database given" do
133
+ lambda{Unattached.all}.should raise_error
134
+ end
135
+ it "should query all" do
136
+ Unattached.cleanup_design_docs!(@db)
137
+ rs = Unattached.all :database => @db
138
+ rs.length.should == 4
139
+ end
140
+ it "should barf on query if no database given" do
141
+ lambda{Unattached.view :by_title}.should raise_error
142
+ end
143
+ it "should make the design doc upon first query" do
144
+ Unattached.by_title :database => @db
145
+ doc = Unattached.design_doc
146
+ doc['views']['all']['map'].should include('Unattached')
147
+ end
148
+ it "should merge query params" do
149
+ rs = Unattached.by_title :database=>@db, :startkey=>"bbb", :endkey=>"eee"
150
+ rs.length.should == 3
151
+ end
152
+ it "should query via view" do
153
+ view = Unattached.view :by_title, :database=>@db
154
+ designed = Unattached.by_title :database=>@db
155
+ view.should == designed
156
+ end
157
+ it "should yield" do
158
+ things = []
159
+ Unattached.view(:by_title, :database=>@db) do |thing|
160
+ things << thing
161
+ end
162
+ things[0]["doc"]["title"].should =='aaa'
163
+ end
164
+ it "should yield with by_key method" do
165
+ things = []
166
+ Unattached.by_title(:database=>@db) do |thing|
167
+ things << thing
168
+ end
169
+ things[0]["doc"]["title"].should =='aaa'
170
+ end
171
+ it "should return nil on get if no database given" do
172
+ Unattached.get("aaa").should be_nil
173
+ end
174
+ it "should barf on get! if no database given" do
175
+ lambda{Unattached.get!("aaa")}.should raise_error
176
+ end
177
+ it "should get from specific database" do
178
+ u = Unattached.get(@first_id, @db)
179
+ u.title.should == "aaa"
180
+ end
181
+ it "should barf on first if no database given" do
182
+ lambda{Unattached.first}.should raise_error
183
+ end
184
+ it "should get first" do
185
+ u = Unattached.first :database=>@db
186
+ u.title.should =~ /\A...\z/
187
+ end
188
+ it "should barf on all_design_doc_versions if no database given" do
189
+ lambda{Unattached.all_design_doc_versions}.should raise_error
190
+ end
191
+ it "should be able to cleanup the db/bump the revision number" do
192
+ # if the previous specs were not run, the model_design_doc will be blank
193
+ Unattached.use_database DB
194
+ Unattached.view_by :questions
195
+ Unattached.by_questions(:database => @db)
196
+ original_revision = Unattached.model_design_doc(@db)['_rev']
197
+ Unattached.cleanup_design_docs!(@db)
198
+ Unattached.model_design_doc(@db)['_rev'].should_not == original_revision
199
+ end
200
+ end
201
+
202
+ describe "class proxy" do
203
+ before(:all) do
204
+ reset_test_db!
205
+ # setup the class default doc to save the design doc
206
+ Unattached.use_database nil # just to be sure it is really unattached
207
+ @us = Unattached.on(DB)
208
+ %w{aaa bbb ddd eee}.each do |title|
209
+ u = @us.new(:title => title)
210
+ u.save
211
+ @first_id ||= u.id
212
+ end
213
+ end
214
+ it "should query all" do
215
+ rs = @us.all
216
+ rs.length.should == 4
217
+ end
218
+ it "should count" do
219
+ @us.count.should == 4
220
+ end
221
+ it "should make the design doc upon first query" do
222
+ @us.by_title
223
+ doc = @us.design_doc
224
+ doc['views']['all']['map'].should include('Unattached')
225
+ end
226
+ it "should merge query params" do
227
+ rs = @us.by_title :startkey=>"bbb", :endkey=>"eee"
228
+ rs.length.should == 3
229
+ end
230
+ it "should query via view" do
231
+ view = @us.view :by_title
232
+ designed = @us.by_title
233
+ view.should == designed
234
+ end
235
+ it "should yield" do
236
+ things = []
237
+ @us.view(:by_title) do |thing|
238
+ things << thing
239
+ end
240
+ things[0]["doc"]["title"].should =='aaa'
241
+ end
242
+ it "should yield with by_key method" do
243
+ things = []
244
+ @us.by_title do |thing|
245
+ things << thing
246
+ end
247
+ things[0]["doc"]["title"].should =='aaa'
248
+ end
249
+ it "should get from specific database" do
250
+ u = @us.get(@first_id)
251
+ u.title.should == "aaa"
252
+ end
253
+ it "should get first" do
254
+ u = @us.first
255
+ u.title.should =~ /\A...\z/
256
+ end
257
+ it "should clean up design docs left around on specific database" do
258
+ @us.by_title
259
+ original_id = @us.model_design_doc['_rev']
260
+ Unattached.view_by :professor
261
+ @us.by_professor
262
+ @us.model_design_doc['_rev'].should_not == original_id
263
+ end
264
+ end
265
+
266
+ describe "a model with a compound key view" do
267
+ before(:all) do
268
+ Article.by_user_id_and_date.each{|a| a.destroy(true)}
269
+ Article.database.bulk_delete
270
+ written_at = Time.now - 24 * 3600 * 7
271
+ @titles = ["uniq one", "even more interesting", "less fun", "not junk"]
272
+ @user_ids = ["quentin", "aaron"]
273
+ @titles.each_with_index do |title,i|
274
+ u = i % 2
275
+ a = Article.new(:title => title, :user_id => @user_ids[u])
276
+ a.date = written_at
277
+ a.save
278
+ written_at += 24 * 3600
279
+ end
280
+ end
281
+ it "should create the design doc" do
282
+ Article.by_user_id_and_date rescue nil
283
+ doc = Article.design_doc
284
+ doc['views']['by_date'].should_not be_nil
285
+ end
286
+ it "should sort correctly" do
287
+ articles = Article.by_user_id_and_date
288
+ articles.collect{|a|a['user_id']}.should == ['aaron', 'aaron', 'quentin',
289
+ 'quentin']
290
+ articles[1].title.should == 'not junk'
291
+ end
292
+ it "should be queryable with couchrest options" do
293
+ articles = Article.by_user_id_and_date :limit => 1, :startkey => 'quentin'
294
+ articles.length.should == 1
295
+ articles[0].title.should == "even more interesting"
296
+ end
297
+ end
298
+
299
+ describe "with a custom view" do
300
+ before(:all) do
301
+ @titles = ["very uniq one", "even less interesting", "some fun",
302
+ "really junk", "crazy bob"]
303
+ @tags = ["cool", "lame"]
304
+ @titles.each_with_index do |title,i|
305
+ u = i % 2
306
+ a = Article.new(:title => title, :tags => [@tags[u]])
307
+ a.save
308
+ end
309
+ end
310
+ it "should be available raw" do
311
+ view = Article.by_tags :raw => true
312
+ view['rows'].length.should == 5
313
+ end
314
+
315
+ it "should be default to :reduce => false" do
316
+ ars = Article.by_tags
317
+ ars.first.tags.first.should == 'cool'
318
+ end
319
+
320
+ it "should be raw when reduce is true" do
321
+ view = Article.by_tags :reduce => true, :group => true
322
+ view['rows'].find{|r|r['key'] == 'cool'}['value'].should == 3
323
+ end
324
+ end
325
+
326
+ # TODO: moved to Design, delete
327
+ describe "adding a view" do
328
+ before(:each) do
329
+ reset_test_db!
330
+ Article.by_date
331
+ @original_doc_rev = Article.model_design_doc['_rev']
332
+ @design_docs = Article.database.documents :startkey => "_design/", :endkey => "_design/\u9999"
333
+ end
334
+ it "should not create a design doc on view definition" do
335
+ Article.view_by :created_at
336
+ newdocs = Article.database.documents :startkey => "_design/", :endkey => "_design/\u9999"
337
+ newdocs["rows"].length.should == @design_docs["rows"].length
338
+ end
339
+ it "should create a new version of the design document on view access" do
340
+ ddocs = Article.all_design_doc_versions["rows"].length
341
+ Article.view_by :updated_at
342
+ Article.by_updated_at
343
+ @original_doc_rev.should_not == Article.model_design_doc['_rev']
344
+ Article.design_doc["views"].keys.should include("by_updated_at")
345
+ end
346
+ end
347
+
348
+ describe "with a collection" do
349
+ before(:all) do
350
+ reset_test_db!
351
+ @titles = ["very uniq one", "really interesting", "some fun",
352
+ "really awesome", "crazy bob", "this rocks", "super rad"]
353
+ @titles.each_with_index do |title,i|
354
+ a = Article.new(:title => title, :date => Date.today)
355
+ a.save
356
+ end
357
+ end
358
+ it "should return a proxy that looks like an array of 7 Article objects" do
359
+ articles = Article.by_date :key => Date.today
360
+ articles.class.should == Array
361
+ articles.size.should == 7
362
+ end
363
+ it "should get a subset of articles using paginate" do
364
+ articles = Article.by_date :key => Date.today
365
+ articles.paginate(:page => 1, :per_page => 3).size.should == 3
366
+ articles.paginate(:page => 2, :per_page => 3).size.should == 3
367
+ articles.paginate(:page => 3, :per_page => 3).size.should == 1
368
+ end
369
+ it "should get all articles, a few at a time, using paginated each" do
370
+ articles = Article.by_date :key => Date.today
371
+ articles.paginated_each(:per_page => 3) do |a|
372
+ a.should_not be_nil
373
+ end
374
+ end
375
+ it "should have the amount of paginated pages" do
376
+ articles = Article.by_date :key => Date.today
377
+ articles.paginate(:per_page => 3)
378
+ articles.amount_pages.should == 3
379
+ end
380
+ it "should provide a class method to access the collection directly" do
381
+ articles = Article.collection_proxy_for('Article', 'by_date', :descending => true,
382
+ :key => Date.today, :include_docs => true)
383
+ articles.class.should == Array
384
+ articles.size.should == 7
385
+ end
386
+ it "should provide a class method for paginate" do
387
+ articles = Article.paginate(:design_doc => 'Article', :view_name => 'by_date',
388
+ :per_page => 3, :descending => true, :key => Date.today, :include_docs => true)
389
+ articles.size.should == 3
390
+
391
+ articles = Article.paginate(:design_doc => 'Article', :view_name => 'by_date',
392
+ :per_page => 3, :page => 2, :descending => true, :key => Date.today, :include_docs => true)
393
+ articles.size.should == 3
394
+
395
+ articles = Article.paginate(:design_doc => 'Article', :view_name => 'by_date',
396
+ :per_page => 3, :page => 3, :descending => true, :key => Date.today, :include_docs => true)
397
+ articles.size.should == 1
398
+ end
399
+ it "should provide a class method for paginated_each" do
400
+ options = { :design_doc => 'Article', :view_name => 'by_date',
401
+ :per_page => 3, :page => 1, :descending => true, :key => Date.today,
402
+ :include_docs => true }
403
+ Article.paginated_each(options) do |a|
404
+ a.should_not be_nil
405
+ end
406
+ end
407
+ it "should provide a class method to get a collection for a view" do
408
+ class Article
409
+ provides_collection :article_details, 'Article', 'by_date', :descending => true, :include_docs => true
410
+ end
411
+
412
+ articles = Article.find_all_article_details(:key => Date.today)
413
+ articles.class.should == Array
414
+ articles.size.should == 7
415
+ end
416
+ it "should raise an exception if design_doc is not provided" do
417
+ lambda{Article.collection_proxy_for(nil, 'by_date')}.should raise_error
418
+ lambda{Article.paginate(:view_name => 'by_date')}.should raise_error
419
+ end
420
+ it "should raise an exception if view_name is not provided" do
421
+ lambda{Article.collection_proxy_for('Article', nil)}.should raise_error
422
+ lambda{Article.paginate(:design_doc => 'Article')}.should raise_error
423
+ end
424
+ end
425
+
426
+ end