couchrest_model 1.1.0.beta2 → 1.1.0.beta3
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/.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
|