dolly 1.1.4 → 3.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.
- checksums.yaml +5 -5
- data/README.md +78 -0
- data/lib/dolly.rb +4 -2
- data/lib/dolly/attachment.rb +29 -0
- data/lib/dolly/bulk_document.rb +27 -26
- data/lib/dolly/class_methods_delegation.rb +15 -0
- data/lib/dolly/collection.rb +32 -65
- data/lib/dolly/configuration.rb +43 -0
- data/lib/dolly/connection.rb +101 -22
- data/lib/dolly/depracated_database.rb +24 -0
- data/lib/dolly/document.rb +48 -198
- data/lib/dolly/document_creation.rb +20 -0
- data/lib/dolly/document_state.rb +66 -0
- data/lib/dolly/document_type.rb +47 -0
- data/lib/dolly/exceptions.rb +32 -0
- data/lib/dolly/identity_properties.rb +29 -0
- data/lib/dolly/mango.rb +124 -0
- data/lib/dolly/mango_index.rb +65 -0
- data/lib/dolly/properties.rb +36 -0
- data/lib/dolly/property.rb +58 -47
- data/lib/dolly/property_manager.rb +47 -0
- data/lib/dolly/property_set.rb +23 -0
- data/lib/dolly/query.rb +37 -67
- data/lib/dolly/query_arguments.rb +35 -0
- data/lib/dolly/request.rb +12 -94
- data/lib/dolly/request_header.rb +26 -0
- data/lib/dolly/timestamp.rb +24 -0
- data/lib/dolly/version.rb +1 -1
- data/lib/dolly/view_query.rb +14 -0
- data/lib/{dolly → railties}/railtie.rb +2 -1
- data/lib/refinements/hash_refinements.rb +27 -0
- data/lib/refinements/string_refinements.rb +28 -0
- data/lib/tasks/db.rake +20 -4
- data/test/bulk_document_test.rb +8 -5
- data/test/document_test.rb +132 -95
- data/test/document_type_test.rb +28 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/log/test.log +111132 -0
- data/test/inheritance_test.rb +23 -0
- data/test/mango_index_test.rb +64 -0
- data/test/mango_test.rb +273 -0
- data/test/test_helper.rb +63 -18
- data/test/view_query_test.rb +27 -0
- metadata +57 -141
- data/Rakefile +0 -11
- data/lib/dolly/bulk_error.rb +0 -16
- data/lib/dolly/db_config.rb +0 -20
- data/lib/dolly/interpreter.rb +0 -5
- data/lib/dolly/name_space.rb +0 -28
- data/lib/dolly/timestamps.rb +0 -21
- data/lib/exceptions/dolly.rb +0 -38
- data/test/collection_test.rb +0 -59
- data/test/dummy/README.rdoc +0 -28
- data/test/dummy/Rakefile +0 -6
- data/test/dummy/app/assets/javascripts/application.js +0 -13
- data/test/dummy/app/assets/stylesheets/application.css +0 -13
- data/test/dummy/app/controllers/application_controller.rb +0 -5
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/views/layouts/application.html.erb +0 -14
- data/test/dummy/bin/bundle +0 -3
- data/test/dummy/bin/rails +0 -4
- data/test/dummy/bin/rake +0 -4
- data/test/dummy/config.ru +0 -4
- data/test/dummy/config/application.rb +0 -27
- data/test/dummy/config/boot.rb +0 -5
- data/test/dummy/config/couchdb.yml +0 -13
- data/test/dummy/config/environment.rb +0 -5
- data/test/dummy/config/environments/development.rb +0 -29
- data/test/dummy/config/environments/production.rb +0 -80
- data/test/dummy/config/environments/test.rb +0 -36
- data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/test/dummy/config/initializers/inflections.rb +0 -16
- data/test/dummy/config/initializers/mime_types.rb +0 -5
- data/test/dummy/config/initializers/secret_token.rb +0 -12
- data/test/dummy/config/initializers/session_store.rb +0 -3
- data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/test/dummy/config/locales/en.yml +0 -23
- data/test/dummy/config/routes.rb +0 -56
- data/test/dummy/lib/couch_rest_adapter/railtie.rb +0 -10
- data/test/dummy/public/404.html +0 -58
- data/test/dummy/public/422.html +0 -58
- data/test/dummy/public/500.html +0 -57
- data/test/dummy/public/favicon.ico +0 -0
- data/test/factories/factories.rb +0 -8
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class BaseDoc < Dolly::Document
|
4
|
+
typed_model
|
5
|
+
end
|
6
|
+
|
7
|
+
class BaseBaseDoc < BaseDoc
|
8
|
+
property :supertype
|
9
|
+
end
|
10
|
+
|
11
|
+
class NewBar < BaseBaseDoc
|
12
|
+
property :a, :b
|
13
|
+
end
|
14
|
+
|
15
|
+
class InheritanceTest < Test::Unit::TestCase
|
16
|
+
test 'property inheritance' do
|
17
|
+
assert_equal(BaseBaseDoc.new.properties.map(&:key), [:supertype, :type])
|
18
|
+
end
|
19
|
+
|
20
|
+
test 'deep properties inheritance' do
|
21
|
+
assert_equal(NewBar.new.properties.map(&:key), [:a, :b, :supertype, :type])
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class FooBar < BaseDolly
|
4
|
+
property :foo, :bar
|
5
|
+
property :with_default, default: 1
|
6
|
+
property :boolean, class_name: TrueClass, default: true
|
7
|
+
property :date, class_name: Date
|
8
|
+
property :time, class_name: Time
|
9
|
+
property :datetime, class_name: DateTime
|
10
|
+
property :is_nil, class_name: NilClass, default: nil
|
11
|
+
|
12
|
+
timestamps!
|
13
|
+
end
|
14
|
+
|
15
|
+
class MangoIndexTest < Test::Unit::TestCase
|
16
|
+
DB_BASE_PATH = "http://localhost:5984/test".freeze
|
17
|
+
|
18
|
+
def setup
|
19
|
+
stub_request(:get, index_base_path).
|
20
|
+
to_return(body: { indexes:[ {
|
21
|
+
ddoc: nil,
|
22
|
+
name:"_all_docs",
|
23
|
+
type:"special",
|
24
|
+
def:{ fields:[{ _id:"asc" }] }
|
25
|
+
},
|
26
|
+
{
|
27
|
+
ddoc: "_design/1",
|
28
|
+
name:"foo-index-json",
|
29
|
+
type:"json",
|
30
|
+
def:{ fields:[{ foo:"asc" }] }
|
31
|
+
}
|
32
|
+
]}.to_json)
|
33
|
+
end
|
34
|
+
|
35
|
+
test '#delete_all' do
|
36
|
+
previous_indexes = Dolly::MangoIndex.all
|
37
|
+
|
38
|
+
stub_request(:delete, index_delete_path(previous_indexes.last)).
|
39
|
+
to_return(body: { "ok": true }.to_json)
|
40
|
+
|
41
|
+
Dolly::MangoIndex.delete_all
|
42
|
+
|
43
|
+
stub_request(:get, index_base_path).
|
44
|
+
to_return(body: { indexes:[ {
|
45
|
+
ddoc: nil,
|
46
|
+
name:"_all_docs",
|
47
|
+
type:"special",
|
48
|
+
def:{ fields:[{ _id:"asc" }] }
|
49
|
+
}
|
50
|
+
]}.to_json)
|
51
|
+
|
52
|
+
new_indexes = Dolly::MangoIndex.all
|
53
|
+
assert_not_equal(new_indexes.length, previous_indexes.length)
|
54
|
+
assert_equal(new_indexes.length, 1)
|
55
|
+
end
|
56
|
+
|
57
|
+
def index_base_path
|
58
|
+
"#{DB_BASE_PATH}/_index"
|
59
|
+
end
|
60
|
+
|
61
|
+
def index_delete_path(doc)
|
62
|
+
"#{index_base_path}/#{doc[:ddoc]}/json/#{doc[:name]}"
|
63
|
+
end
|
64
|
+
end
|
data/test/mango_test.rb
ADDED
@@ -0,0 +1,273 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class FooBar < BaseDolly
|
4
|
+
property :foo, :bar
|
5
|
+
property :with_default, default: 1
|
6
|
+
property :boolean, class_name: TrueClass, default: true
|
7
|
+
property :date, class_name: Date
|
8
|
+
property :time, class_name: Time
|
9
|
+
property :datetime, class_name: DateTime
|
10
|
+
property :is_nil, class_name: NilClass, default: nil
|
11
|
+
|
12
|
+
timestamps!
|
13
|
+
end
|
14
|
+
|
15
|
+
class FooBarTyped < BaseDolly
|
16
|
+
typed_model
|
17
|
+
end
|
18
|
+
|
19
|
+
class MangoTest < Test::Unit::TestCase
|
20
|
+
DB_BASE_PATH = "http://localhost:5984/test".freeze
|
21
|
+
|
22
|
+
def setup
|
23
|
+
data = {foo: 'Foo', bar: 'Bar', type: 'foo_bar'}
|
24
|
+
|
25
|
+
all_docs = [ {foo: 'Foo B', bar: 'Bar B', type: 'foo_bar'}, {foo: 'Foo A', bar: 'Bar A', type: 'foo_bar'}]
|
26
|
+
|
27
|
+
view_resp = build_view_response [data]
|
28
|
+
empty_resp = build_view_response []
|
29
|
+
not_found_resp = generic_response [{ key: "foo_bar/2", error: "not_found" }]
|
30
|
+
@multi_resp = build_view_response all_docs
|
31
|
+
@multi_type_resp = build_view_collation_response all_docs
|
32
|
+
|
33
|
+
build_request [["foo_bar","1"]], view_resp
|
34
|
+
build_request [["foo_bar","2"]], empty_resp
|
35
|
+
build_request [["foo_bar","1"],["foo_bar","2"]], @multi_resp
|
36
|
+
|
37
|
+
stub_request(:get, "#{query_base_path}?startkey=%22foo_bar%2F%22&endkey=%22foo_bar%2F%EF%BF%B0%22&include_docs=true").
|
38
|
+
to_return(body: @multi_resp.to_json)
|
39
|
+
|
40
|
+
stub_request(:get, "#{all_docs_path}?key=\"index_foo\"").
|
41
|
+
to_return(body: {
|
42
|
+
total_rows: 2,
|
43
|
+
offset: 0,
|
44
|
+
rows: [{
|
45
|
+
id: '_design/index_foo',
|
46
|
+
key: '_design/index_foo',
|
47
|
+
value: { rev: '1-c5457a0d26da85f15c4ad6bd739e441d' }
|
48
|
+
}]}.to_json)
|
49
|
+
|
50
|
+
stub_request(:get, "#{all_docs_path}?key=\"index_date\"").
|
51
|
+
to_return(body: {
|
52
|
+
total_rows: 2,
|
53
|
+
offset: 0,
|
54
|
+
rows: []}.to_json)
|
55
|
+
end
|
56
|
+
|
57
|
+
test '#find_by' do
|
58
|
+
#TODO: clean up all the fake request creation
|
59
|
+
resp = { docs: [{ foo: 'bar', id: "foo_bar/1"} ] }
|
60
|
+
|
61
|
+
stub_request(:post, query_base_path).
|
62
|
+
to_return(body: resp.to_json)
|
63
|
+
|
64
|
+
key = 'foo'
|
65
|
+
stub_request(:get, "#{all_docs_path}?key=\"_design/index_#{key}\"").
|
66
|
+
to_return(body: index_response(key).to_json)
|
67
|
+
|
68
|
+
assert_equal(FooBar.find_by(foo: 'bar').class, FooBar)
|
69
|
+
end
|
70
|
+
|
71
|
+
test '#find_by for a property that does not have an index' do
|
72
|
+
#TODO: clean up all the fake request creation
|
73
|
+
resp = { docs: [{ foo: 'bar', id: "foo_bar/1"} ] }
|
74
|
+
key = 'date'
|
75
|
+
|
76
|
+
stub_request(:post, query_base_path).
|
77
|
+
to_return(body: resp.to_json)
|
78
|
+
|
79
|
+
stub_request(:get, "#{all_docs_path}?key=\"_design/index_#{key}\"").
|
80
|
+
to_return(body: { rows: [] }.to_json)
|
81
|
+
|
82
|
+
assert_raise Dolly::IndexNotFoundError do
|
83
|
+
FooBar.find_by(date: Date.today)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
test '#find_by with no returned data' do
|
88
|
+
resp = { docs: [] }
|
89
|
+
|
90
|
+
stub_request(:post, query_base_path).
|
91
|
+
to_return(body: resp.to_json)
|
92
|
+
|
93
|
+
key = 'foo'
|
94
|
+
stub_request(:get, "#{all_docs_path}?key=\"_design/index_#{key}\"").
|
95
|
+
to_return(body: index_response(key).to_json)
|
96
|
+
|
97
|
+
assert_equal(FooBar.find_by(foo: 'bar'), nil)
|
98
|
+
end
|
99
|
+
|
100
|
+
test '#find_doc_by' do
|
101
|
+
#TODO: clean up all the fake request creation
|
102
|
+
resp = { docs: [{ foo: 'bar', id: "foo_bar/1"} ] }
|
103
|
+
|
104
|
+
stub_request(:post, query_base_path).
|
105
|
+
to_return(body: resp.to_json)
|
106
|
+
|
107
|
+
key = 'foo'
|
108
|
+
stub_request(:get, "#{all_docs_path}?key=\"_design/index_#{key}\"").
|
109
|
+
to_return(body: index_response(key).to_json)
|
110
|
+
|
111
|
+
assert_equal(FooBar.find_doc_by(foo: 'bar').class, Hash)
|
112
|
+
end
|
113
|
+
|
114
|
+
test '#where' do
|
115
|
+
#TODO: clean up all the fake request creation
|
116
|
+
resp = { docs: [{ foo: 'bar', id: "foo_bar/1"} ] }
|
117
|
+
|
118
|
+
stub_request(:post, query_base_path).
|
119
|
+
to_return(body: resp.to_json)
|
120
|
+
|
121
|
+
key = 'foo'
|
122
|
+
stub_request(:get, "#{all_docs_path}?key=\"_design/index_#{key}\"").
|
123
|
+
to_return(body: index_response(key).to_json)
|
124
|
+
|
125
|
+
assert_equal(FooBar.where(foo: { eq: 'bar' }).map(&:class).uniq, [FooBar])
|
126
|
+
end
|
127
|
+
|
128
|
+
test '#where for a property that does not have an index' do
|
129
|
+
#TODO: clean up all the fake request creation
|
130
|
+
resp = { docs: [{ foo: 'bar', id: "foo_bar/1"} ] }
|
131
|
+
|
132
|
+
stub_request(:post, query_base_path).
|
133
|
+
to_return(body: resp.to_json)
|
134
|
+
|
135
|
+
key = 'date'
|
136
|
+
stub_request(:get, "#{all_docs_path}?key=\"_design/index_#{key}\"").
|
137
|
+
to_return(body: { rows: [] }.to_json)
|
138
|
+
|
139
|
+
assert_raise Dolly::IndexNotFoundError do
|
140
|
+
FooBar.where(date: Date.today)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
test '#where with no returned data' do
|
145
|
+
resp = { docs: [] }
|
146
|
+
|
147
|
+
stub_request(:post, query_base_path).
|
148
|
+
to_return(body: resp.to_json)
|
149
|
+
|
150
|
+
key = 'foo'
|
151
|
+
stub_request(:get, "#{all_docs_path}?key=\"_design/index_#{key}\"").
|
152
|
+
to_return(body: index_response(key).to_json)
|
153
|
+
|
154
|
+
assert_equal(FooBar.where(foo: 'bar'), [])
|
155
|
+
end
|
156
|
+
|
157
|
+
test '#docs_where' do
|
158
|
+
#TODO: clean up all the fake request creation
|
159
|
+
resp = { docs: [{ foo: 'bar', id: "foo_bar/1"} ] }
|
160
|
+
|
161
|
+
stub_request(:post, query_base_path).
|
162
|
+
to_return(body: resp.to_json)
|
163
|
+
|
164
|
+
key = 'foo'
|
165
|
+
stub_request(:get, "#{all_docs_path}?key=\"_design/index_#{key}\"").
|
166
|
+
to_return(body: index_response(key).to_json)
|
167
|
+
|
168
|
+
assert_equal(FooBar.docs_where(foo: { eq: 'bar' }).map(&:class).uniq, [Hash])
|
169
|
+
end
|
170
|
+
|
171
|
+
test '#build_query' do
|
172
|
+
query = { and: [{ _id: { eq: 'foo_bar/1' } } , { foo: { eq: 'bar'}} ] }
|
173
|
+
opts = {}
|
174
|
+
expected = {"selector"=>{"$and"=>[{:_id=>{"$eq"=>"foo_bar/1"}}, {:foo=>{"$eq"=>"bar"}}]}}
|
175
|
+
|
176
|
+
assert_equal(FooBar.send(:build_query, query, opts), expected)
|
177
|
+
end
|
178
|
+
|
179
|
+
test '#build_query with options' do
|
180
|
+
query = { and: [{ _id: { eq: 'foo_bar/1' } } , { foo: { eq: 'bar'}} ] }
|
181
|
+
opts = { limit: 1, fields: ['foo']}
|
182
|
+
expected = {"selector"=>{"$and"=>[{:_id=>{"$eq"=>"foo_bar/1"}}, {:foo=>{"$eq"=>"bar"}}]}, limit: 1, fields: ['foo']}
|
183
|
+
|
184
|
+
assert_equal(FooBar.send(:build_query, query, opts), expected)
|
185
|
+
end
|
186
|
+
|
187
|
+
test '#build_selectors with invalid operator' do
|
188
|
+
query = { _id: { eeeq: 'foo_bar/1' } }
|
189
|
+
|
190
|
+
assert_raise Dolly::InvalidMangoOperatorError do
|
191
|
+
FooBar.send(:build_selectors, query)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
test '#build_selectors with type operator' do
|
196
|
+
query = { _id: { type: "user" } }
|
197
|
+
|
198
|
+
assert_nothing_raised Dolly::InvalidMangoOperatorError do
|
199
|
+
FooBarTyped.send(:build_selectors, query)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
test '#build_selectors with $type operator' do
|
204
|
+
query = { _id: { "$type" => "null" } }
|
205
|
+
|
206
|
+
assert_nothing_raised Dolly::InvalidMangoOperatorError do
|
207
|
+
FooBarTyped.send(:build_selectors, query)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
private
|
212
|
+
|
213
|
+
def generic_response rows, count = 1
|
214
|
+
{total_rows: count, offset:0, rows: rows}
|
215
|
+
end
|
216
|
+
|
217
|
+
def build_view_response properties
|
218
|
+
rows = properties.map.with_index do |v, i|
|
219
|
+
{
|
220
|
+
id: "foo_bar/#{i}",
|
221
|
+
key: "foo_bar",
|
222
|
+
value: 1,
|
223
|
+
doc: {_id: "foo_bar/#{i}", _rev: SecureRandom.hex}.merge!(v)
|
224
|
+
}
|
225
|
+
end
|
226
|
+
generic_response rows, properties.count
|
227
|
+
end
|
228
|
+
|
229
|
+
def build_view_collation_response properties
|
230
|
+
rows = properties.map.with_index do |v, i|
|
231
|
+
id = i.zero? ? "foo_bar/#{i}" : "baz/#{i}"
|
232
|
+
{
|
233
|
+
id: id,
|
234
|
+
key: "foo_bar",
|
235
|
+
value: 1,
|
236
|
+
doc: {_id: id, _rev: SecureRandom.hex}.merge!(v)
|
237
|
+
}
|
238
|
+
end
|
239
|
+
generic_response rows, properties.count
|
240
|
+
end
|
241
|
+
|
242
|
+
|
243
|
+
def build_request keys, body, view_name = 'foo_bar'
|
244
|
+
query = "keys=#{CGI::escape keys.to_s.gsub(' ','')}&" unless keys&.empty?
|
245
|
+
stub_request(:get, "#{query_base_path}?#{query.to_s}include_docs=true").
|
246
|
+
to_return(body: body.to_json)
|
247
|
+
end
|
248
|
+
|
249
|
+
def query_base_path
|
250
|
+
"#{DB_BASE_PATH}/_find"
|
251
|
+
end
|
252
|
+
|
253
|
+
def all_docs_path
|
254
|
+
"#{DB_BASE_PATH}/_all_docs"
|
255
|
+
end
|
256
|
+
|
257
|
+
def build_save_request(obj)
|
258
|
+
stub_request(:put, "#{DB_BASE_PATH}/#{CGI.escape(obj.id)}").
|
259
|
+
to_return(body: {ok: true, id: obj.id, rev: "FF0000" }.to_json)
|
260
|
+
end
|
261
|
+
|
262
|
+
def index_response(key)
|
263
|
+
{
|
264
|
+
rows: [
|
265
|
+
{
|
266
|
+
id: "_design/index_#{key}",
|
267
|
+
key: "_design/index_#{key}",
|
268
|
+
value: { rev: '1-c5457a0d26da85f15c4ad6bd739e441d' }
|
269
|
+
}
|
270
|
+
]
|
271
|
+
}
|
272
|
+
end
|
273
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -1,37 +1,82 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require 'test/unit'
|
2
|
+
require 'webmock/test_unit'
|
3
|
+
require 'mocha/test_unit'
|
4
|
+
require 'securerandom'
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
Rails.backtrace_cleaner.remove_silencers!
|
6
|
+
# Load gem files
|
7
|
+
Dir["#{File.dirname(__FILE__)}/../lib/dolly/**/*.rb"].each { |f| require f }
|
8
|
+
Dir["#{File.dirname(__FILE__)}/../lib/refinements/**/*.rb"].each { |f| require f }
|
9
|
+
Dir["#{File.dirname(__FILE__)}/../dolly.rb"].each { |f| require f }
|
9
10
|
|
10
11
|
# Load support files
|
11
12
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
12
13
|
|
13
|
-
|
14
|
-
if ActiveSupport::TestCase.method_defined?(:fixture_path=)
|
15
|
-
ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
|
16
|
-
end
|
17
|
-
|
18
|
-
|
19
|
-
class ActiveSupport::TestCase
|
14
|
+
class Test::Unit::TestCase
|
20
15
|
DEFAULT_DB = 'test'
|
16
|
+
DB_BASE_PATH = "http://localhost:5984/test".freeze
|
21
17
|
|
22
18
|
setup :global_setup
|
23
19
|
|
24
20
|
def global_setup
|
25
|
-
|
21
|
+
response = { uuids: [SecureRandom.uuid] }.to_json
|
26
22
|
|
27
|
-
|
28
|
-
|
23
|
+
stub_request(:get, %r{http://.*:5984/_uuids.*}).
|
24
|
+
to_return(status: 200, body: response, headers: { 'Content-Type': 'application/json'})
|
29
25
|
end
|
30
26
|
|
31
27
|
protected
|
28
|
+
|
32
29
|
def base_path
|
33
|
-
%r
|
30
|
+
%r{http://.*:5984/#{DEFAULT_DB}}
|
31
|
+
end
|
32
|
+
|
33
|
+
def generic_response rows, count = 1
|
34
|
+
{total_rows: count, offset:0, rows: rows}
|
35
|
+
end
|
36
|
+
|
37
|
+
def build_view_response properties
|
38
|
+
rows = properties.map.with_index do |v, i|
|
39
|
+
{
|
40
|
+
id: "foo_bar/#{i}",
|
41
|
+
key: "foo_bar",
|
42
|
+
value: 1,
|
43
|
+
doc: {_id: "foo_bar/#{i}", _rev: SecureRandom.hex}.merge!(v)
|
44
|
+
}
|
45
|
+
end
|
46
|
+
generic_response rows, properties.count
|
34
47
|
end
|
35
48
|
|
49
|
+
def build_view_collation_response properties
|
50
|
+
rows = properties.map.with_index do |v, i|
|
51
|
+
id = i.zero? ? "foo_bar/#{i}" : "baz/#{i}"
|
52
|
+
{
|
53
|
+
id: id,
|
54
|
+
key: "foo_bar",
|
55
|
+
value: 1,
|
56
|
+
doc_type: id.split("/").first,
|
57
|
+
doc: {
|
58
|
+
_id: id, _rev: SecureRandom.hex
|
59
|
+
}.merge!(v)
|
60
|
+
}
|
61
|
+
end
|
62
|
+
generic_response rows, properties.count
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def build_request keys, body, view_name = 'foo_bar'
|
67
|
+
query = "keys=#{CGI::escape keys.to_s.gsub(' ','')}&" unless keys&.empty?
|
68
|
+
stub_request(:get, "#{query_base_path}?#{query.to_s}include_docs=true").
|
69
|
+
to_return(body: body.to_json)
|
70
|
+
end
|
71
|
+
|
72
|
+
def query_base_path
|
73
|
+
"#{DB_BASE_PATH}/_all_docs"
|
74
|
+
end
|
75
|
+
|
76
|
+
def build_save_request(obj)
|
77
|
+
stub_request(:put, "#{DB_BASE_PATH}/#{CGI.escape(obj.id)}").
|
78
|
+
to_return(body: {ok: true, id: obj.id, rev: "FF0000" }.to_json)
|
79
|
+
end
|
36
80
|
end
|
37
81
|
|
82
|
+
class BaseDolly < Dolly::Document; end
|