couchrest_model 1.1.0.beta2 → 1.1.0.beta3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/README.md +50 -3
- data/VERSION +1 -1
- data/benchmarks/dirty.rb +118 -0
- data/couchrest_model.gemspec +1 -0
- data/history.txt +12 -0
- data/lib/couchrest/model/base.rb +15 -23
- data/lib/couchrest/model/casted_array.rb +26 -1
- data/lib/couchrest/model/casted_by.rb +23 -0
- data/lib/couchrest/model/casted_hash.rb +76 -0
- data/lib/couchrest/model/casted_model.rb +9 -6
- data/lib/couchrest/model/collection.rb +10 -1
- data/lib/couchrest/model/configuration.rb +4 -4
- data/lib/couchrest/model/design_doc.rb +65 -71
- data/lib/couchrest/model/designs/view.rb +26 -19
- data/lib/couchrest/model/designs.rb +0 -2
- data/lib/couchrest/model/dirty.rb +49 -0
- data/lib/couchrest/model/extended_attachments.rb +7 -1
- data/lib/couchrest/model/persistence.rb +15 -4
- data/lib/couchrest/model/properties.rb +50 -9
- data/lib/couchrest/model/property.rb +6 -2
- data/lib/couchrest/model/proxyable.rb +13 -19
- data/lib/couchrest/model/support/couchrest_design.rb +33 -0
- data/lib/couchrest/model/views.rb +4 -18
- data/lib/couchrest_model.rb +8 -3
- data/spec/couchrest/base_spec.rb +1 -28
- data/spec/couchrest/casted_model_spec.rb +1 -1
- data/spec/couchrest/collection_spec.rb +0 -1
- data/spec/couchrest/design_doc_spec.rb +211 -0
- data/spec/couchrest/designs/view_spec.rb +41 -17
- data/spec/couchrest/designs_spec.rb +0 -5
- data/spec/couchrest/dirty_spec.rb +355 -0
- data/spec/couchrest/property_spec.rb +5 -2
- data/spec/couchrest/proxyable_spec.rb +0 -11
- data/spec/couchrest/subclass_spec.rb +6 -16
- data/spec/couchrest/view_spec.rb +6 -50
- data/spec/fixtures/base.rb +1 -1
- data/spec/fixtures/more/card.rb +2 -2
- data/spec/spec_helper.rb +2 -0
- metadata +9 -4
- data/Gemfile.lock +0 -76
- data/lib/couchrest/model/support/couchrest.rb +0 -19
@@ -2,7 +2,7 @@ module CouchRest
|
|
2
2
|
module Model
|
3
3
|
module Views
|
4
4
|
extend ActiveSupport::Concern
|
5
|
-
|
5
|
+
|
6
6
|
module ClassMethods
|
7
7
|
# Define a CouchDB view. The name of the view will be the concatenation
|
8
8
|
# of <tt>by</tt> and the keys joined by <tt>_and_</tt>
|
@@ -81,7 +81,6 @@ module CouchRest
|
|
81
81
|
end
|
82
82
|
keys.push opts
|
83
83
|
design_doc.view_by(*keys)
|
84
|
-
req_design_doc_refresh
|
85
84
|
end
|
86
85
|
|
87
86
|
# returns stored defaults if there is a view named this in the design doc
|
@@ -99,9 +98,9 @@ module CouchRest
|
|
99
98
|
def view(name, query={}, &block)
|
100
99
|
query = query.dup # Modifications made on copy!
|
101
100
|
db = query.delete(:database) || database
|
102
|
-
refresh_design_doc(db)
|
103
101
|
query[:raw] = true if query[:reduce]
|
104
102
|
raw = query.delete(:raw)
|
103
|
+
save_design_doc(db)
|
105
104
|
fetch_view_with_docs(db, name, query, raw, &block)
|
106
105
|
end
|
107
106
|
|
@@ -140,23 +139,10 @@ module CouchRest
|
|
140
139
|
|
141
140
|
def fetch_view(db, view_name, opts, &block)
|
142
141
|
raise "A view needs a database to operate on (specify :database option, or use_database in the #{self.class} class)" unless db
|
143
|
-
|
144
|
-
begin
|
145
|
-
design_doc.view_on(db, view_name, opts, &block)
|
146
|
-
# the design doc may not have been saved yet on this database
|
147
|
-
rescue RestClient::ResourceNotFound => e
|
148
|
-
if retryable
|
149
|
-
save_design_doc(db)
|
150
|
-
retryable = false
|
151
|
-
retry
|
152
|
-
else
|
153
|
-
raise e
|
154
|
-
end
|
155
|
-
end
|
142
|
+
design_doc.view_on(db, view_name, opts, &block)
|
156
143
|
end
|
157
|
-
|
158
144
|
end # module ClassMethods
|
159
|
-
|
145
|
+
|
160
146
|
end
|
161
147
|
end
|
162
148
|
end
|
data/lib/couchrest_model.rb
CHANGED
@@ -8,6 +8,7 @@ require "active_model/serialization"
|
|
8
8
|
require "active_model/translation"
|
9
9
|
require "active_model/validator"
|
10
10
|
require "active_model/validations"
|
11
|
+
require "active_model/dirty"
|
11
12
|
|
12
13
|
require 'active_support/core_ext'
|
13
14
|
require 'active_support/json'
|
@@ -26,10 +27,14 @@ require 'couchrest/model'
|
|
26
27
|
require 'couchrest/model/errors'
|
27
28
|
require "couchrest/model/persistence"
|
28
29
|
require "couchrest/model/typecast"
|
30
|
+
require "couchrest/model/casted_by"
|
31
|
+
require "couchrest/model/dirty"
|
29
32
|
require "couchrest/model/property"
|
30
33
|
require "couchrest/model/property_protection"
|
31
|
-
require "couchrest/model/casted_array"
|
32
34
|
require "couchrest/model/properties"
|
35
|
+
require "couchrest/model/casted_array"
|
36
|
+
require "couchrest/model/casted_hash"
|
37
|
+
require "couchrest/model/casted_model"
|
33
38
|
require "couchrest/model/validations"
|
34
39
|
require "couchrest/model/callbacks"
|
35
40
|
require "couchrest/model/document_queries"
|
@@ -45,7 +50,8 @@ require "couchrest/model/designs"
|
|
45
50
|
require "couchrest/model/designs/view"
|
46
51
|
|
47
52
|
# Monkey patches applied to couchrest
|
48
|
-
require "couchrest/model/support/
|
53
|
+
require "couchrest/model/support/couchrest_design"
|
54
|
+
|
49
55
|
# Core Extensions
|
50
56
|
require "couchrest/model/core_extensions/hash"
|
51
57
|
require "couchrest/model/core_extensions/time_parsing"
|
@@ -53,7 +59,6 @@ require "couchrest/model/core_extensions/time_parsing"
|
|
53
59
|
# Base libraries
|
54
60
|
require "couchrest/model/casted_model"
|
55
61
|
require "couchrest/model/base"
|
56
|
-
|
57
62
|
# Add rails support *after* everything has loaded
|
58
63
|
|
59
64
|
require "couchrest/railtie"
|
data/spec/couchrest/base_spec.rb
CHANGED
@@ -246,7 +246,6 @@ describe "Model Base" do
|
|
246
246
|
|
247
247
|
describe "finding all instances of a model" do
|
248
248
|
before(:all) do
|
249
|
-
WithTemplateAndUniqueID.req_design_doc_refresh
|
250
249
|
WithTemplateAndUniqueID.all.map{|o| o.destroy}
|
251
250
|
WithTemplateAndUniqueID.database.bulk_delete
|
252
251
|
WithTemplateAndUniqueID.new('important-field' => '1').save
|
@@ -254,11 +253,6 @@ describe "Model Base" do
|
|
254
253
|
WithTemplateAndUniqueID.new('important-field' => '3').save
|
255
254
|
WithTemplateAndUniqueID.new('important-field' => '4').save
|
256
255
|
end
|
257
|
-
it "should make the design doc" do
|
258
|
-
WithTemplateAndUniqueID.all
|
259
|
-
d = WithTemplateAndUniqueID.design_doc
|
260
|
-
d['views']['all']['map'].should include('WithTemplateAndUniqueID')
|
261
|
-
end
|
262
256
|
it "should find all" do
|
263
257
|
rs = WithTemplateAndUniqueID.all
|
264
258
|
rs.length.should == 4
|
@@ -268,7 +262,6 @@ describe "Model Base" do
|
|
268
262
|
describe "counting all instances of a model" do
|
269
263
|
before(:each) do
|
270
264
|
@db = reset_test_db!
|
271
|
-
WithTemplateAndUniqueID.req_design_doc_refresh
|
272
265
|
end
|
273
266
|
|
274
267
|
it ".count should return 0 if there are no docuemtns" do
|
@@ -287,17 +280,11 @@ describe "Model Base" do
|
|
287
280
|
describe "finding the first instance of a model" do
|
288
281
|
before(:each) do
|
289
282
|
@db = reset_test_db!
|
290
|
-
# WithTemplateAndUniqueID.req_design_doc_refresh # Removed by Sam Lown, design doc should be loaded automatically
|
291
283
|
WithTemplateAndUniqueID.new('important-field' => '1').save
|
292
284
|
WithTemplateAndUniqueID.new('important-field' => '2').save
|
293
285
|
WithTemplateAndUniqueID.new('important-field' => '3').save
|
294
286
|
WithTemplateAndUniqueID.new('important-field' => '4').save
|
295
287
|
end
|
296
|
-
it "should make the design doc" do
|
297
|
-
WithTemplateAndUniqueID.all
|
298
|
-
d = WithTemplateAndUniqueID.design_doc
|
299
|
-
d['views']['all']['map'].should include('WithTemplateAndUniqueID')
|
300
|
-
end
|
301
288
|
it "should find first" do
|
302
289
|
rs = WithTemplateAndUniqueID.first
|
303
290
|
rs['important-field'].should == "1"
|
@@ -308,21 +295,6 @@ describe "Model Base" do
|
|
308
295
|
end
|
309
296
|
end
|
310
297
|
|
311
|
-
describe "lazily refreshing the design document" do
|
312
|
-
before(:all) do
|
313
|
-
@db = reset_test_db!
|
314
|
-
WithTemplateAndUniqueID.new('important-field' => '1').save
|
315
|
-
end
|
316
|
-
it "should not save the design doc twice" do
|
317
|
-
WithTemplateAndUniqueID.all
|
318
|
-
WithTemplateAndUniqueID.req_design_doc_refresh
|
319
|
-
WithTemplateAndUniqueID.refresh_design_doc
|
320
|
-
rev = WithTemplateAndUniqueID.design_doc['_rev']
|
321
|
-
WithTemplateAndUniqueID.req_design_doc_refresh
|
322
|
-
WithTemplateAndUniqueID.refresh_design_doc
|
323
|
-
WithTemplateAndUniqueID.design_doc['_rev'].should eql(rev)
|
324
|
-
end
|
325
|
-
end
|
326
298
|
|
327
299
|
describe "getting a model with a subobject field" do
|
328
300
|
before(:all) do
|
@@ -378,6 +350,7 @@ describe "Model Base" do
|
|
378
350
|
foundart.created_at.should == foundart.updated_at
|
379
351
|
end
|
380
352
|
it "should set the time on update" do
|
353
|
+
@art.title = "new title" # only saved if @art.changed? == true
|
381
354
|
@art.save
|
382
355
|
@art.created_at.should < @art.updated_at
|
383
356
|
end
|
@@ -0,0 +1,211 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path("../../spec_helper", __FILE__)
|
4
|
+
require File.join(FIXTURE_PATH, 'base')
|
5
|
+
require File.join(FIXTURE_PATH, 'more', 'article')
|
6
|
+
|
7
|
+
describe "Design Documents" do
|
8
|
+
|
9
|
+
before :all do
|
10
|
+
reset_test_db!
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "CouchRest Extension" do
|
14
|
+
|
15
|
+
it "should have created a checksum! method" do
|
16
|
+
::CouchRest::Design.new.should respond_to(:checksum!)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should calculate a consistent checksum for model" do
|
20
|
+
WithTemplateAndUniqueID.design_doc.checksum!.should eql('ff6fa2eaf774397391942d51428c1fe2')
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should calculate checksum for complex model" do
|
24
|
+
Article.design_doc.checksum!.should eql('fb65c06a76b6141529e31e894ad00b1a')
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should cache the generated checksum value" do
|
28
|
+
Article.design_doc.checksum!
|
29
|
+
Article.design_doc['couchrest-hash'].should_not be_blank
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "class methods" do
|
34
|
+
|
35
|
+
describe ".design_doc" do
|
36
|
+
it "should provide Design document" do
|
37
|
+
Article.design_doc.should be_a(::CouchRest::Design)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe ".design_doc_id" do
|
42
|
+
it "should provide a reasonable id" do
|
43
|
+
Article.design_doc_id.should eql("_design/Article")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe ".design_doc_slug" do
|
48
|
+
it "should provide slug part of design doc" do
|
49
|
+
Article.design_doc_slug.should eql('Article')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe ".design_doc_uri" do
|
54
|
+
it "should provide complete url" do
|
55
|
+
Article.design_doc_uri.should eql("#{COUCHHOST}/#{TESTDB}/_design/Article")
|
56
|
+
end
|
57
|
+
it "should provide complete url for new DB" do
|
58
|
+
db = mock("Database")
|
59
|
+
db.should_receive(:root).and_return('db')
|
60
|
+
Article.design_doc_uri(db).should eql("db/_design/Article")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe ".stored_design_doc" do
|
65
|
+
it "should load a stored design from the database" do
|
66
|
+
Article.by_date
|
67
|
+
Article.stored_design_doc['_rev'].should_not be_blank
|
68
|
+
end
|
69
|
+
it "should return nil if not already stored" do
|
70
|
+
WithDefaultValues.stored_design_doc.should be_nil
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe ".save_design_doc" do
|
75
|
+
it "should call up the design updater" do
|
76
|
+
Article.should_receive(:update_design_doc).with('db', false)
|
77
|
+
Article.save_design_doc('db')
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe ".save_design_doc!" do
|
82
|
+
it "should call save_design_doc with force" do
|
83
|
+
Article.should_receive(:save_design_doc).with('db', true)
|
84
|
+
Article.save_design_doc!('db')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "basics" do
|
91
|
+
|
92
|
+
before :all do
|
93
|
+
reset_test_db!
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should have been instantiated with views" do
|
97
|
+
d = Article.design_doc
|
98
|
+
d['views']['all']['map'].should include('Article')
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should not have been saved yet" do
|
102
|
+
lambda { Article.database.get(Article.design_doc.id) }.should raise_error(RestClient::ResourceNotFound)
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "after requesting a view" do
|
106
|
+
before :each do
|
107
|
+
Article.all
|
108
|
+
end
|
109
|
+
it "should have saved the design doc after view request" do
|
110
|
+
Article.database.get(Article.design_doc.id).should_not be_nil
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "model with simple views" do
|
115
|
+
before(:all) do
|
116
|
+
Article.all.map{|a| a.destroy(true)}
|
117
|
+
Article.database.bulk_delete
|
118
|
+
written_at = Time.now - 24 * 3600 * 7
|
119
|
+
@titles = ["this and that", "also interesting", "more fun", "some junk"]
|
120
|
+
@titles.each do |title|
|
121
|
+
a = Article.new(:title => title)
|
122
|
+
a.date = written_at
|
123
|
+
a.save
|
124
|
+
written_at += 24 * 3600
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
it "will send request for the saved design doc on view request" do
|
129
|
+
reset_test_db!
|
130
|
+
Article.should_receive(:stored_design_doc).and_return(nil)
|
131
|
+
Article.by_date
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should have generated a design doc" do
|
135
|
+
Article.design_doc["views"]["by_date"].should_not be_nil
|
136
|
+
end
|
137
|
+
it "should save the design doc when view requested" do
|
138
|
+
Article.by_date
|
139
|
+
doc = Article.database.get Article.design_doc.id
|
140
|
+
doc['views']['by_date'].should_not be_nil
|
141
|
+
end
|
142
|
+
it "should save design doc if a view changed" do
|
143
|
+
Article.by_date
|
144
|
+
orig = Article.stored_design_doc
|
145
|
+
design = Article.design_doc
|
146
|
+
view = design['views']['by_date']['map']
|
147
|
+
design['views']['by_date']['map'] = view + ' ' # little bit of white space
|
148
|
+
Article.by_date
|
149
|
+
Article.stored_design_doc['_rev'].should_not eql(orig['_rev'])
|
150
|
+
orig['views']['by_date']['map'].should_not eql(Article.design_doc['views']['by_date']['map'])
|
151
|
+
end
|
152
|
+
it "should not save design doc if not changed" do
|
153
|
+
Article.by_date
|
154
|
+
orig = Article.stored_design_doc['_rev']
|
155
|
+
Article.by_date
|
156
|
+
Article.stored_design_doc['_rev'].should eql(orig)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe "when auto_update_design_doc false" do
|
161
|
+
|
162
|
+
before :all do
|
163
|
+
Article.auto_update_design_doc = false
|
164
|
+
Article.save_design_doc!
|
165
|
+
end
|
166
|
+
|
167
|
+
after :all do
|
168
|
+
Article.auto_update_design_doc = true
|
169
|
+
end
|
170
|
+
|
171
|
+
it "will not send a request for the saved design doc" do
|
172
|
+
Article.should_not_receive(:stored_design_doc)
|
173
|
+
Article.by_date
|
174
|
+
end
|
175
|
+
|
176
|
+
it "will not update stored design doc if view changed" do
|
177
|
+
Article.by_date
|
178
|
+
orig = Article.stored_design_doc
|
179
|
+
design = Article.design_doc
|
180
|
+
view = design['views']['by_date']['map']
|
181
|
+
design['views']['by_date']['map'] = view + ' '
|
182
|
+
Article.by_date
|
183
|
+
Article.stored_design_doc['_rev'].should eql(orig['_rev'])
|
184
|
+
end
|
185
|
+
|
186
|
+
it "will update stored design if forced" do
|
187
|
+
Article.by_date
|
188
|
+
orig = Article.stored_design_doc
|
189
|
+
design = Article.design_doc
|
190
|
+
view = design['views']['by_date']['map']
|
191
|
+
design['views']['by_date']['map'] = view + ' '
|
192
|
+
Article.save_design_doc!
|
193
|
+
Article.stored_design_doc['_rev'].should_not eql(orig['_rev'])
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe "lazily refreshing the design document" do
|
199
|
+
before(:all) do
|
200
|
+
@db = reset_test_db!
|
201
|
+
WithTemplateAndUniqueID.new('important-field' => '1').save
|
202
|
+
end
|
203
|
+
it "should not save the design doc twice" do
|
204
|
+
WithTemplateAndUniqueID.all
|
205
|
+
rev = WithTemplateAndUniqueID.design_doc['_rev']
|
206
|
+
WithTemplateAndUniqueID.design_doc['_rev'].should eql(rev)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
|
211
|
+
end
|
@@ -74,7 +74,7 @@ describe "Design View" do
|
|
74
74
|
it "should auto generate mapping from name" do
|
75
75
|
lambda { @klass.create(DesignViewModel, 'by_title') }.should_not raise_error
|
76
76
|
str = @design_doc['views']['by_title']['map']
|
77
|
-
str.should include("((doc['
|
77
|
+
str.should include("((doc['model'] == 'DesignViewModel') && (doc['title'] != null))")
|
78
78
|
str.should include("emit(doc['title'], 1);")
|
79
79
|
str = @design_doc['views']['by_title']['reduce']
|
80
80
|
str.should include("return sum(values);")
|
@@ -163,10 +163,17 @@ describe "Design View" do
|
|
163
163
|
end
|
164
164
|
end
|
165
165
|
|
166
|
+
describe "#length" do
|
167
|
+
it "should provide a length from the docs array" do
|
168
|
+
@obj.should_receive(:docs).and_return([1, 2, 3])
|
169
|
+
@obj.length.should eql(3)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
166
173
|
describe "#count" do
|
167
174
|
it "should raise an error if view prepared for group" do
|
168
175
|
@obj.should_receive(:query).and_return({:group => true})
|
169
|
-
lambda { @obj.count }.should raise_error
|
176
|
+
lambda { @obj.count }.should raise_error(/group/)
|
170
177
|
end
|
171
178
|
|
172
179
|
it "should return first row value if reduce possible" do
|
@@ -174,6 +181,8 @@ describe "Design View" do
|
|
174
181
|
row = mock("Row")
|
175
182
|
@obj.should_receive(:can_reduce?).and_return(true)
|
176
183
|
@obj.should_receive(:reduce).and_return(view)
|
184
|
+
view.should_receive(:skip).with(0).and_return(view)
|
185
|
+
view.should_receive(:limit).with(1).and_return(view)
|
177
186
|
view.should_receive(:rows).and_return([row])
|
178
187
|
row.should_receive(:value).and_return(2)
|
179
188
|
@obj.count.should eql(2)
|
@@ -182,6 +191,8 @@ describe "Design View" do
|
|
182
191
|
view = mock("SubView")
|
183
192
|
@obj.should_receive(:can_reduce?).and_return(true)
|
184
193
|
@obj.should_receive(:reduce).and_return(view)
|
194
|
+
view.should_receive(:skip).with(0).and_return(view)
|
195
|
+
view.should_receive(:limit).with(1).and_return(view)
|
185
196
|
view.should_receive(:rows).and_return([])
|
186
197
|
@obj.count.should eql(0)
|
187
198
|
end
|
@@ -375,6 +386,24 @@ describe "Design View" do
|
|
375
386
|
@obj.should_receive(:update_query).with({:descending => true})
|
376
387
|
@obj.descending
|
377
388
|
end
|
389
|
+
it "should reverse start and end keys if given" do
|
390
|
+
@obj = @obj.startkey('a').endkey('z')
|
391
|
+
@obj = @obj.descending
|
392
|
+
@obj.query[:endkey].should eql('a')
|
393
|
+
@obj.query[:startkey].should eql('z')
|
394
|
+
end
|
395
|
+
it "should reverse even if start or end nil" do
|
396
|
+
@obj = @obj.startkey('a')
|
397
|
+
@obj = @obj.descending
|
398
|
+
@obj.query[:endkey].should eql('a')
|
399
|
+
@obj.query[:startkey].should be_nil
|
400
|
+
end
|
401
|
+
it "should reverse start_doc and end_doc keys if given" do
|
402
|
+
@obj = @obj.startkey_doc('a').endkey_doc('z')
|
403
|
+
@obj = @obj.descending
|
404
|
+
@obj.query[:endkey_docid].should eql('a')
|
405
|
+
@obj.query[:startkey_docid].should eql('z')
|
406
|
+
end
|
378
407
|
end
|
379
408
|
|
380
409
|
describe "#limit" do
|
@@ -528,6 +557,7 @@ describe "Design View" do
|
|
528
557
|
# disable real execution!
|
529
558
|
@design_doc = mock("DesignDoc")
|
530
559
|
@design_doc.stub!(:view_on)
|
560
|
+
@obj.model.stub!(:save_design_doc)
|
531
561
|
@obj.model.stub!(:design_doc).and_return(@design_doc)
|
532
562
|
end
|
533
563
|
|
@@ -550,29 +580,19 @@ describe "Design View" do
|
|
550
580
|
@obj.send(:execute)
|
551
581
|
end
|
552
582
|
|
553
|
-
it "should
|
554
|
-
@obj.should_receive(:can_reduce?).and_return(
|
555
|
-
@
|
583
|
+
it "should call to save the design document" do
|
584
|
+
@obj.should_receive(:can_reduce?).and_return(false)
|
585
|
+
@obj.model.should_receive(:save_design_doc).with(DB)
|
556
586
|
@obj.send(:execute)
|
557
|
-
@obj.result.should eql('foos')
|
558
587
|
end
|
559
588
|
|
560
|
-
it "should
|
589
|
+
it "should populate the results" do
|
561
590
|
@obj.should_receive(:can_reduce?).and_return(true)
|
562
|
-
@
|
563
|
-
@design_doc.should_receive(:view_on).ordered.and_raise(RestClient::ResourceNotFound)
|
564
|
-
@design_doc.should_receive(:view_on).ordered.and_return('foos')
|
591
|
+
@design_doc.should_receive(:view_on).and_return('foos')
|
565
592
|
@obj.send(:execute)
|
566
593
|
@obj.result.should eql('foos')
|
567
594
|
end
|
568
595
|
|
569
|
-
it "should retry twice and fail on a resource not found error" do
|
570
|
-
@obj.should_receive(:can_reduce?).and_return(true)
|
571
|
-
@obj.model.should_receive(:save_design_doc)
|
572
|
-
@design_doc.should_receive(:view_on).twice.and_raise(RestClient::ResourceNotFound)
|
573
|
-
lambda { @obj.send(:execute) }.should raise_error(RestClient::ResourceNotFound)
|
574
|
-
end
|
575
|
-
|
576
596
|
it "should remove nil values from query" do
|
577
597
|
@obj.should_receive(:can_reduce?).and_return(true)
|
578
598
|
@obj.stub!(:use_database).and_return('database')
|
@@ -772,6 +792,10 @@ describe "Design View" do
|
|
772
792
|
docs[0].name.should eql("Judith")
|
773
793
|
docs[1].name.should eql("Peter")
|
774
794
|
end
|
795
|
+
it "should provide count even if limit or skip set" do
|
796
|
+
docs = DesignViewModel.by_name.limit(20).skip(2)
|
797
|
+
docs.count.should eql(5)
|
798
|
+
end
|
775
799
|
end
|
776
800
|
|
777
801
|
describe "pagination" do
|
@@ -31,11 +31,6 @@ describe "Design" do
|
|
31
31
|
DesignModel.design { foo }
|
32
32
|
end
|
33
33
|
|
34
|
-
it "should request a design refresh" do
|
35
|
-
DesignModel.should_receive(:req_design_doc_refresh)
|
36
|
-
DesignModel.design() { }
|
37
|
-
end
|
38
|
-
|
39
34
|
it "should work even if a block is not provided" do
|
40
35
|
lambda { DesignModel.design }.should_not raise_error
|
41
36
|
end
|