norr-couchrest 0.30

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