couch_potato 1.7.0 → 1.10.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/.github/workflows/ruby.yml +50 -0
- data/.gitignore +3 -0
- data/CHANGES.md +180 -130
- data/Gemfile +4 -0
- data/README.md +61 -85
- data/Rakefile +11 -10
- data/couch_potato-rspec.gemspec +2 -1
- data/couch_potato.gemspec +9 -7
- data/gemfiles/active_support_5_0 +6 -0
- data/gemfiles/active_support_5_1 +7 -0
- data/gemfiles/active_support_5_2 +6 -0
- data/gemfiles/active_support_6_0 +6 -0
- data/gemfiles/active_support_6_1 +6 -0
- data/gemfiles/active_support_7_0 +6 -0
- data/lib/couch_potato/database.rb +170 -71
- data/lib/couch_potato/persistence/dirty_attributes.rb +3 -21
- data/lib/couch_potato/persistence/magic_timestamps.rb +3 -3
- data/lib/couch_potato/persistence/properties.rb +15 -10
- data/lib/couch_potato/persistence/simple_property.rb +0 -4
- data/lib/couch_potato/persistence/type_caster.rb +11 -6
- data/lib/couch_potato/persistence.rb +0 -1
- data/lib/couch_potato/railtie.rb +6 -11
- data/lib/couch_potato/validation.rb +8 -0
- data/lib/couch_potato/version.rb +2 -2
- data/lib/couch_potato/view/base_view_spec.rb +8 -32
- data/lib/couch_potato/view/custom_views.rb +4 -3
- data/lib/couch_potato/view/flex_view_spec.rb +121 -0
- data/lib/couch_potato/view/view_parameters.rb +34 -0
- data/lib/couch_potato.rb +37 -16
- data/spec/callbacks_spec.rb +45 -19
- data/spec/conflict_handling_spec.rb +1 -2
- data/spec/property_spec.rb +12 -3
- data/spec/railtie_spec.rb +10 -0
- data/spec/spec_helper.rb +4 -3
- data/spec/unit/active_model_compliance_spec.rb +7 -3
- data/spec/unit/attributes_spec.rb +54 -1
- data/spec/unit/caching_spec.rb +105 -0
- data/spec/unit/couch_potato_spec.rb +70 -5
- data/spec/unit/create_spec.rb +5 -4
- data/spec/unit/database_spec.rb +239 -135
- data/spec/unit/dirty_attributes_spec.rb +5 -26
- data/spec/unit/flex_view_spec_spec.rb +17 -0
- data/spec/unit/model_view_spec_spec.rb +1 -1
- data/spec/unit/rspec_stub_db_spec.rb +31 -0
- data/spec/unit/validation_spec.rb +42 -2
- data/spec/unit/view_query_spec.rb +12 -7
- data/spec/views_spec.rb +214 -103
- data/vendor/pouchdb-collate/LICENSE +202 -0
- data/vendor/pouchdb-collate/pouchdb-collate.js +430 -0
- metadata +47 -36
- data/.ruby-version +0 -1
- data/.travis.yml +0 -21
- data/gemfiles/active_support_4_0 +0 -11
- data/gemfiles/active_support_4_1 +0 -11
- data/gemfiles/active_support_4_2 +0 -11
- data/lib/couch_potato/persistence/deep_dirty_attributes.rb +0 -180
- data/spec/unit/deep_dirty_attributes_spec.rb +0 -434
@@ -13,19 +13,13 @@ describe 'dirty attribute tracking' do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
describe "save" do
|
16
|
-
it "should
|
16
|
+
it "should save when nothing dirty" do
|
17
17
|
plate = Plate.new :food => 'sushi'
|
18
18
|
@db.save_document!(plate)
|
19
|
-
expect(@couchrest_db).
|
19
|
+
expect(@couchrest_db).to receive(:save_doc)
|
20
20
|
@db.save_document(plate)
|
21
21
|
end
|
22
22
|
|
23
|
-
it "should return true when not dirty" do
|
24
|
-
plate = Plate.new :food => 'sushi'
|
25
|
-
@db.save_document!(plate)
|
26
|
-
expect(@db.save_document(plate)).to be_truthy
|
27
|
-
end
|
28
|
-
|
29
23
|
it "should save when there are dirty attributes" do
|
30
24
|
plate = Plate.new :food => 'sushi'
|
31
25
|
@db.save_document!(plate)
|
@@ -57,13 +51,13 @@ describe 'dirty attribute tracking' do
|
|
57
51
|
it "should not dup BigDecimal" do
|
58
52
|
|
59
53
|
expect {
|
60
|
-
Bowl.new :price => BigDecimal
|
54
|
+
Bowl.new :price => BigDecimal("5.23")
|
61
55
|
}.not_to raise_error
|
62
56
|
end
|
63
57
|
|
64
58
|
it "should return the old value" do
|
65
|
-
bowl = Bowl.new :price => BigDecimal
|
66
|
-
bowl.price = BigDecimal
|
59
|
+
bowl = Bowl.new :price => BigDecimal("5.23")
|
60
|
+
bowl.price = BigDecimal("2.23")
|
67
61
|
expect(bowl.price_was).to eq(5.23)
|
68
62
|
end
|
69
63
|
|
@@ -79,11 +73,6 @@ describe 'dirty attribute tracking' do
|
|
79
73
|
it "should return false if attribute not changed" do
|
80
74
|
expect(Plate.new).not_to be_food_changed
|
81
75
|
end
|
82
|
-
|
83
|
-
it "should return true if forced dirty" do
|
84
|
-
@plate.is_dirty
|
85
|
-
expect(@plate).to be_dirty
|
86
|
-
end
|
87
76
|
end
|
88
77
|
end
|
89
78
|
|
@@ -122,15 +111,5 @@ describe 'dirty attribute tracking' do
|
|
122
111
|
db.save! @plate
|
123
112
|
expect(@plate).not_to be_food_changed
|
124
113
|
end
|
125
|
-
|
126
|
-
it "should reset a forced dirty state" do
|
127
|
-
couchrest_db = double('database', :get => Plate.json_create({'_id' => '1', '_rev' => '2', 'food' => 'sushi', JSON.create_id => 'Plate'}), :info => nil, :save_doc => {'rev' => '3'})
|
128
|
-
db = CouchPotato::Database.new(couchrest_db)
|
129
|
-
@plate = db.load_document '1'
|
130
|
-
@plate.is_dirty
|
131
|
-
db.save! @plate
|
132
|
-
expect(@plate).not_to be_dirty
|
133
|
-
end
|
134
114
|
end
|
135
|
-
|
136
115
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe CouchPotato::View::FlexViewSpec::Results, '#reduce_count' do
|
6
|
+
it 'returns the value of the first row (which is the result of reduce)' do
|
7
|
+
result = CouchPotato::View::FlexViewSpec::Results.new 'rows' => [{ 'value' => 3 }]
|
8
|
+
|
9
|
+
expect(result.reduce_count).to eq(3)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'returns 0 if there is no first row (empty result set)' do
|
13
|
+
result = CouchPotato::View::FlexViewSpec::Results.new 'rows' => []
|
14
|
+
|
15
|
+
expect(result.reduce_count).to eq(0)
|
16
|
+
end
|
17
|
+
end
|
@@ -108,6 +108,6 @@ describe CouchPotato::View::ModelViewSpec, '#map_function' do
|
|
108
108
|
|
109
109
|
it "should raise exception when emit value cannot be handled" do
|
110
110
|
spec = CouchPotato::View::ModelViewSpec.new Object, 'all', {:emit_value => []}, {}
|
111
|
-
expect { spec.map_function }.to raise_error
|
111
|
+
expect { spec.map_function }.to raise_error(RuntimeError)
|
112
112
|
end
|
113
113
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
require 'couch_potato-rspec'
|
3
5
|
|
@@ -40,6 +42,35 @@ describe 'stubbing a view' do
|
|
40
42
|
expect(@db.first!(WithStubbedView.stubbed_view('123'))).to eq(:result)
|
41
43
|
end
|
42
44
|
|
45
|
+
it 'stubs the database to return fake results in batches with no given batch size' do
|
46
|
+
@db.stub_view(WithStubbedView, :stubbed_view).with('123').and_return([:result] * 501)
|
47
|
+
|
48
|
+
expect do |b|
|
49
|
+
@db.view_in_batches(WithStubbedView.stubbed_view('123'), &b)
|
50
|
+
end.to yield_successive_args([:result] * 500, [:result])
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'stubs the database to return fake results in batches with a given batch size' do
|
54
|
+
@db.stub_view(WithStubbedView, :stubbed_view).with('123').and_return([:result] * 3)
|
55
|
+
|
56
|
+
expect do |b|
|
57
|
+
@db.view_in_batches(WithStubbedView.stubbed_view('123'), batch_size: 2, &b)
|
58
|
+
end.to yield_successive_args([:result] * 2, [:result])
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'stubs the database to return fake results in batches for multiple view specs' do
|
62
|
+
@db.stub_view(WithStubbedView, :stubbed_view).with('123').and_return([:result])
|
63
|
+
@db.stub_view(WithStubbedView, :stubbed_view).with('456').and_return([:result2])
|
64
|
+
|
65
|
+
expect do |b|
|
66
|
+
@db.view_in_batches(WithStubbedView.stubbed_view('123'), &b)
|
67
|
+
end.to yield_successive_args([:result])
|
68
|
+
|
69
|
+
expect do |b|
|
70
|
+
@db.view_in_batches(WithStubbedView.stubbed_view('456'), &b)
|
71
|
+
end.to yield_successive_args([:result2])
|
72
|
+
end
|
73
|
+
|
43
74
|
it 'raises an error if there is no first result' do
|
44
75
|
@db.stub_view(WithStubbedView, :stubbed_view).and_return([])
|
45
76
|
expect do
|
@@ -1,13 +1,53 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'CouchPotato Validation' do
|
4
|
-
|
4
|
+
|
5
5
|
describe "access to errors object" do
|
6
|
-
it "
|
6
|
+
it "adds an errors method the the errors object to be compatible with Validatable" do
|
7
7
|
model_class = Class.new
|
8
8
|
model_class.send(:include, CouchPotato::Persistence)
|
9
9
|
expect(model_class.new.errors).to respond_to(:errors)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
class Monkey
|
14
|
+
include CouchPotato::Persistence
|
15
|
+
property :create_property
|
16
|
+
property :update_property
|
17
|
+
|
18
|
+
validates :create_property, presence: true, on: :create
|
19
|
+
validates :update_property, presence: true, on: :update
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'create' do
|
23
|
+
let(:monkey) { Monkey.new }
|
24
|
+
|
25
|
+
before do
|
26
|
+
monkey.valid?
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'has an error on the create property' do
|
30
|
+
expect(monkey.errors[:create_property]).to be_present
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'has no error on the update property' do
|
34
|
+
expect(monkey.errors[:update_property]).not_to be_present
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'update' do
|
39
|
+
let(:monkey) { Monkey.new _rev: '1' }
|
40
|
+
|
41
|
+
before do
|
42
|
+
monkey.valid?
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'has no error on the create property' do
|
46
|
+
expect(monkey.errors[:create_property]).to_not be_present
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'has an error on the update property' do
|
50
|
+
expect(monkey.errors[:update_property]).to be_present
|
51
|
+
end
|
52
|
+
end
|
13
53
|
end
|
@@ -15,10 +15,12 @@ describe CouchPotato::View::ViewQuery, 'query_view!' do
|
|
15
15
|
|
16
16
|
it 'updates a view if it does not exist' do
|
17
17
|
expect(db).to receive(:save_doc).with(
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
{
|
19
|
+
'views' => {'view' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}, 'lib' => {'test' => '<lib_code>'}},
|
20
|
+
'lists' => {},
|
21
|
+
"_id" => "_design/design",
|
22
|
+
"language" => "javascript"
|
23
|
+
}
|
22
24
|
)
|
23
25
|
|
24
26
|
CouchPotato::View::ViewQuery.new(db, 'design', {:view => {:map => '<map_code>', :reduce => '<reduce_code>'}}, nil, {'test' => "<lib_code>"}).query_view!
|
@@ -46,8 +48,11 @@ describe CouchPotato::View::ViewQuery, 'query_view!' do
|
|
46
48
|
|
47
49
|
it 'updates a view in erlang if it does not exist' do
|
48
50
|
expect(db).to receive(:save_doc).with(
|
49
|
-
|
50
|
-
|
51
|
+
{
|
52
|
+
'views' => {'view' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}},
|
53
|
+
'lists' => {}, "_id" => "_design/design", "language" => "erlang"
|
54
|
+
}
|
55
|
+
)
|
51
56
|
|
52
57
|
CouchPotato::View::ViewQuery.new(db, 'design',
|
53
58
|
{:view => {:map => '<map_code>', :reduce => '<reduce_code>'}},
|
@@ -120,7 +125,7 @@ describe CouchPotato::View::ViewQuery, 'query_view!' do
|
|
120
125
|
|
121
126
|
it 'does not pass in reduce or lib keys if there is no lib or reduce object' do
|
122
127
|
allow(db).to receive(:get).and_return({'views' => {}})
|
123
|
-
expect(db).to receive(:save_doc).with('views' => {'view7' => {'map' => '<map code>'}})
|
128
|
+
expect(db).to receive(:save_doc).with({'views' => {'view7' => {'map' => '<map code>'}}})
|
124
129
|
CouchPotato::View::ViewQuery.new(db, 'design', :view7 => {:map => '<map code>', :reduce => nil}).query_view!
|
125
130
|
end
|
126
131
|
|