couch_view 0.0.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.
- data/features/couch_view.array.feature +28 -0
- data/features/couch_view.config.feature +396 -0
- data/features/couch_view.count.proxy.feature +284 -0
- data/features/couch_view.feature +359 -0
- data/features/couch_view.map.feature +117 -0
- data/features/couch_view.proxy.feature +236 -0
- data/features/setup/env.rb +15 -0
- data/features/setup/hooks.rb +7 -0
- data/features/step_definitions/couch_view.array.rb +7 -0
- data/features/step_definitions/couch_view.config.rb +11 -0
- data/features/step_definitions/couch_view.count.proxy.rb +23 -0
- data/features/step_definitions/couch_view.map.rb +19 -0
- data/features/step_definitions/couch_view.proxy.rb +15 -0
- data/features/step_definitions/couch_view.rb +87 -0
- data/lib/couch_view/array.rb +9 -0
- data/lib/couch_view/config.rb +89 -0
- data/lib/couch_view/couch_view.rb +61 -0
- data/lib/couch_view/count_proxy.rb +27 -0
- data/lib/couch_view/map.rb +45 -0
- data/lib/couch_view/map_property.rb +7 -0
- data/lib/couch_view/proxy.rb +70 -0
- data/lib/couch_view/query_options.rb +43 -0
- data/lib/couch_view.rb +10 -0
- data/readme.markdown +307 -0
- metadata +174 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
Feature: All subsets of an array
|
2
|
+
|
3
|
+
|
4
|
+
Scenario: Generating all subsets of an array
|
5
|
+
|
6
|
+
Given an array of 3 elements:
|
7
|
+
"""
|
8
|
+
@array = [1,2,3]
|
9
|
+
"""
|
10
|
+
|
11
|
+
When I call the "all_combinations" method on it:
|
12
|
+
"""
|
13
|
+
@result = @array.all_combinations
|
14
|
+
"""
|
15
|
+
|
16
|
+
Then I should receive all of the subsets of my array:
|
17
|
+
"""
|
18
|
+
@result.should == [
|
19
|
+
[],
|
20
|
+
[1],
|
21
|
+
[2],
|
22
|
+
[3],
|
23
|
+
[1,2],
|
24
|
+
[1,3],
|
25
|
+
[2,3],
|
26
|
+
[1,2,3]
|
27
|
+
]
|
28
|
+
"""
|
@@ -0,0 +1,396 @@
|
|
1
|
+
Feature: CouchView::Config
|
2
|
+
|
3
|
+
A `CouchView::Config` consists of the following data:
|
4
|
+
* a CouchView::Map
|
5
|
+
* the conditions (if any) with which to extend that map
|
6
|
+
* the names of the views
|
7
|
+
* the reduce for the view
|
8
|
+
* the base name of the view
|
9
|
+
|
10
|
+
When you instantiate a CouchView::Config, you must provide both the model and the properties to map over:
|
11
|
+
|
12
|
+
class Article < CouchRest::Model::Base; end
|
13
|
+
|
14
|
+
config = CouchView::Config.new Article
|
15
|
+
config.map :prop1, :prop2
|
16
|
+
config.view_names #==> ["by_prop1_and_prop2"]
|
17
|
+
config.base_view_name #==> "by_prop1_and_prop2"
|
18
|
+
config.model #==> Article
|
19
|
+
|
20
|
+
You could, alternatively, provide it with a model and a CouchView::Map class:
|
21
|
+
|
22
|
+
class ById; include CouchView::Map; end
|
23
|
+
config = CouchView::Config.new Article
|
24
|
+
config.map ById
|
25
|
+
config.view_names #==> ["by_id"]
|
26
|
+
config.model #==> Article
|
27
|
+
|
28
|
+
By default, a `CouchView::Config` will assume a reduce of `_count`:
|
29
|
+
|
30
|
+
config.reduce #==> "_count"
|
31
|
+
|
32
|
+
You can override this by supplying your own reduce:
|
33
|
+
|
34
|
+
config.reduce "function(key, values){}"
|
35
|
+
config.reduce #==> "function(key, values){}"
|
36
|
+
|
37
|
+
The base name of your view is generated by the parameters passed to the "map" method.
|
38
|
+
|
39
|
+
If you want to override that, you can pass a new name to the "base_view_name" method:
|
40
|
+
|
41
|
+
config.base_view_name "funny"
|
42
|
+
|
43
|
+
Lastly, you can provide your `CouchView::Config` with conditions:
|
44
|
+
|
45
|
+
module Published
|
46
|
+
def conditions
|
47
|
+
"#{super} && doc.published == true"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
config.conditions Published
|
52
|
+
config.conditions #==> [Published]
|
53
|
+
|
54
|
+
You could also add conditions by passing a block to the map method:
|
55
|
+
|
56
|
+
config.map :label do
|
57
|
+
conditions Published
|
58
|
+
end
|
59
|
+
|
60
|
+
You can now ask your `Config` to return a hash containing all of the views (with their corresponding map/reduce) that you should setup on your model:
|
61
|
+
|
62
|
+
class Article < CouchRest::Model::Base
|
63
|
+
property :label
|
64
|
+
property :published, TrueClass, :default => false
|
65
|
+
end
|
66
|
+
|
67
|
+
config = CouchView::Config.new Article
|
68
|
+
config.map :label
|
69
|
+
|
70
|
+
module Published
|
71
|
+
def conditions
|
72
|
+
"#{super} && doc.published == true"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
config.conditions Published
|
77
|
+
|
78
|
+
config.views #==>
|
79
|
+
{
|
80
|
+
"by_label" => {
|
81
|
+
"map" => "function....",
|
82
|
+
"reduce" => "_count"
|
83
|
+
},
|
84
|
+
"by_label_published" => {
|
85
|
+
"map" => "function....",
|
86
|
+
"reduce" => "_count"
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
|
91
|
+
@db
|
92
|
+
Scenario: Generating a name based on the properties passed in to map over
|
93
|
+
|
94
|
+
Given the following model:
|
95
|
+
"""
|
96
|
+
class Article < CouchRest::Model::Base
|
97
|
+
include CouchView
|
98
|
+
property :label
|
99
|
+
property :name
|
100
|
+
end
|
101
|
+
"""
|
102
|
+
|
103
|
+
When I create a CouchView::Config to map over Article labels:
|
104
|
+
"""
|
105
|
+
@config = CouchView::Config.new Article
|
106
|
+
@config.map :label
|
107
|
+
"""
|
108
|
+
|
109
|
+
Then the config should report "by_label" as a view name:
|
110
|
+
"""
|
111
|
+
@config.view_names.should == ["by_label"]
|
112
|
+
"""
|
113
|
+
|
114
|
+
When I create a CouchView::Config to map over Article labels and names:
|
115
|
+
"""
|
116
|
+
@config = CouchView::Config.new Article
|
117
|
+
@config.map :label, :name
|
118
|
+
"""
|
119
|
+
|
120
|
+
Then the config should report "by_label" as a view name:
|
121
|
+
"""
|
122
|
+
@config.view_names.should == ["by_label_and_name"]
|
123
|
+
"""
|
124
|
+
|
125
|
+
When I create a CouchView::Map `ById`:
|
126
|
+
"""
|
127
|
+
class ById
|
128
|
+
include CouchView::Map
|
129
|
+
end
|
130
|
+
"""
|
131
|
+
|
132
|
+
And I create a CouchView::Config to map over article documents `ById`:
|
133
|
+
"""
|
134
|
+
@config = CouchView::Config.new Article
|
135
|
+
@config.map ById
|
136
|
+
"""
|
137
|
+
|
138
|
+
Then the config should report "by_id" as a view name:
|
139
|
+
"""
|
140
|
+
@config.view_names.should == ["by_id"]
|
141
|
+
"""
|
142
|
+
|
143
|
+
|
144
|
+
@db
|
145
|
+
Scenario: Setting a custom reduce
|
146
|
+
|
147
|
+
Given the following model:
|
148
|
+
"""
|
149
|
+
class Article < CouchRest::Model::Base
|
150
|
+
include CouchView
|
151
|
+
property :label
|
152
|
+
property :name
|
153
|
+
end
|
154
|
+
"""
|
155
|
+
|
156
|
+
When I create a CouchView::Config to map over Article labels:
|
157
|
+
"""
|
158
|
+
@config = CouchView::Config.new Article
|
159
|
+
@config.map :label
|
160
|
+
"""
|
161
|
+
|
162
|
+
Then the config should default the "reduce" to "_count":
|
163
|
+
"""
|
164
|
+
@config.reduce.should == "_count"
|
165
|
+
"""
|
166
|
+
|
167
|
+
When I change the "reduce" to a javascript function:
|
168
|
+
"""
|
169
|
+
@config.reduce "function(key, values){}"
|
170
|
+
"""
|
171
|
+
|
172
|
+
Then the config should return that function for the "reduce":
|
173
|
+
"""
|
174
|
+
@config.reduce.should == "function(key, values){}"
|
175
|
+
"""
|
176
|
+
|
177
|
+
|
178
|
+
@db
|
179
|
+
Scenario: Setting conditions on the view
|
180
|
+
|
181
|
+
Given the following model:
|
182
|
+
"""
|
183
|
+
class Article < CouchRest::Model::Base
|
184
|
+
include CouchView
|
185
|
+
property :label
|
186
|
+
property :name
|
187
|
+
end
|
188
|
+
"""
|
189
|
+
|
190
|
+
And the following conditions:
|
191
|
+
"""
|
192
|
+
module Published
|
193
|
+
def conditions
|
194
|
+
"#{super} && doc.published == true"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
module Visible
|
199
|
+
def conditions
|
200
|
+
"#{super} && doc.visible == true"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
"""
|
204
|
+
|
205
|
+
When I create a CouchView::Config to map over Article labels:
|
206
|
+
"""
|
207
|
+
@config = CouchView::Config.new Article
|
208
|
+
@config.map :label
|
209
|
+
"""
|
210
|
+
|
211
|
+
And I add the Published and Visible conditions to it:
|
212
|
+
"""
|
213
|
+
@config.conditions Published, Visible
|
214
|
+
"""
|
215
|
+
|
216
|
+
Then the conditions should be Published and Visible:
|
217
|
+
"""
|
218
|
+
@config.conditions.should == [Published, Visible]
|
219
|
+
"""
|
220
|
+
|
221
|
+
And the view names should include views for published, visible, and published/visible documents:
|
222
|
+
"""
|
223
|
+
@config.view_names.sort.should == ["by_label", "by_label_published", "by_label_published_visible", "by_label_visible"]
|
224
|
+
"""
|
225
|
+
|
226
|
+
|
227
|
+
@db @focus
|
228
|
+
Scenario: Creating conditions by passing a block to the map
|
229
|
+
|
230
|
+
Given the following model:
|
231
|
+
"""
|
232
|
+
class Article < CouchRest::Model::Base; end
|
233
|
+
"""
|
234
|
+
|
235
|
+
And the following conditions:
|
236
|
+
"""
|
237
|
+
module Published
|
238
|
+
def conditions
|
239
|
+
"#{super} && doc.published == true"
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
module Visible
|
244
|
+
def conditions
|
245
|
+
"#{super} && doc.visible == true"
|
246
|
+
end
|
247
|
+
end
|
248
|
+
"""
|
249
|
+
|
250
|
+
When I create a view config and specify conditions in a block on the `map` method:
|
251
|
+
"""
|
252
|
+
@config = CouchView::Config.new Article
|
253
|
+
@config.map :label do
|
254
|
+
conditions Published, Visible
|
255
|
+
end
|
256
|
+
"""
|
257
|
+
|
258
|
+
Then the conditions method on my config should return the conditions specified:
|
259
|
+
"""
|
260
|
+
@config.conditions.should == [Published, Visible]
|
261
|
+
"""
|
262
|
+
|
263
|
+
@db
|
264
|
+
Scenario: Getting all the views
|
265
|
+
|
266
|
+
Given the following model:
|
267
|
+
"""
|
268
|
+
class Article < CouchRest::Model::Base
|
269
|
+
include CouchView
|
270
|
+
property :label
|
271
|
+
property :name
|
272
|
+
end
|
273
|
+
"""
|
274
|
+
|
275
|
+
And the following conditions:
|
276
|
+
"""
|
277
|
+
module Published
|
278
|
+
def conditions
|
279
|
+
"#{super} && doc.published == true"
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
module Visible
|
284
|
+
def conditions
|
285
|
+
"#{super} && doc.visible == true"
|
286
|
+
end
|
287
|
+
end
|
288
|
+
"""
|
289
|
+
|
290
|
+
When I create a CouchView::Config to map over Article labels:
|
291
|
+
"""
|
292
|
+
@config = CouchView::Config.new Article
|
293
|
+
@config.map :label
|
294
|
+
"""
|
295
|
+
|
296
|
+
And I add the Published and Visible conditions to it:
|
297
|
+
"""
|
298
|
+
@config.conditions Published, Visible
|
299
|
+
"""
|
300
|
+
|
301
|
+
Then the views should include a "by_label" view:
|
302
|
+
"""
|
303
|
+
@config.views[:by_label][:map].should ==
|
304
|
+
"
|
305
|
+
function(doc){
|
306
|
+
if (doc['couchrest-type'] == 'Article')
|
307
|
+
emit(doc.label, null)
|
308
|
+
}
|
309
|
+
"
|
310
|
+
@config.views[:by_label][:reduce].should == "_count"
|
311
|
+
"""
|
312
|
+
|
313
|
+
And the views should include a "by_label_published" view:
|
314
|
+
"""
|
315
|
+
@config.views[:by_label_published][:map].should ==
|
316
|
+
"
|
317
|
+
function(doc){
|
318
|
+
if (doc['couchrest-type'] == 'Article' && doc.published == true)
|
319
|
+
emit(doc.label, null)
|
320
|
+
}
|
321
|
+
"
|
322
|
+
@config.views[:by_label_published][:reduce].should == "_count"
|
323
|
+
"""
|
324
|
+
|
325
|
+
And the views should include a "by_label_visible" view:
|
326
|
+
"""
|
327
|
+
@config.views[:by_label_visible][:map].should ==
|
328
|
+
"
|
329
|
+
function(doc){
|
330
|
+
if (doc['couchrest-type'] == 'Article' && doc.visible == true)
|
331
|
+
emit(doc.label, null)
|
332
|
+
}
|
333
|
+
"
|
334
|
+
@config.views[:by_label_visible][:reduce].should == "_count"
|
335
|
+
"""
|
336
|
+
|
337
|
+
And the views should include a "by_label_published_visible" view:
|
338
|
+
"""
|
339
|
+
@config.views[:by_label_published_visible][:map].should ==
|
340
|
+
"
|
341
|
+
function(doc){
|
342
|
+
if (doc['couchrest-type'] == 'Article' && doc.published == true && doc.visible == true)
|
343
|
+
emit(doc.label, null)
|
344
|
+
}
|
345
|
+
"
|
346
|
+
@config.views[:by_label_published_visible][:reduce].should == "_count"
|
347
|
+
"""
|
348
|
+
|
349
|
+
|
350
|
+
@db @focus
|
351
|
+
Scenario: Giving your view a custom base name
|
352
|
+
|
353
|
+
Given the following model:
|
354
|
+
"""
|
355
|
+
class Article < CouchRest::Model::Base
|
356
|
+
include CouchView
|
357
|
+
property :label
|
358
|
+
property :name
|
359
|
+
end
|
360
|
+
"""
|
361
|
+
|
362
|
+
And the following conditions:
|
363
|
+
"""
|
364
|
+
module Published
|
365
|
+
def conditions
|
366
|
+
"#{super} && doc.published == true"
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
module Visible
|
371
|
+
def conditions
|
372
|
+
"#{super} && doc.visible == true"
|
373
|
+
end
|
374
|
+
end
|
375
|
+
"""
|
376
|
+
|
377
|
+
When I create a CouchView::Config to map over Article labels:
|
378
|
+
"""
|
379
|
+
@config = CouchView::Config.new Article
|
380
|
+
@config.map :label
|
381
|
+
"""
|
382
|
+
|
383
|
+
And I give it a base name of "funny":
|
384
|
+
"""
|
385
|
+
@config.base_view_name "funny"
|
386
|
+
"""
|
387
|
+
|
388
|
+
And I add the Published and Visible conditions to it:
|
389
|
+
"""
|
390
|
+
@config.conditions Published, Visible
|
391
|
+
"""
|
392
|
+
|
393
|
+
Then the view names should include "funny" views for published, visible, and published/visible documents:
|
394
|
+
"""
|
395
|
+
@config.view_names.sort.should == ["funny", "funny_published", "funny_published_visible", "funny_visible"]
|
396
|
+
"""
|
@@ -0,0 +1,284 @@
|
|
1
|
+
Feature: CouchView::Count::Proxy
|
2
|
+
|
3
|
+
A `CouchView::Count::Proxy` is like a regular `CouchView::Proxy`, except that it defaults the CouchDB "reduce" option to "true".
|
4
|
+
|
5
|
+
proxy = CouchView::Count::Proxy SomeModel, :some_view
|
6
|
+
proxy._options #==> { "reduce" => true }
|
7
|
+
|
8
|
+
Another noticable difference: you can't call ".each" on the proxy unless you've set the "group" option to "true":
|
9
|
+
|
10
|
+
proxy = CouchView::Count::Proxy SomeModel, :some_view
|
11
|
+
|
12
|
+
proxy.each {...} #==> raises an exception "You can't call 'each' on a count proxy that doesn't set 'group' to 'true'."
|
13
|
+
|
14
|
+
If you've set "group" to true, then when you call ".each" on it, you will iterate over the key/value pairs in the response:
|
15
|
+
|
16
|
+
proxy.group(true).each do |key, value|
|
17
|
+
...
|
18
|
+
end
|
19
|
+
|
20
|
+
If you'd rather work with the raw (hash) response on a group level query, simply use the "get!" method:
|
21
|
+
|
22
|
+
proxy.get!
|
23
|
+
|
24
|
+
If you're not running a group level query, then "get!" will return the actual count (`Fixnum`):
|
25
|
+
|
26
|
+
proxy = CouchView::Count::Proxy SomeModel, :some_view
|
27
|
+
proxy.get! #==> 0, or some other positive integer
|
28
|
+
|
29
|
+
|
30
|
+
@db
|
31
|
+
Scenario: Options default to "reduce" => true
|
32
|
+
|
33
|
+
Given an Article model with a view "by_id":
|
34
|
+
"""
|
35
|
+
class Article < CouchRest::Model::Base
|
36
|
+
view_by :id
|
37
|
+
end
|
38
|
+
"""
|
39
|
+
|
40
|
+
When I instantiate a new CouchView::Map::Proxy with "Article" and ":by_id":
|
41
|
+
"""
|
42
|
+
@proxy = CouchView::Count::Proxy.new Article, :by_id
|
43
|
+
"""
|
44
|
+
|
45
|
+
Then the options on the proxy should default to "reduce" => true
|
46
|
+
"""
|
47
|
+
@proxy._options.should == {:reduce => true}
|
48
|
+
"""
|
49
|
+
|
50
|
+
|
51
|
+
@db
|
52
|
+
Scenario: ".each" should iterate over the key/value pairs of the 'rows' result:
|
53
|
+
|
54
|
+
Given the following map definition:
|
55
|
+
"""
|
56
|
+
class ByLabel
|
57
|
+
include CouchView::Map
|
58
|
+
|
59
|
+
def map
|
60
|
+
"
|
61
|
+
function(doc){
|
62
|
+
if (#{conditions})
|
63
|
+
emit(doc.label, null)
|
64
|
+
}
|
65
|
+
"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
"""
|
69
|
+
|
70
|
+
And an Article model that maps ByLabel:
|
71
|
+
"""
|
72
|
+
class Article < CouchRest::Model::Base
|
73
|
+
include CouchView
|
74
|
+
map ByLabel
|
75
|
+
end
|
76
|
+
"""
|
77
|
+
|
78
|
+
And several articles:
|
79
|
+
"""
|
80
|
+
Article.create :label => "fun-article"
|
81
|
+
Article.create :label => "awesome-article"
|
82
|
+
Article.create :label => "awesome-article"
|
83
|
+
"""
|
84
|
+
|
85
|
+
When I instantiate a new CouchView::Map::Proxy with "Article" and ":by_id":
|
86
|
+
"""
|
87
|
+
@proxy = CouchView::Count::Proxy.new Article, :by_by_label
|
88
|
+
"""
|
89
|
+
|
90
|
+
And I set the CouchDB "group" query option to "true":
|
91
|
+
"""
|
92
|
+
@proxy.group! true
|
93
|
+
"""
|
94
|
+
|
95
|
+
Then the ".each" method should iterate over the keys and values in the 'rows' array in the query response:
|
96
|
+
"""
|
97
|
+
@results = []
|
98
|
+
@proxy.each {|label, count| @results << {label => count}}
|
99
|
+
@results.first.should == {"awesome-article" => 2}
|
100
|
+
@results.last.should == {"fun-article" => 1}
|
101
|
+
@results.count.should == 2
|
102
|
+
"""
|
103
|
+
|
104
|
+
|
105
|
+
@db @focus
|
106
|
+
Scenario: ".get!" should return 0 when the reduce returns an empty 'rows' response:
|
107
|
+
|
108
|
+
Given the following map definition:
|
109
|
+
"""
|
110
|
+
class ByLabel
|
111
|
+
include CouchView::Map
|
112
|
+
|
113
|
+
def map
|
114
|
+
"
|
115
|
+
function(doc){
|
116
|
+
if (#{conditions})
|
117
|
+
emit(doc.label, null)
|
118
|
+
}
|
119
|
+
"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
"""
|
123
|
+
|
124
|
+
And an Article model that maps ByLabel:
|
125
|
+
"""
|
126
|
+
class Article < CouchRest::Model::Base
|
127
|
+
include CouchView
|
128
|
+
map ByLabel
|
129
|
+
end
|
130
|
+
"""
|
131
|
+
|
132
|
+
And there are no articles:
|
133
|
+
"""
|
134
|
+
Article.all.count.should == 0
|
135
|
+
"""
|
136
|
+
|
137
|
+
When I instantiate a new CouchView::Map::Proxy with "Article" and ":by_id":
|
138
|
+
"""
|
139
|
+
@proxy = CouchView::Count::Proxy.new Article, :by_by_label
|
140
|
+
"""
|
141
|
+
|
142
|
+
Then the ".get!" method should return 0:
|
143
|
+
"""
|
144
|
+
@proxy.get!.should == 0
|
145
|
+
"""
|
146
|
+
|
147
|
+
|
148
|
+
@db @focus
|
149
|
+
Scenario: ".get!" should return the 'value' of the first row of the 'rows' reduce response:
|
150
|
+
|
151
|
+
Given the following map definition:
|
152
|
+
"""
|
153
|
+
class ById
|
154
|
+
include CouchView::Map
|
155
|
+
end
|
156
|
+
"""
|
157
|
+
|
158
|
+
And an Article model that maps ByLabel:
|
159
|
+
"""
|
160
|
+
class Article < CouchRest::Model::Base
|
161
|
+
include CouchView
|
162
|
+
map ById
|
163
|
+
end
|
164
|
+
"""
|
165
|
+
|
166
|
+
And there are 2 articles:
|
167
|
+
"""
|
168
|
+
2.times { Article.create }
|
169
|
+
"""
|
170
|
+
|
171
|
+
When I instantiate a new CouchView::Map::Proxy with "Article" and ":by_by_id":
|
172
|
+
"""
|
173
|
+
@proxy = CouchView::Count::Proxy.new Article, :by_by_id
|
174
|
+
"""
|
175
|
+
|
176
|
+
Then the ".get!" method should return 2:
|
177
|
+
"""
|
178
|
+
@proxy.get!.should == 2
|
179
|
+
"""
|
180
|
+
|
181
|
+
|
182
|
+
|
183
|
+
@db @focus
|
184
|
+
Scenario: ".get!" should return the raw JSON (hash) response from CouchDB for a group query:
|
185
|
+
|
186
|
+
Given the following map definition:
|
187
|
+
"""
|
188
|
+
class ByLabel
|
189
|
+
include CouchView::Map
|
190
|
+
|
191
|
+
def map
|
192
|
+
"
|
193
|
+
function(doc){
|
194
|
+
if (#{conditions})
|
195
|
+
emit(doc.label, null)
|
196
|
+
}
|
197
|
+
"
|
198
|
+
end
|
199
|
+
end
|
200
|
+
"""
|
201
|
+
|
202
|
+
And an Article model that maps ByLabel:
|
203
|
+
"""
|
204
|
+
class Article < CouchRest::Model::Base
|
205
|
+
include CouchView
|
206
|
+
map ByLabel
|
207
|
+
end
|
208
|
+
"""
|
209
|
+
|
210
|
+
And several articles:
|
211
|
+
"""
|
212
|
+
Article.create :label => "fun-article"
|
213
|
+
Article.create :label => "awesome-article"
|
214
|
+
Article.create :label => "awesome-article"
|
215
|
+
"""
|
216
|
+
|
217
|
+
When I instantiate a new CouchView::Map::Proxy with "Article" and ":by_id":
|
218
|
+
"""
|
219
|
+
@proxy = CouchView::Count::Proxy.new Article, :by_by_label
|
220
|
+
"""
|
221
|
+
|
222
|
+
And I set the CouchDB "group" query option to "true":
|
223
|
+
"""
|
224
|
+
@proxy.group! true
|
225
|
+
"""
|
226
|
+
|
227
|
+
Then the ".get!" method should return the raw JSON response from CouchDB as a hash:
|
228
|
+
"""
|
229
|
+
@proxy.get!.should == {
|
230
|
+
"rows" => [
|
231
|
+
{ "key" => "awesome-article", "value" => 2 },
|
232
|
+
{ "key" => "fun-article", "value" => 1 }
|
233
|
+
]
|
234
|
+
}
|
235
|
+
"""
|
236
|
+
|
237
|
+
|
238
|
+
@db
|
239
|
+
Scenario: You can't call ".each" on a count proxy unless the CouchDB "group" option is set to true
|
240
|
+
|
241
|
+
Given the following map definition:
|
242
|
+
"""
|
243
|
+
class ByLabel
|
244
|
+
include CouchView::Map
|
245
|
+
|
246
|
+
def map
|
247
|
+
"
|
248
|
+
function(doc){
|
249
|
+
if (#{conditions})
|
250
|
+
emit(doc.label, null)
|
251
|
+
}
|
252
|
+
"
|
253
|
+
end
|
254
|
+
end
|
255
|
+
"""
|
256
|
+
|
257
|
+
And an Article model that maps ByLabel:
|
258
|
+
"""
|
259
|
+
class Article < CouchRest::Model::Base
|
260
|
+
include CouchView
|
261
|
+
map ByLabel
|
262
|
+
end
|
263
|
+
"""
|
264
|
+
|
265
|
+
When I instantiate a new CouchView::Map::Proxy with "Article" and ":by_label":
|
266
|
+
"""
|
267
|
+
@proxy = CouchView::Count::Proxy.new Article, :by_by_label
|
268
|
+
"""
|
269
|
+
|
270
|
+
Then ".each" should raise an exception:
|
271
|
+
"""
|
272
|
+
proc { @proxy.each {|k,v|} }.should raise_exception("You can't call 'each' on a count proxy that doesn't set 'group' to 'true'.")
|
273
|
+
"""
|
274
|
+
|
275
|
+
When I set the CouchDB "group" query option to "true":
|
276
|
+
"""
|
277
|
+
@proxy.group!(true)
|
278
|
+
"""
|
279
|
+
|
280
|
+
Then ".each" should not raise an exception:
|
281
|
+
"""
|
282
|
+
proc { @proxy.each {|k,v|} }.should_not raise_exception
|
283
|
+
"""
|
284
|
+
|