couch_potato 1.18.0 → 1.19.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 +4 -4
- data/.github/workflows/ruby.yml +5 -3
- data/CHANGES.md +9 -0
- data/README.md +8 -52
- data/lib/couch_potato/database.rb +0 -2
- data/lib/couch_potato/persistence.rb +9 -6
- data/lib/couch_potato/version.rb +2 -2
- data/lib/couch_potato/view/base_view_spec.rb +21 -12
- data/lib/couch_potato/view/custom_view_spec.rb +0 -4
- data/lib/couch_potato/view/custom_views.rb +12 -0
- data/lib/couch_potato/view/flex_view_spec.rb +1 -1
- data/lib/couch_potato/view/raw_view_spec.rb +2 -6
- data/lib/couch_potato/view/view_query.rb +29 -28
- data/lib/couch_potato.rb +9 -1
- data/spec/property_spec.rb +1 -1
- data/spec/single_design_document_spec.rb +63 -0
- data/spec/unit/attributes_spec.rb +1 -1
- data/spec/unit/base_view_spec_spec.rb +62 -68
- data/spec/unit/couch_potato_spec.rb +3 -0
- data/spec/unit/database_spec.rb +1 -53
- data/spec/unit/rspec_matchers_spec.rb +2 -66
- data/spec/unit/view_query_spec.rb +25 -95
- data/spec/view_updates_spec.rb +53 -5
- data/spec/views_spec.rb +1 -34
- metadata +4 -5
- data/lib/couch_potato/view/lists.rb +0 -23
- data/spec/unit/lists_spec.rb +0 -20
@@ -33,8 +33,7 @@ describe CouchPotato::View::BaseViewSpec, 'initialize' do
|
|
33
33
|
:group_level => 1,
|
34
34
|
:reduce => false,
|
35
35
|
:include_docs => true,
|
36
|
-
:inclusive_end => true
|
37
|
-
:list_params => {}
|
36
|
+
:inclusive_end => true
|
38
37
|
}
|
39
38
|
}.not_to raise_error
|
40
39
|
end
|
@@ -54,70 +53,72 @@ describe CouchPotato::View::BaseViewSpec, 'initialize' do
|
|
54
53
|
expect(spec.view_parameters).to eq({:key => '2'})
|
55
54
|
end
|
56
55
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
it "generates the design document path by snake_casing the class name but keeping double colons" do
|
63
|
-
spec = CouchPotato::View::BaseViewSpec.new 'Foo::BarBaz', '', {}, ''
|
64
|
-
expect(spec.design_document).to eq('foo::bar_baz')
|
65
|
-
end
|
66
|
-
|
67
|
-
it "generates the design document independent of the view name by default" do
|
68
|
-
CouchPotato::Config.split_design_documents_per_view = false
|
69
|
-
spec = CouchPotato::View::BaseViewSpec.new 'User', 'by_login_and_email', {}, ''
|
70
|
-
expect(spec.design_document).to eq('user')
|
71
|
-
end
|
72
|
-
|
73
|
-
it "generates the design document per view if configured to" do
|
74
|
-
CouchPotato::Config.split_design_documents_per_view = true
|
75
|
-
spec = CouchPotato::View::BaseViewSpec.new 'User', 'by_login_and_email', {}, ''
|
76
|
-
expect(spec.design_document).to eq('user_view_by_login_and_email')
|
77
|
-
end
|
78
|
-
|
79
|
-
it 'adds the view name digest to the design doc name' do
|
80
|
-
CouchPotato::Config.split_design_documents_per_view = true
|
81
|
-
spec = CouchPotato::View::RawViewSpec.new 'User', 'by_login_and_email',
|
82
|
-
{digest_view_name: true, map: 'function(doc) {}'}, ''
|
83
|
-
|
84
|
-
expect(spec.design_document).to eq('user_view_by_login_and_email-375c815fcb4f977f330a2edfadc7f74d')
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'builds the name digest by hashing the map and reduce function if there is one' do
|
88
|
-
CouchPotato::Config.split_design_documents_per_view = true
|
89
|
-
spec = CouchPotato::View::RawViewSpec.new 'User', 'by_login_and_email',
|
90
|
-
{digest_view_name: true, map: 'function(doc) {}', reduce: 'function(key, values) {}'}, ''
|
91
|
-
|
92
|
-
expect(spec.design_document).to eq('user_view_by_login_and_email-c9f83cec3dab954a8ca56330006f187e')
|
93
|
-
end
|
94
|
-
|
95
|
-
|
96
|
-
it "generates the design document independent of the list name by default" do
|
97
|
-
CouchPotato::Config.split_design_documents_per_view = false
|
98
|
-
spec = CouchPotato::View::BaseViewSpec.new double(lists: nil, :to_s => 'User'), '', {list: 'test_list'}, {}
|
99
|
-
expect(spec.design_document).to eq('user')
|
100
|
-
end
|
56
|
+
context 'when single design document is enabled' do
|
57
|
+
before(:each) do
|
58
|
+
CouchPotato::Config.single_design_document = true
|
59
|
+
end
|
101
60
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
61
|
+
after(:each) do
|
62
|
+
CouchPotato::Config.single_design_document = false
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'generates one design document for all views' do
|
66
|
+
spec = CouchPotato::View::BaseViewSpec.new 'User', 'by_login_and_email', {}, ''
|
107
67
|
|
108
|
-
|
109
|
-
|
110
|
-
expect(spec.list_name).to eq(:test_list)
|
68
|
+
expect(spec.design_document).to eq('couch_potato')
|
69
|
+
end
|
111
70
|
end
|
112
71
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
72
|
+
context 'when single design document is disabled' do
|
73
|
+
before(:each) do
|
74
|
+
CouchPotato::Config.single_design_document = false
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'and split design documents per view is enabled' do
|
78
|
+
before(:each) do
|
79
|
+
CouchPotato::Config.split_design_documents_per_view = true
|
80
|
+
end
|
81
|
+
|
82
|
+
after(:each) do
|
83
|
+
CouchPotato::Config.split_design_documents_per_view = false
|
84
|
+
end
|
85
|
+
|
86
|
+
it "generates one design document per view" do
|
87
|
+
spec = CouchPotato::View::BaseViewSpec.new 'User', 'by_login_and_email', {}, ''
|
88
|
+
expect(spec.design_document).to eq('user_view_by_login_and_email')
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'adds the view name digest to the design doc name' do
|
92
|
+
spec = CouchPotato::View::RawViewSpec.new 'User', 'by_login_and_email',
|
93
|
+
{digest_view_name: true, map: 'function(doc) {}'}, ''
|
94
|
+
|
95
|
+
expect(spec.design_document).to eq('user_view_by_login_and_email-375c815fcb4f977f330a2edfadc7f74d')
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'builds the name digest by hashing the map and reduce function if there is one' do
|
99
|
+
spec = CouchPotato::View::RawViewSpec.new 'User', 'by_login_and_email',
|
100
|
+
{digest_view_name: true, map: 'function(doc) {}', reduce: 'function(key, values) {}'}, ''
|
101
|
+
|
102
|
+
expect(spec.design_document).to eq('user_view_by_login_and_email-c9f83cec3dab954a8ca56330006f187e')
|
103
|
+
end
|
104
|
+
end
|
117
105
|
|
118
|
-
|
119
|
-
|
120
|
-
|
106
|
+
context 'and split design documents per view is disabled' do
|
107
|
+
before(:each) do
|
108
|
+
CouchPotato::Config.split_design_documents_per_view = false
|
109
|
+
end
|
110
|
+
|
111
|
+
it "generates the design document path by snake_casing the class name but keeping double colons" do
|
112
|
+
spec = CouchPotato::View::BaseViewSpec.new 'Foo::BarBaz', '', {}, ''
|
113
|
+
expect(spec.design_document).to eq('foo::bar_baz')
|
114
|
+
end
|
115
|
+
|
116
|
+
it "generates the design document independent of the view name" do
|
117
|
+
spec = CouchPotato::View::BaseViewSpec.new 'User', 'by_login_and_email', {}, ''
|
118
|
+
expect(spec.design_document).to eq('user')
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
121
122
|
end
|
122
123
|
|
123
124
|
it 'returns the view name' do
|
@@ -146,13 +147,6 @@ describe CouchPotato::View::BaseViewSpec, 'initialize' do
|
|
146
147
|
end
|
147
148
|
end
|
148
149
|
|
149
|
-
it "returns the list function" do
|
150
|
-
klass = double 'class'
|
151
|
-
allow(klass).to receive(:lists).with('test_list').and_return('<list_code>')
|
152
|
-
spec = CouchPotato::View::BaseViewSpec.new klass, 'all', {list: 'test_list'}, {}
|
153
|
-
expect(spec.list_function).to eq('<list_code>')
|
154
|
-
end
|
155
|
-
|
156
150
|
it 'reads the language from the couch potato config by default' do
|
157
151
|
CouchPotato::Config.default_language = :ruby
|
158
152
|
spec = CouchPotato::View::BaseViewSpec.new Object, 'all', {}, {}
|
@@ -8,6 +8,7 @@ describe CouchPotato, '.configure' do
|
|
8
8
|
CouchPotato::Config.database_name = nil
|
9
9
|
CouchPotato::Config.split_design_documents_per_view = false
|
10
10
|
CouchPotato::Config.digest_view_names = false
|
11
|
+
CouchPotato::Config.single_design_document = false
|
11
12
|
CouchPotato::Config.default_language = :javascript
|
12
13
|
CouchPotato::Config.database_host = 'http://127.0.0.1:5984'
|
13
14
|
CouchPotato::Config.additional_databases = {}
|
@@ -35,12 +36,14 @@ describe CouchPotato, '.configure' do
|
|
35
36
|
test2: 'test2_db'
|
36
37
|
},
|
37
38
|
split_design_documents_per_view: true,
|
39
|
+
single_design_document: true,
|
38
40
|
digest_view_names: true,
|
39
41
|
default_language: 'erlang'
|
40
42
|
)
|
41
43
|
|
42
44
|
expect(CouchPotato::Config.database_name).to eq('testdb')
|
43
45
|
expect(CouchPotato::Config.split_design_documents_per_view).to eq(true)
|
46
|
+
expect(CouchPotato::Config.single_design_document).to eq(true)
|
44
47
|
expect(CouchPotato::Config.digest_view_names).to eq(true)
|
45
48
|
expect(CouchPotato::Config.default_language).to eq('erlang')
|
46
49
|
expect(CouchPotato::Config.database_host).to eq('http://10.0.0.1:2000')
|
data/spec/unit/database_spec.rb
CHANGED
@@ -415,29 +415,10 @@ describe CouchPotato::Database, 'view' do
|
|
415
415
|
allow(CouchPotato::View::ViewQuery).to receive_messages(new: double('view query', query_view!: { 'rows' => [@result] }))
|
416
416
|
end
|
417
417
|
|
418
|
-
it 'initializes a view query with map/reduce/list/lib funtions' do
|
419
|
-
allow(@spec).to receive_messages(design_document: 'design_doc', view_name: 'my_view',
|
420
|
-
map_function: '<map_code>', reduce_function: '<reduce_code>',
|
421
|
-
lib: { test: '<test_code>' },
|
422
|
-
list_name: 'my_list', list_function: '<list_code>', language: 'javascript')
|
423
|
-
expect(CouchPotato::View::ViewQuery).to receive(:new).with(
|
424
|
-
@couchrest_db,
|
425
|
-
'design_doc',
|
426
|
-
{ 'my_view' => {
|
427
|
-
map: '<map_code>',
|
428
|
-
reduce: '<reduce_code>'
|
429
|
-
} },
|
430
|
-
{ 'my_list' => '<list_code>' },
|
431
|
-
{ test: '<test_code>' },
|
432
|
-
'javascript'
|
433
|
-
)
|
434
|
-
@db.view(@spec)
|
435
|
-
end
|
436
418
|
|
437
|
-
it 'initializes a view query with map/reduce
|
419
|
+
it 'initializes a view query with map/reduce functions' do
|
438
420
|
allow(@spec).to receive_messages(design_document: 'design_doc', view_name: 'my_view',
|
439
421
|
map_function: '<map_code>', reduce_function: '<reduce_code>',
|
440
|
-
lib: nil, list_name: 'my_list', list_function: '<list_code>',
|
441
422
|
language: 'javascript')
|
442
423
|
expect(CouchPotato::View::ViewQuery).to receive(:new).with(
|
443
424
|
@couchrest_db,
|
@@ -446,44 +427,11 @@ describe CouchPotato::Database, 'view' do
|
|
446
427
|
map: '<map_code>',
|
447
428
|
reduce: '<reduce_code>'
|
448
429
|
} },
|
449
|
-
{ 'my_list' => '<list_code>' },
|
450
|
-
nil,
|
451
430
|
'javascript'
|
452
431
|
)
|
453
432
|
@db.view(@spec)
|
454
433
|
end
|
455
434
|
|
456
|
-
it 'initializes a view query with only map/reduce/lib functions' do
|
457
|
-
allow(@spec).to receive_messages(design_document: 'design_doc', view_name: 'my_view',
|
458
|
-
map_function: '<map_code>', reduce_function: '<reduce_code>',
|
459
|
-
list_name: nil, list_function: nil,
|
460
|
-
lib: { test: '<test_code>' })
|
461
|
-
expect(CouchPotato::View::ViewQuery).to receive(:new).with(
|
462
|
-
@couchrest_db,
|
463
|
-
'design_doc',
|
464
|
-
{ 'my_view' => {
|
465
|
-
map: '<map_code>',
|
466
|
-
reduce: '<reduce_code>'
|
467
|
-
} }, nil, { test: '<test_code>' }, anything
|
468
|
-
)
|
469
|
-
@db.view(@spec)
|
470
|
-
end
|
471
|
-
|
472
|
-
it 'initializes a view query with only map/reduce functions' do
|
473
|
-
allow(@spec).to receive_messages(design_document: 'design_doc', view_name: 'my_view',
|
474
|
-
map_function: '<map_code>', reduce_function: '<reduce_code>',
|
475
|
-
lib: nil, list_name: nil, list_function: nil)
|
476
|
-
expect(CouchPotato::View::ViewQuery).to receive(:new).with(
|
477
|
-
@couchrest_db,
|
478
|
-
'design_doc',
|
479
|
-
{ 'my_view' => {
|
480
|
-
map: '<map_code>',
|
481
|
-
reduce: '<reduce_code>'
|
482
|
-
} }, nil, nil, anything
|
483
|
-
)
|
484
|
-
@db.view(@spec)
|
485
|
-
end
|
486
|
-
|
487
435
|
it 'sets itself on returned docs that have an accessor' do
|
488
436
|
allow(@result).to receive(:respond_to?).and_return(false)
|
489
437
|
allow(@result).to receive(:respond_to?).with(:database=).and_return(true)
|
@@ -36,22 +36,6 @@ describe CouchPotato::RSpec::MapToMatcher do
|
|
36
36
|
expect(spec).to map({}).to([nil, "2013-05-17T15:00:00.000Z"])
|
37
37
|
end
|
38
38
|
|
39
|
-
it "should work with commonJS modules that use 'exports'" do
|
40
|
-
spec = double(
|
41
|
-
:map_function => "function(doc) { var test = require('views/lib/test'); emit(null, test.test); }",
|
42
|
-
:lib => {:test => "exports.test = 'test';"}
|
43
|
-
)
|
44
|
-
expect(spec).to map({}).to([nil, "test"])
|
45
|
-
end
|
46
|
-
|
47
|
-
it "should work with commonJS modules that use 'module.exports'" do
|
48
|
-
spec = double(
|
49
|
-
:map_function => "function(doc) { var test = require('views/lib/test'); emit(null, test.test); }",
|
50
|
-
:lib => {:test => "module.exports.test = 'test';"}
|
51
|
-
)
|
52
|
-
expect(spec).to map({}).to([nil, "test"])
|
53
|
-
end
|
54
|
-
|
55
39
|
describe "failing specs" do
|
56
40
|
before(:each) do
|
57
41
|
@view_spec = double(:map_function => "function(doc) {emit(doc.name, null)}")
|
@@ -145,22 +129,6 @@ describe CouchPotato::RSpec::MapReduceToMatcher do
|
|
145
129
|
expect(spec).to map_reduce({}).to({"key" => nil, "value" => "2013-05-17T15:00:00.000Z"})
|
146
130
|
end
|
147
131
|
|
148
|
-
it "should handle CommonJS requires for modules that use 'exports'" do
|
149
|
-
spec = double(
|
150
|
-
:map_function => "function() { var test = require('views/lib/test'); emit(null, test.test); }",
|
151
|
-
:reduce_function => "function(keys, values) { return 'test' }",
|
152
|
-
:lib => {:test => "exports.test = 'test'"})
|
153
|
-
expect(spec).to map_reduce({}).to({"key" => nil, "value" => "test"})
|
154
|
-
end
|
155
|
-
|
156
|
-
it "should handle CommonJS requires for modules that use 'module.exports'" do
|
157
|
-
spec = double(
|
158
|
-
:map_function => "function() { var test = require('views/lib/test'); emit(null, test.test); }",
|
159
|
-
:reduce_function => "function(keys, values) { return 'test' }",
|
160
|
-
:lib => {:test => "module.exports.test = 'test'"})
|
161
|
-
expect(spec).to map_reduce({}).to({"key" => nil, "value" => "test"})
|
162
|
-
end
|
163
|
-
|
164
132
|
it "should handle sum function" do
|
165
133
|
spec = double(
|
166
134
|
:map_function => "function(doc) { emit(null, doc.age); }",
|
@@ -240,13 +208,13 @@ describe CouchPotato::RSpec::MapReduceToMatcher do
|
|
240
208
|
it "should have a nice error message for failing should" do
|
241
209
|
expect {
|
242
210
|
expect(@view_spec).to map_reduce(@docs).with_options(:group => false).to({"key" => nil, "value" => 9})
|
243
|
-
}.to raise_error(
|
211
|
+
}.to raise_error(%r{Expected to map/reduce to \[{"key"\s*=>\s*nil, "value"\s*=>\s*9}\] but got \[{"key"\s*=>\s*nil, "value"\s*=>\s*8}\].})
|
244
212
|
end
|
245
213
|
|
246
214
|
it "should have a nice error message for failing should not" do
|
247
215
|
expect {
|
248
216
|
expect(@view_spec).not_to map_reduce(@docs).with_options(:group => false).to({"key" => nil, "value" => 8})
|
249
|
-
}.to raise_error(
|
217
|
+
}.to raise_error(%r{Expected not to map/reduce to \[{"key"\s*=>\s*nil, "value"\s*=>\s*8}\] but did.})
|
250
218
|
end
|
251
219
|
end
|
252
220
|
|
@@ -283,35 +251,3 @@ describe CouchPotato::RSpec::MapReduceToMatcher do
|
|
283
251
|
end
|
284
252
|
end
|
285
253
|
|
286
|
-
describe CouchPotato::RSpec::ListAsMatcher do
|
287
|
-
before(:each) do
|
288
|
-
@view_spec = double(:list_function => "function() {var row = getRow(); send(JSON.stringify([{text: row.text + ' world'}]));}")
|
289
|
-
end
|
290
|
-
|
291
|
-
it "should pass if the function return the expected json" do
|
292
|
-
expect(@view_spec).to list({'rows' => [{:text => 'hello'}]}).as([{'text' => 'hello world'}])
|
293
|
-
end
|
294
|
-
|
295
|
-
it "should not pass if the function does not return the expected json" do
|
296
|
-
expect(@view_spec).not_to list({'rows' => [{:text => 'hello'}]}).as([{'text' => 'hello there'}])
|
297
|
-
end
|
298
|
-
|
299
|
-
it "should work with date values" do
|
300
|
-
spec = double(:list_function => "function() { send(JSON.stringify([{date: new Date(1368802800000)}])); }")
|
301
|
-
expect(spec).to list({"rows" => [{}]}).as([{"date" => "2013-05-17T15:00:00.000Z"}])
|
302
|
-
end
|
303
|
-
|
304
|
-
describe "failing specs" do
|
305
|
-
it "should have a nice error message for failing should" do
|
306
|
-
expect {
|
307
|
-
expect(@view_spec).to list({'rows' => [{:text => 'hello'}]}).as([{'text' => 'hello there'}])
|
308
|
-
}.to raise_error('Expected to list as [{"text"=>"hello there"}] but got [{"text"=>"hello world"}].')
|
309
|
-
end
|
310
|
-
|
311
|
-
it "should have a nice error message for failing should not" do
|
312
|
-
expect {
|
313
|
-
expect(@view_spec).not_to list({'rows' => [{:text => 'hello'}]}).as([{'text' => 'hello world'}])
|
314
|
-
}.to raise_error('Expected to not list as [{"text"=>"hello world"}] but did.')
|
315
|
-
end
|
316
|
-
end
|
317
|
-
end
|
@@ -8,6 +8,11 @@ describe CouchPotato::View::ViewQuery, 'query_view!' do
|
|
8
8
|
CouchPotato::View::ViewQuery.clear_cache
|
9
9
|
end
|
10
10
|
|
11
|
+
after(:each) do
|
12
|
+
CouchPotato::Config.single_design_document = false
|
13
|
+
CouchPotato::Config.digest_view_names = false
|
14
|
+
end
|
15
|
+
|
11
16
|
it 'does not pass a key if conditions are empty' do
|
12
17
|
expect(db).to receive(:view).with(anything, {})
|
13
18
|
CouchPotato::View::ViewQuery.new(db, '', {:view0 => {}}).query_view!
|
@@ -16,14 +21,13 @@ describe CouchPotato::View::ViewQuery, 'query_view!' do
|
|
16
21
|
it 'updates a view if it does not exist' do
|
17
22
|
expect(db).to receive(:save_doc).with(
|
18
23
|
{
|
19
|
-
'views' => {'view' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}
|
20
|
-
'lists' => {},
|
24
|
+
'views' => {'view' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}},
|
21
25
|
"_id" => "_design/design",
|
22
26
|
"language" => "javascript"
|
23
27
|
}
|
24
28
|
)
|
25
29
|
|
26
|
-
CouchPotato::View::ViewQuery.new(db, 'design', {:view => {:map => '<map_code>', :reduce => '<reduce_code>'}}
|
30
|
+
CouchPotato::View::ViewQuery.new(db, 'design', {:view => {:map => '<map_code>', :reduce => '<reduce_code>'}}).query_view!
|
27
31
|
end
|
28
32
|
|
29
33
|
it 'only updates a view once' do
|
@@ -50,33 +54,19 @@ describe CouchPotato::View::ViewQuery, 'query_view!' do
|
|
50
54
|
expect(db).to receive(:save_doc).with(
|
51
55
|
{
|
52
56
|
'views' => {'view' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}},
|
53
|
-
|
57
|
+
"_id" => "_design/design", "language" => "erlang"
|
54
58
|
}
|
55
59
|
)
|
56
60
|
|
57
61
|
CouchPotato::View::ViewQuery.new(db, 'design',
|
58
62
|
{:view => {:map => '<map_code>', :reduce => '<reduce_code>'}},
|
59
|
-
|
63
|
+
:erlang).query_view!
|
60
64
|
end
|
61
65
|
|
62
66
|
it "does not update a view when the views object haven't changed" do
|
63
67
|
allow(db).to receive(:get).and_return({'views' => {'view' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}}})
|
64
68
|
expect(db).not_to receive(:save_doc)
|
65
|
-
CouchPotato::View::ViewQuery.new(db, 'design', {:view => {:map => '<map_code>', :reduce => '<reduce_code>'}}
|
66
|
-
end
|
67
|
-
|
68
|
-
it "does not update a view when the list function hasn't changed" do
|
69
|
-
allow(db).to receive(:get).and_return({'views' => {'view' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}}, 'lists' => {'list0' => '<list_code>'}})
|
70
|
-
expect(db).not_to receive(:save_doc)
|
71
|
-
CouchPotato::View::ViewQuery.new(db, 'design', {:view => {:map => '<map_code>', :reduce => '<reduce_code>'}}, :list0 => '<list_code>').query_view!
|
72
|
-
end
|
73
|
-
|
74
|
-
it "does not update a view when the lib function hasn't changed" do
|
75
|
-
allow(db).to receive(:get).and_return({'views' => {'view' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}, 'lib' => {'test' => '<lib_code>'}}})
|
76
|
-
|
77
|
-
expect(db).not_to receive(:save_doc)
|
78
|
-
|
79
|
-
CouchPotato::View::ViewQuery.new(db, 'design', {:view => {:map => '<map_code>', :reduce => '<reduce_code>'}}, nil, {'test' => "<lib_code>"}).query_view!
|
69
|
+
CouchPotato::View::ViewQuery.new(db, 'design', {:view => {:map => '<map_code>', :reduce => '<reduce_code>'}}).query_view!
|
80
70
|
end
|
81
71
|
|
82
72
|
it 'updates a view when the map function has changed' do
|
@@ -91,88 +81,28 @@ describe CouchPotato::View::ViewQuery, 'query_view!' do
|
|
91
81
|
CouchPotato::View::ViewQuery.new(db, 'design', :view3 => {:map => '<new map_code>'}).query_view!
|
92
82
|
end
|
93
83
|
|
94
|
-
it 'updates a view when the lib hash has changed' do
|
95
|
-
allow(db).to receive(:get).and_return({'views' => {'view4' => {'map' => '<map_code>'}}}, 'lib' => {'test' => "<test_lib>"})
|
96
|
-
|
97
|
-
expect(db).to receive(:save_doc)
|
98
|
-
|
99
|
-
CouchPotato::View::ViewQuery.new(db, 'design', {:view4 => {:map => '<map_code>'}}, nil, {:test => "<test_lib>"}).query_view!
|
100
|
-
end
|
101
|
-
|
102
|
-
it "doesn't override libs with different names" do
|
103
|
-
allow(db).to receive(:get).and_return({'views' => {'view5' => {'map' => '<map_code>'}, 'lib' => {'test' => "<test_lib>"}}})
|
104
|
-
expect(db).to receive(:save_doc).with({
|
105
|
-
'views' => {
|
106
|
-
'view5' => {'map' => '<map_code>'},
|
107
|
-
'lib' => {'test' => '<test_lib>', 'test1' => '<test1_lib>'}
|
108
|
-
}
|
109
|
-
})
|
110
|
-
CouchPotato::View::ViewQuery.new(db, 'design', {:view5 => {:map => '<map_code>'}}, nil, {'test1' => '<test1_lib>'}).query_view!
|
111
|
-
end
|
112
|
-
|
113
|
-
it 'overrides libs with the same name' do
|
114
|
-
allow(db).to receive(:get).and_return({'views' => {'view6' => {'map' => '<map_code>'}, 'lib' => {'test' => "<test_lib>"}}})
|
115
|
-
|
116
|
-
expect(db).to receive(:save_doc).with({
|
117
|
-
'views' => {
|
118
|
-
'view6' => {'map' => '<map_code>'},
|
119
|
-
'lib' => {'test' => '<test1_lib>'}
|
120
|
-
},
|
121
|
-
})
|
122
|
-
|
123
|
-
CouchPotato::View::ViewQuery.new(db, 'design', {:view6 => {:map => '<map_code>'}}, nil, {'test' => '<test1_lib>'}).query_view!
|
124
|
-
end
|
125
|
-
|
126
|
-
it 'does not pass in reduce or lib keys if there is no lib or reduce object' do
|
127
|
-
allow(db).to receive(:get).and_return({'views' => {}})
|
128
|
-
expect(db).to receive(:save_doc).with({'views' => {'view7' => {'map' => '<map code>'}}})
|
129
|
-
CouchPotato::View::ViewQuery.new(db, 'design', :view7 => {:map => '<map code>', :reduce => nil}).query_view!
|
130
|
-
end
|
131
|
-
|
132
84
|
it 'updates a view when the reduce function has changed' do
|
133
85
|
allow(db).to receive(:get).and_return({'views' => {'view8' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}}})
|
134
86
|
expect(db).to receive(:save_doc)
|
135
87
|
CouchPotato::View::ViewQuery.new(db, 'design', :view8 => {:map => '<map_code>', :reduce => '<new reduce_code>'}).query_view!
|
136
88
|
end
|
137
89
|
|
138
|
-
it '
|
139
|
-
|
140
|
-
|
141
|
-
'lists' => {'list1' => '<list_code>'}
|
142
|
-
})
|
143
|
-
expect(db).to receive(:save_doc)
|
144
|
-
CouchPotato::View::ViewQuery.new(db, 'design', {:view9 => {:map => '<map_code>', :reduce => '<reduce_code>'}}, :list1 => '<new_list_code>').query_view!
|
145
|
-
end
|
90
|
+
it 'adds a digest of all views to the design document if single_design_doc is true' do
|
91
|
+
CouchPotato::Config.single_design_document = true
|
92
|
+
CouchPotato::Config.digest_view_names = true
|
146
93
|
|
147
|
-
|
148
|
-
allow(db).to receive(:
|
149
|
-
|
150
|
-
}
|
151
|
-
|
152
|
-
CouchPotato
|
153
|
-
end
|
154
|
-
|
155
|
-
it "does not update a view when there is a list function but no list function is passed" do
|
156
|
-
allow(db).to receive(:get).and_return({
|
157
|
-
'views' => {'view11' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}},
|
158
|
-
'lists' => {'list1' => '<list_code>'}
|
159
|
-
})
|
160
|
-
expect(db).not_to receive(:save_doc)
|
161
|
-
CouchPotato::View::ViewQuery.new(db, 'design', {:view11 => {:map => '<map_code>', :reduce => '<reduce_code>'}}, {}).query_view!
|
162
|
-
end
|
163
|
-
|
164
|
-
it "does not update a view when there were no lists before and no list function is passed" do
|
165
|
-
allow(db).to receive(:get).and_return({
|
166
|
-
'views' => {'view12' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}}
|
167
|
-
})
|
168
|
-
expect(db).not_to receive(:save_doc)
|
169
|
-
CouchPotato::View::ViewQuery.new(db, 'design', {:view12 => {:map => '<map_code>', :reduce => '<reduce_code>'}}, {}).query_view!
|
170
|
-
end
|
94
|
+
allow(db).to receive(:get).and_return(nil)
|
95
|
+
allow(db).to receive(:save_doc).and_return(true)
|
96
|
+
view_class = double('view_class',
|
97
|
+
views: {view: {map: '<map_code>'}},
|
98
|
+
execute_view: double('view_spec', view_name: 'view', map_function: '<map_code>', reduce_function: nil))
|
99
|
+
allow(CouchPotato).to receive(:views).and_return([view_class])
|
171
100
|
|
172
|
-
|
173
|
-
|
101
|
+
CouchPotato::View::ViewQuery.new(
|
102
|
+
db,
|
103
|
+
'couch_potato',
|
104
|
+
{:view => {:map => '<map_code>'}}).query_view!
|
174
105
|
|
175
|
-
expect(db
|
176
|
-
CouchPotato::View::ViewQuery.new(db, 'my_design', {:view13 => {:map => '<map_code>', :reduce => '<reduce_code>'}}, :list1 => '<new_list_code>').query_view!(:key => 1)
|
106
|
+
expect(db).to have_received(:save_doc).with(hash_including({"_id" => "_design/couch_potato-56d286b4f0cd3a50fdd2ad428034d08a6483311539f7e138c45e781611b9dbbc"}))
|
177
107
|
end
|
178
|
-
end
|
108
|
+
end
|
data/spec/view_updates_spec.rb
CHANGED
@@ -7,8 +7,27 @@ describe "automatic view updates" do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should update a view that doesn't match the given functions" do
|
10
|
-
CouchPotato::View::ViewQuery.new(
|
11
|
-
|
10
|
+
CouchPotato::View::ViewQuery.new(
|
11
|
+
@db,
|
12
|
+
'test_design1', {
|
13
|
+
'test_view' => {
|
14
|
+
:map => 'function(doc) { }',
|
15
|
+
:reduce => 'function(key, values) { return []; }'
|
16
|
+
}
|
17
|
+
}
|
18
|
+
).query_view! # create view
|
19
|
+
CouchPotato::View::ViewQuery.clear_cache
|
20
|
+
CouchPotato::View::ViewQuery.new(
|
21
|
+
@db,
|
22
|
+
'test_design1',
|
23
|
+
{
|
24
|
+
'test_view' => {
|
25
|
+
:map => 'function(doc) {emit(doc.id, null)}',
|
26
|
+
:reduce => 'function(key, values) {return sum(values)}'
|
27
|
+
}
|
28
|
+
}
|
29
|
+
).query_view!
|
30
|
+
|
12
31
|
expect(CouchPotato.database.load('_design/test_design1')['views']['test_view']).to eq({
|
13
32
|
'map' => 'function(doc) {emit(doc.id, null)}',
|
14
33
|
'reduce' => 'function(key, values) {return sum(values)}'
|
@@ -16,9 +35,38 @@ describe "automatic view updates" do
|
|
16
35
|
end
|
17
36
|
|
18
37
|
it "should only update a view once to avoid writing the view for every request" do
|
19
|
-
CouchPotato::View::ViewQuery.new(
|
20
|
-
|
21
|
-
|
38
|
+
CouchPotato::View::ViewQuery.new(
|
39
|
+
@db,
|
40
|
+
'test_design2',
|
41
|
+
{
|
42
|
+
'test_view' => {
|
43
|
+
:map => 'function(doc) {}',
|
44
|
+
:reduce => 'function() {}'
|
45
|
+
}
|
46
|
+
}
|
47
|
+
).query_view! # create view
|
48
|
+
CouchPotato::View::ViewQuery.clear_cache
|
49
|
+
CouchPotato::View::ViewQuery.new(
|
50
|
+
@db,
|
51
|
+
'test_design2',
|
52
|
+
{
|
53
|
+
'test_view' => {
|
54
|
+
:map => 'function(doc) {emit(doc.id, null)}',
|
55
|
+
:reduce => 'function(key, values) {return sum(values)}'
|
56
|
+
}
|
57
|
+
}
|
58
|
+
).query_view!
|
59
|
+
CouchPotato::View::ViewQuery.new(
|
60
|
+
@db,
|
61
|
+
'test_design2',
|
62
|
+
{
|
63
|
+
'test_view' => {
|
64
|
+
:map => 'function(doc) {}',
|
65
|
+
:reduce => 'function() {}'
|
66
|
+
}
|
67
|
+
}
|
68
|
+
).query_view!
|
69
|
+
|
22
70
|
expect(CouchPotato.database.load('_design/test_design2')['views']['test_view']).to eq({
|
23
71
|
'map' => 'function(doc) {emit(doc.id, null)}',
|
24
72
|
'reduce' => 'function(key, values) {return sum(values)}'
|
data/spec/views_spec.rb
CHANGED
@@ -225,7 +225,7 @@ describe 'views' do
|
|
225
225
|
|
226
226
|
describe 'with array as key' do
|
227
227
|
it 'should create a map function with the composite key' do
|
228
|
-
expect(CouchPotato::View::ViewQuery).to receive(:new) do |_db, _design_name, view
|
228
|
+
expect(CouchPotato::View::ViewQuery).to receive(:new) do |_db, _design_name, view|
|
229
229
|
expect(view['key_array_timeline'][:map]).to match(/emit\(\[doc\['time'\], doc\['state'\]\]/)
|
230
230
|
|
231
231
|
double('view query', query_view!: { 'rows' => [] })
|
@@ -362,39 +362,6 @@ describe 'views' do
|
|
362
362
|
end
|
363
363
|
end
|
364
364
|
|
365
|
-
describe 'list functions' do
|
366
|
-
class Coworker
|
367
|
-
include CouchPotato::Persistence
|
368
|
-
|
369
|
-
property :name
|
370
|
-
|
371
|
-
view :all_with_list, key: :name, list: :append_doe
|
372
|
-
view :all, key: :name
|
373
|
-
|
374
|
-
list :append_doe, <<-JS
|
375
|
-
function(head, req) {
|
376
|
-
var row;
|
377
|
-
send('{"rows": [');
|
378
|
-
while(row = getRow()) {
|
379
|
-
row.doc.name = row.doc.name + ' doe';
|
380
|
-
send(JSON.stringify(row));
|
381
|
-
};
|
382
|
-
send(']}');
|
383
|
-
}
|
384
|
-
JS
|
385
|
-
end
|
386
|
-
|
387
|
-
it 'should use the list function declared at class level' do
|
388
|
-
@db.save! Coworker.new(name: 'joe')
|
389
|
-
expect(@db.view(Coworker.all_with_list).first.name).to eq('joe doe')
|
390
|
-
end
|
391
|
-
|
392
|
-
it 'should use the list function passed at runtime' do
|
393
|
-
@db.save! Coworker.new(name: 'joe')
|
394
|
-
expect(@db.view(Coworker.all(list: :append_doe)).first.name).to eq('joe doe')
|
395
|
-
end
|
396
|
-
end
|
397
|
-
|
398
365
|
describe 'with stale views' do
|
399
366
|
it 'does not return deleted documents' do
|
400
367
|
build = Build.new
|