chewy 0.6.2 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/.travis.yml +35 -29
- data/Appraisals +37 -0
- data/CHANGELOG.md +115 -4
- data/Gemfile +2 -3
- data/README.md +135 -40
- data/chewy.gemspec +4 -3
- data/gemfiles/rails.3.2.activerecord.gemfile +13 -0
- data/gemfiles/rails.3.2.activerecord.kaminari.gemfile +14 -0
- data/gemfiles/rails.3.2.activerecord.will_paginate.gemfile +14 -0
- data/gemfiles/rails.4.0.activerecord.gemfile +13 -0
- data/gemfiles/rails.4.0.activerecord.kaminari.gemfile +14 -0
- data/gemfiles/rails.4.0.activerecord.will_paginate.gemfile +14 -0
- data/gemfiles/rails.4.0.mongoid.gemfile +13 -0
- data/gemfiles/rails.4.0.mongoid.kaminari.gemfile +14 -0
- data/gemfiles/rails.4.0.mongoid.will_paginate.gemfile +14 -0
- data/gemfiles/rails.4.1.activerecord.gemfile +13 -0
- data/gemfiles/rails.4.1.activerecord.kaminari.gemfile +14 -0
- data/gemfiles/rails.4.1.activerecord.will_paginate.gemfile +14 -0
- data/gemfiles/rails.4.1.mongoid.gemfile +13 -0
- data/gemfiles/rails.4.1.mongoid.kaminari.gemfile +14 -0
- data/gemfiles/rails.4.1.mongoid.will_paginate.gemfile +14 -0
- data/gemfiles/rails.4.2.activerecord.gemfile +13 -0
- data/gemfiles/rails.4.2.activerecord.kaminari.gemfile +14 -0
- data/gemfiles/rails.4.2.activerecord.will_paginate.gemfile +14 -0
- data/gemfiles/rails.4.2.mongoid.gemfile +13 -0
- data/gemfiles/rails.4.2.mongoid.kaminari.gemfile +14 -0
- data/gemfiles/rails.4.2.mongoid.will_paginate.gemfile +14 -0
- data/lib/chewy.rb +65 -0
- data/lib/chewy/config.rb +44 -93
- data/lib/chewy/errors.rb +14 -5
- data/lib/chewy/fields/base.rb +8 -7
- data/lib/chewy/fields/root.rb +2 -2
- data/lib/chewy/index.rb +7 -9
- data/lib/chewy/log_subscriber.rb +34 -0
- data/lib/chewy/query.rb +41 -27
- data/lib/chewy/query/criteria.rb +28 -23
- data/lib/chewy/query/scoping.rb +20 -0
- data/lib/chewy/railtie.rb +51 -13
- data/lib/chewy/repository.rb +61 -0
- data/lib/chewy/rspec/update_index.rb +3 -6
- data/lib/chewy/search.rb +28 -7
- data/lib/chewy/strategy.rb +60 -0
- data/lib/chewy/strategy/atomic.rb +31 -0
- data/lib/chewy/strategy/base.rb +27 -0
- data/lib/chewy/strategy/bypass.rb +15 -0
- data/lib/chewy/strategy/urgent.rb +17 -0
- data/lib/chewy/type.rb +19 -5
- data/lib/chewy/type/adapter/active_record.rb +28 -117
- data/lib/chewy/type/adapter/base.rb +35 -0
- data/lib/chewy/type/adapter/mongoid.rb +23 -123
- data/lib/chewy/type/adapter/object.rb +41 -19
- data/lib/chewy/type/adapter/orm.rb +142 -0
- data/lib/chewy/type/import.rb +43 -16
- data/lib/chewy/type/observe.rb +8 -21
- data/lib/chewy/version.rb +1 -1
- data/lib/tasks/chewy.rake +8 -4
- data/spec/chewy/config_spec.rb +20 -97
- data/spec/chewy/fields/base_spec.rb +24 -11
- data/spec/chewy/fields/time_fields_spec.rb +27 -0
- data/spec/chewy/index/settings_spec.rb +2 -1
- data/spec/chewy/index_spec.rb +98 -79
- data/spec/chewy/query/criteria_spec.rb +14 -0
- data/spec/chewy/query_spec.rb +1 -1
- data/spec/chewy/repository_spec.rb +50 -0
- data/spec/chewy/search_spec.rb +100 -0
- data/spec/chewy/strategy_spec.rb +109 -0
- data/spec/chewy/type/adapter/active_record_spec.rb +110 -46
- data/spec/chewy/type/adapter/mongoid_spec.rb +123 -74
- data/spec/chewy/type/adapter/object_spec.rb +51 -34
- data/spec/chewy/type/import_spec.rb +21 -21
- data/spec/chewy/type/observe_spec.rb +26 -29
- data/spec/chewy/type_spec.rb +19 -0
- data/spec/chewy_spec.rb +19 -3
- data/spec/spec_helper.rb +1 -1
- data/spec/support/active_record.rb +2 -1
- data/spec/support/mongoid.rb +29 -38
- metadata +85 -55
- data/gemfiles/Gemfile.rails-3.2.active_record +0 -6
- data/gemfiles/Gemfile.rails-3.2.active_record.kaminari +0 -7
- data/gemfiles/Gemfile.rails-3.2.active_record.will_paginate +0 -7
- data/gemfiles/Gemfile.rails-4.0.active_record +0 -6
- data/gemfiles/Gemfile.rails-4.0.active_record.kaminari +0 -7
- data/gemfiles/Gemfile.rails-4.0.active_record.will_paginate +0 -7
- data/gemfiles/Gemfile.rails-4.0.mongoid +0 -6
- data/gemfiles/Gemfile.rails-4.0.mongoid.kaminari +0 -7
- data/gemfiles/Gemfile.rails-4.0.mongoid.will_paginate +0 -7
- data/gemfiles/Gemfile.rails-4.1.active_record +0 -6
- data/gemfiles/Gemfile.rails-4.1.active_record.kaminari +0 -7
- data/gemfiles/Gemfile.rails-4.1.active_record.will_paginate +0 -7
- data/gemfiles/Gemfile.rails-4.1.mongoid +0 -6
- data/gemfiles/Gemfile.rails-4.1.mongoid.kaminari +0 -7
- data/gemfiles/Gemfile.rails-4.1.mongoid.will_paginate +0 -7
- data/gemfiles/Gemfile.rails-4.2.active_record +0 -6
- data/gemfiles/Gemfile.rails-4.2.active_record.kaminari +0 -7
- data/gemfiles/Gemfile.rails-4.2.active_record.will_paginate +0 -7
- data/gemfiles/Gemfile.rails-4.2.mongoid +0 -6
- data/gemfiles/Gemfile.rails-4.2.mongoid.kaminari +0 -7
- data/gemfiles/Gemfile.rails-4.2.mongoid.will_paginate +0 -7
- data/spec/chewy/index/search_spec.rb +0 -46
@@ -16,6 +16,14 @@ describe Chewy::Type::Adapter::Mongoid, :mongoid do
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
describe '#default_scope' do
|
20
|
+
specify { expect(described_class.new(City).default_scope).to eq(City.all) }
|
21
|
+
specify { expect(described_class.new(City.order(:id.asc)).default_scope).to eq(City.all) }
|
22
|
+
specify { expect(described_class.new(City.limit(10)).default_scope).to eq(City.all) }
|
23
|
+
specify { expect(described_class.new(City.offset(10)).default_scope).to eq(City.all) }
|
24
|
+
specify { expect(described_class.new(City.where(rating: 10)).default_scope).to eq(City.where(rating: 10)) }
|
25
|
+
end
|
26
|
+
|
19
27
|
describe '#type_name' do
|
20
28
|
specify { expect(described_class.new(City).type_name).to eq('city') }
|
21
29
|
specify { expect(described_class.new(City.order(:id.asc)).type_name).to eq('city') }
|
@@ -29,6 +37,16 @@ describe Chewy::Type::Adapter::Mongoid, :mongoid do
|
|
29
37
|
end
|
30
38
|
end
|
31
39
|
|
40
|
+
describe '#identify' do
|
41
|
+
subject { described_class.new(City) }
|
42
|
+
let!(:cities) { 3.times.map { City.create! } }
|
43
|
+
|
44
|
+
specify { expect(subject.identify(City.all)).to match_array(cities.map(&:id)) }
|
45
|
+
specify { expect(subject.identify(cities)).to eq(cities.map(&:id)) }
|
46
|
+
specify { expect(subject.identify(cities.first)).to eq([cities.first.id]) }
|
47
|
+
specify { expect(subject.identify(cities.first(2).map(&:id))).to eq(cities.first(2).map(&:id)) }
|
48
|
+
end
|
49
|
+
|
32
50
|
describe '#import' do
|
33
51
|
def import(*args)
|
34
52
|
result = []
|
@@ -38,10 +56,11 @@ describe Chewy::Type::Adapter::Mongoid, :mongoid do
|
|
38
56
|
|
39
57
|
context do
|
40
58
|
let!(:cities) { 3.times.map { |i| City.create! }.sort_by(&:id) }
|
41
|
-
let!(:deleted) {
|
59
|
+
let!(:deleted) { 4.times.map { |i| City.create!.tap(&:destroy) }.sort_by(&:id) }
|
42
60
|
subject { described_class.new(City) }
|
43
61
|
|
44
62
|
specify { expect(import).to eq([{index: cities}]) }
|
63
|
+
specify { expect(import nil).to eq([]) }
|
45
64
|
|
46
65
|
specify { expect(import(City.order(:id.asc))).to eq([{index: cities}]) }
|
47
66
|
specify { expect(import(City.order(:id.asc), batch_size: 2))
|
@@ -50,11 +69,13 @@ describe Chewy::Type::Adapter::Mongoid, :mongoid do
|
|
50
69
|
specify { expect(import(cities)).to eq([{index: cities}]) }
|
51
70
|
specify { expect(import(cities, batch_size: 2))
|
52
71
|
.to eq([{index: cities.first(2)}, {index: cities.last(1)}]) }
|
53
|
-
specify { expect(import(cities, deleted))
|
72
|
+
specify { expect(import(cities, deleted))
|
73
|
+
.to eq([{index: cities}, {delete: deleted}]) }
|
54
74
|
specify { expect(import(cities, deleted, batch_size: 2)).to eq([
|
55
|
-
|
56
|
-
|
57
|
-
|
75
|
+
{index: cities.first(2)},
|
76
|
+
{index: cities.last(1)},
|
77
|
+
{delete: deleted.first(2)},
|
78
|
+
{delete: deleted.last(2)}]) }
|
58
79
|
|
59
80
|
specify { expect(import(cities.map(&:id))).to eq([{index: cities}]) }
|
60
81
|
specify { expect(import(deleted.map(&:id))).to eq([{delete: deleted.map(&:id)}]) }
|
@@ -66,127 +87,155 @@ describe Chewy::Type::Adapter::Mongoid, :mongoid do
|
|
66
87
|
{index: cities.first(2)},
|
67
88
|
{index: cities.last(1)},
|
68
89
|
{delete: deleted.first(2).map(&:id)},
|
69
|
-
{delete: deleted.last(
|
90
|
+
{delete: deleted.last(2).map(&:id)}]) }
|
70
91
|
|
71
92
|
specify { expect(import(cities.first, nil)).to eq([{index: [cities.first]}]) }
|
72
93
|
specify { expect(import(cities.first.id, nil)).to eq([{index: [cities.first]}]) }
|
94
|
+
end
|
73
95
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
96
|
+
context 'additional delete conitions' do
|
97
|
+
let!(:cities) { 4.times.map { |i| City.create! rating: i } }
|
98
|
+
before { cities.last(2).map(&:destroy) }
|
99
|
+
subject { described_class.new(City) }
|
78
100
|
|
79
101
|
context do
|
80
|
-
before
|
81
|
-
|
82
|
-
|
102
|
+
before do
|
103
|
+
City.class_eval do
|
104
|
+
def delete_from_index?
|
105
|
+
rating.in?([1, 3])
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
83
109
|
|
84
|
-
|
85
|
-
|
86
|
-
|
110
|
+
specify { expect(import(City.all)).to eq([
|
111
|
+
{ index: [cities[0]], delete: [cities[1]] }
|
112
|
+
]) }
|
113
|
+
specify { expect(import(cities)).to eq([
|
114
|
+
{ index: [cities[0]], delete: [cities[1]] },
|
115
|
+
{ delete: cities.last(2) }
|
116
|
+
]) }
|
117
|
+
specify { expect(import(cities.map(&:id))).to eq([
|
118
|
+
{ index: [cities[0]], delete: [cities[1]] },
|
119
|
+
{ delete: cities.last(2).map(&:id) }
|
120
|
+
]) }
|
87
121
|
end
|
88
122
|
|
89
123
|
context do
|
90
|
-
before
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
describe '#delete_from_index?' do
|
96
|
-
before do
|
97
|
-
stub_model(:city) do
|
98
|
-
def delete_from_index?
|
99
|
-
rating == 42
|
124
|
+
before do
|
125
|
+
City.class_eval do
|
126
|
+
def delete_already?
|
127
|
+
rating.in?([1, 3])
|
128
|
+
end
|
100
129
|
end
|
101
130
|
end
|
131
|
+
subject { described_class.new(City, delete_if: ->{ delete_already? }) }
|
132
|
+
|
133
|
+
specify { expect(import(City.all)).to eq([
|
134
|
+
{ index: [cities[0]], delete: [cities[1]] }
|
135
|
+
]) }
|
136
|
+
specify { expect(import(cities)).to eq([
|
137
|
+
{ index: [cities[0]], delete: [cities[1]] },
|
138
|
+
{ delete: cities.last(2) }
|
139
|
+
]) }
|
140
|
+
specify { expect(import(cities.map(&:id))).to eq([
|
141
|
+
{ index: [cities[0]], delete: [cities[1]] },
|
142
|
+
{ delete: cities.last(2).map(&:id) }
|
143
|
+
]) }
|
102
144
|
end
|
103
|
-
let!(:cities) { 3.times.map { |i| City.create! }.sort_by(&:id) }
|
104
|
-
let!(:deleted) { 3.times.map { |i| City.create!(rating: 42) }.sort_by(&:id) }
|
105
|
-
subject { described_class.new(City) }
|
106
|
-
|
107
|
-
specify { expect(import(cities, deleted)).to eq([{index: cities, delete: deleted}]) }
|
108
|
-
specify { expect(import(cities.map(&:id), deleted.map(&:id)))
|
109
|
-
.to eq([{index: cities, delete: deleted}]) }
|
110
|
-
specify { expect(import(City.order(:id.asc))).to eq([{index: cities, delete: deleted}]) }
|
111
145
|
end
|
112
146
|
|
113
147
|
context 'default scope' do
|
114
|
-
let!(:cities) {
|
115
|
-
let!(:deleted) {
|
148
|
+
let!(:cities) { 4.times.map { |i| City.create!(rating: i/3) }.sort_by(&:id) }
|
149
|
+
let!(:deleted) { 3.times.map { |i| City.create!.tap(&:destroy) }.sort_by(&:id) }
|
116
150
|
subject { described_class.new(City.where(rating: 0)) }
|
117
151
|
|
118
|
-
specify { expect(import).to eq([{index: cities.first(
|
152
|
+
specify { expect(import).to eq([{index: cities.first(3)}]) }
|
119
153
|
|
120
|
-
specify { expect(import(City.
|
121
|
-
|
122
|
-
|
154
|
+
specify { expect(import(City.where(:rating.lt => 2).order(:id.asc)))
|
155
|
+
.to eq([{index: cities.first(3)}]) }
|
156
|
+
specify { expect(import(City.where(:rating.lt => 2).order(:id.asc), batch_size: 2))
|
157
|
+
.to eq([{index: cities.first(2)}, {index: [cities[2]]}]) }
|
158
|
+
specify { expect(import(City.where(:rating.lt => 1).order(:id.asc)))
|
159
|
+
.to eq([{index: cities.first(3)}]) }
|
160
|
+
specify { expect(import(City.where(:rating.gt => 1).order(:id.asc))).to eq([]) }
|
123
161
|
|
124
|
-
specify { expect(import(cities
|
162
|
+
specify { expect(import(cities.first(2)))
|
163
|
+
.to eq([{index: cities.first(2)}]) }
|
164
|
+
specify { expect(import(cities))
|
165
|
+
.to eq([{index: cities.first(3)}, {delete: cities.last(1)}]) }
|
125
166
|
specify { expect(import(cities, batch_size: 2))
|
126
|
-
.to eq([{index: cities.first(2)}, {index: cities.last(1)}]) }
|
127
|
-
|
167
|
+
.to eq([{index: cities.first(2)}, {index: [cities[2]]}, {delete: cities.last(1)}]) }
|
168
|
+
specify { expect(import(cities, deleted))
|
169
|
+
.to eq([{index: cities.first(3)}, {delete: cities.last(1) + deleted}]) }
|
170
|
+
specify { expect(import(cities, deleted, batch_size: 3)).to eq([
|
171
|
+
{index: cities.first(3)},
|
172
|
+
{delete: cities.last(1) + deleted.first(2)},
|
173
|
+
{delete: deleted.last(1)}]) }
|
174
|
+
|
175
|
+
specify { expect(import(cities.first(2).map(&:id)))
|
176
|
+
.to eq([{index: cities.first(2)}]) }
|
128
177
|
specify { expect(import(cities.map(&:id)))
|
129
|
-
.to eq([{index: cities.first(
|
130
|
-
|
131
|
-
.to eq([{index:
|
178
|
+
.to eq([{index: cities.first(3)}, {delete: [cities.last.id]}]) }
|
179
|
+
specify { expect(import(cities.map(&:id), batch_size: 2))
|
180
|
+
.to eq([{index: cities.first(2)}, {index: [cities[2]]}, {delete: [cities.last.id]}]) }
|
132
181
|
specify { expect(import(cities.map(&:id), deleted.map(&:id)))
|
133
|
-
.to eq([{index: cities.first(
|
134
|
-
specify { expect(import(cities.map(&:id), deleted.map(&:id), batch_size:
|
135
|
-
{index: cities.first(
|
136
|
-
{delete: [cities.last.id] + deleted.first(
|
182
|
+
.to eq([{index: cities.first(3)}, {delete: [cities.last.id] + deleted.map(&:id)}]) }
|
183
|
+
specify { expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 3)).to eq([
|
184
|
+
{index: cities.first(3)},
|
185
|
+
{delete: [cities.last.id] + deleted.first(2).map(&:id)},
|
137
186
|
{delete: deleted.last(1).map(&:id)}]) }
|
138
187
|
end
|
139
188
|
|
140
189
|
context 'error handling' do
|
141
|
-
let!(:cities) { 6.times.map { |i| City.create! }
|
142
|
-
let!(:deleted) { 4.times.map { |i| City.create!.tap(&:destroy) }
|
190
|
+
let!(:cities) { 6.times.map { |i| City.create! } }
|
191
|
+
let!(:deleted) { 4.times.map { |i| City.create!.tap(&:destroy) } }
|
143
192
|
let(:ids) { (cities + deleted).map(&:id) }
|
144
193
|
subject { described_class.new(City) }
|
145
194
|
|
146
195
|
let(:data_comparer) do
|
147
|
-
->(
|
196
|
+
->(id, data) { objects = data[:index] || data[:delete]; !objects.map { |o| o.respond_to?(:id) ? o.id : o }.include?(id) }
|
148
197
|
end
|
149
198
|
|
150
199
|
context 'implicit scope' do
|
151
200
|
specify { expect(subject.import { |data| true }).to eq(true) }
|
152
201
|
specify { expect(subject.import { |data| false }).to eq(false) }
|
153
|
-
specify { expect(subject.import(batch_size: 2, &data_comparer.curry[cities[0
|
154
|
-
specify { expect(subject.import(batch_size: 2, &data_comparer.curry[cities[2
|
155
|
-
specify { expect(subject.import(batch_size: 2, &data_comparer.curry[cities[4
|
156
|
-
specify { expect(subject.import(batch_size: 2, &data_comparer.curry[deleted[0
|
157
|
-
specify { expect(subject.import(batch_size: 2, &data_comparer.curry[deleted[2
|
202
|
+
specify { expect(subject.import(batch_size: 2, &data_comparer.curry[cities[0].id])).to eq(false) }
|
203
|
+
specify { expect(subject.import(batch_size: 2, &data_comparer.curry[cities[2].id])).to eq(false) }
|
204
|
+
specify { expect(subject.import(batch_size: 2, &data_comparer.curry[cities[4].id])).to eq(false) }
|
205
|
+
specify { expect(subject.import(batch_size: 2, &data_comparer.curry[deleted[0].id])).to eq(true) }
|
206
|
+
specify { expect(subject.import(batch_size: 2, &data_comparer.curry[deleted[2].id])).to eq(true) }
|
158
207
|
end
|
159
208
|
|
160
209
|
context 'explicit scope' do
|
161
|
-
let(:scope) {
|
210
|
+
let(:scope) { City.where(:id.in => ids) }
|
162
211
|
|
163
212
|
specify { expect(subject.import(scope) { |data| true }).to eq(true) }
|
164
213
|
specify { expect(subject.import(scope) { |data| false }).to eq(false) }
|
165
|
-
specify { expect(subject.import(scope, batch_size: 2, &data_comparer.curry[cities[0
|
166
|
-
specify { expect(subject.import(scope, batch_size: 2, &data_comparer.curry[cities[2
|
167
|
-
specify { expect(subject.import(scope, batch_size: 2, &data_comparer.curry[cities[4
|
168
|
-
specify { expect(subject.import(scope, batch_size: 2, &data_comparer.curry[deleted[0
|
169
|
-
specify { expect(subject.import(scope, batch_size: 2, &data_comparer.curry[deleted[2
|
214
|
+
specify { expect(subject.import(scope, batch_size: 2, &data_comparer.curry[cities[0].id])).to eq(false) }
|
215
|
+
specify { expect(subject.import(scope, batch_size: 2, &data_comparer.curry[cities[2].id])).to eq(false) }
|
216
|
+
specify { expect(subject.import(scope, batch_size: 2, &data_comparer.curry[cities[4].id])).to eq(false) }
|
217
|
+
specify { expect(subject.import(scope, batch_size: 2, &data_comparer.curry[deleted[0].id])).to eq(true) }
|
218
|
+
specify { expect(subject.import(scope, batch_size: 2, &data_comparer.curry[deleted[2].id])).to eq(true) }
|
170
219
|
end
|
171
220
|
|
172
221
|
context 'objects' do
|
173
222
|
specify { expect(subject.import(cities + deleted) { |data| true }).to eq(true) }
|
174
223
|
specify { expect(subject.import(cities + deleted) { |data| false }).to eq(false) }
|
175
|
-
specify { expect(subject.import(cities + deleted, batch_size: 2, &data_comparer.curry[cities[0
|
176
|
-
specify { expect(subject.import(cities + deleted, batch_size: 2, &data_comparer.curry[cities[2
|
177
|
-
specify { expect(subject.import(cities + deleted, batch_size: 2, &data_comparer.curry[cities[4
|
178
|
-
specify { expect(subject.import(cities + deleted, batch_size: 2, &data_comparer.curry[deleted[0
|
179
|
-
specify { expect(subject.import(cities + deleted, batch_size: 2, &data_comparer.curry[deleted[2
|
224
|
+
specify { expect(subject.import(cities + deleted, batch_size: 2, &data_comparer.curry[cities[0].id])).to eq(false) }
|
225
|
+
specify { expect(subject.import(cities + deleted, batch_size: 2, &data_comparer.curry[cities[2].id])).to eq(false) }
|
226
|
+
specify { expect(subject.import(cities + deleted, batch_size: 2, &data_comparer.curry[cities[4].id])).to eq(false) }
|
227
|
+
specify { expect(subject.import(cities + deleted, batch_size: 2, &data_comparer.curry[deleted[0].id])).to eq(false) }
|
228
|
+
specify { expect(subject.import(cities + deleted, batch_size: 2, &data_comparer.curry[deleted[2].id])).to eq(false) }
|
180
229
|
end
|
181
230
|
|
182
231
|
context 'ids' do
|
183
232
|
specify { expect(subject.import(ids) { |data| true }).to eq(true) }
|
184
233
|
specify { expect(subject.import(ids) { |data| false }).to eq(false) }
|
185
|
-
specify { expect(subject.import(ids, batch_size: 2, &data_comparer.curry[cities[0
|
186
|
-
specify { expect(subject.import(ids, batch_size: 2, &data_comparer.curry[cities[2
|
187
|
-
specify { expect(subject.import(ids, batch_size: 2, &data_comparer.curry[cities[4
|
188
|
-
specify { expect(subject.import(ids, batch_size: 2, &data_comparer.curry[deleted[0
|
189
|
-
specify { expect(subject.import(ids, batch_size: 2, &data_comparer.curry[deleted[2
|
234
|
+
specify { expect(subject.import(ids, batch_size: 2, &data_comparer.curry[cities[0].id])).to eq(false) }
|
235
|
+
specify { expect(subject.import(ids, batch_size: 2, &data_comparer.curry[cities[2].id])).to eq(false) }
|
236
|
+
specify { expect(subject.import(ids, batch_size: 2, &data_comparer.curry[cities[4].id])).to eq(false) }
|
237
|
+
specify { expect(subject.import(ids, batch_size: 2, &data_comparer.curry[deleted[0].id])).to eq(false) }
|
238
|
+
specify { expect(subject.import(ids, batch_size: 2, &data_comparer.curry[deleted[2].id])).to eq(false) }
|
190
239
|
end
|
191
240
|
end
|
192
241
|
end
|
@@ -29,6 +29,13 @@ describe Chewy::Type::Adapter::Object do
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
+
describe '#identify' do
|
33
|
+
let!(:objects) { 3.times.map { double } }
|
34
|
+
|
35
|
+
specify { expect(subject.identify(objects)).to eq(objects) }
|
36
|
+
specify { expect(subject.identify(objects.first)).to eq([objects.first]) }
|
37
|
+
end
|
38
|
+
|
32
39
|
describe '#import' do
|
33
40
|
def import(*args)
|
34
41
|
result = []
|
@@ -45,6 +52,8 @@ describe Chewy::Type::Adapter::Object do
|
|
45
52
|
subject { described_class.new('product') }
|
46
53
|
|
47
54
|
specify { expect(import).to eq([]) }
|
55
|
+
specify { expect(import nil).to eq([]) }
|
56
|
+
|
48
57
|
specify { expect(import(objects)).to eq([{index: objects}]) }
|
49
58
|
specify { expect(import(objects, batch_size: 2))
|
50
59
|
.to eq([{index: objects.first(2)}, {index: objects.last(1)}]) }
|
@@ -56,39 +65,45 @@ describe Chewy::Type::Adapter::Object do
|
|
56
65
|
|
57
66
|
specify { expect(import(objects.first, nil)).to eq([{index: [objects.first]}]) }
|
58
67
|
|
59
|
-
context do
|
60
|
-
|
61
|
-
specify { expect(import(deleted)).to eq([{delete: deleted}]) }
|
62
|
-
end
|
68
|
+
context 'initial data' do
|
69
|
+
subject { described_class.new ->{ objects } }
|
63
70
|
|
64
|
-
|
65
|
-
|
66
|
-
specify { expect(import(deleted)).to eq([{delete: deleted}]) }
|
67
|
-
end
|
71
|
+
specify { expect(import).to eq([{index: objects}]) }
|
72
|
+
specify { expect(import nil).to eq([]) }
|
68
73
|
|
74
|
+
specify { expect(import(objects[0..1])).to eq([{index: objects[0..1]}]) }
|
75
|
+
specify { expect(import(batch_size: 2))
|
76
|
+
.to eq([{index: objects.first(2)}, {index: objects.last(1)}]) }
|
77
|
+
end
|
69
78
|
|
70
79
|
context do
|
71
|
-
let(:deleted) {
|
72
|
-
|
80
|
+
let(:deleted) { [
|
81
|
+
double(delete_from_index?: true, destroyed?: true),
|
82
|
+
double(delete_from_index?: true, destroyed?: false),
|
83
|
+
double(delete_from_index?: false, destroyed?: true),
|
84
|
+
double(delete_from_index?: false, destroyed?: false)
|
85
|
+
] }
|
86
|
+
|
87
|
+
specify { expect(import(deleted)).to eq([
|
88
|
+
{ delete: deleted[0..2], index: deleted.last(1) }
|
89
|
+
]) }
|
73
90
|
end
|
74
91
|
|
75
92
|
context do
|
76
|
-
|
77
|
-
|
93
|
+
subject { described_class.new('product', delete_if: :delete?) }
|
94
|
+
let(:deleted) { [
|
95
|
+
double(delete?: true, destroyed?: true),
|
96
|
+
double(delete?: true, destroyed?: false),
|
97
|
+
double(delete?: false, destroyed?: true),
|
98
|
+
double(delete?: false, destroyed?: false)
|
99
|
+
] }
|
100
|
+
|
101
|
+
specify { expect(import(deleted)).to eq([
|
102
|
+
{ delete: deleted[0..2], index: deleted.last(1) }
|
103
|
+
]) }
|
78
104
|
end
|
79
105
|
end
|
80
106
|
|
81
|
-
context do
|
82
|
-
let(:products) { 3.times.map { |i| double.tap { |product|
|
83
|
-
allow(product).to receive(:is_a?).with(Product).and_return(true)
|
84
|
-
} } }
|
85
|
-
let(:non_product) { double }
|
86
|
-
subject { described_class.new(Product) }
|
87
|
-
|
88
|
-
specify { expect(import(products)).to eq([{index: products}]) }
|
89
|
-
specify { expect { import(products, non_product) {} }.to raise_error }
|
90
|
-
end
|
91
|
-
|
92
107
|
context 'error handling' do
|
93
108
|
let(:products) { 3.times.map { |i| double.tap { |product| allow(product).to receive_messages(rating: i.next) } } }
|
94
109
|
let(:deleted) { 2.times.map { |i| double(destroyed?: true, rating: i + 4) } }
|
@@ -116,20 +131,22 @@ describe Chewy::Type::Adapter::Object do
|
|
116
131
|
specify { expect(subject.load(objects)).to eq(objects) }
|
117
132
|
end
|
118
133
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
134
|
+
[:wrap, :load_one].each do |load_method|
|
135
|
+
context do
|
136
|
+
before { allow(Product).to receive(load_method) { |object| allow(object).to receive_messages(wrapped?: true); object } }
|
137
|
+
subject { described_class.new(Product) }
|
138
|
+
let(:objects) { 3.times.map { |i| double(wrapped?: false) } }
|
123
139
|
|
124
|
-
|
125
|
-
|
140
|
+
specify { expect(subject.load(objects)).to satisfy { |objects| objects.all?(&:wrapped?) } }
|
141
|
+
end
|
126
142
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
143
|
+
context do
|
144
|
+
before { allow(Product).to receive(load_method) { |object| nil } }
|
145
|
+
subject { described_class.new(Product) }
|
146
|
+
let(:objects) { 3.times.map { |i| double(wrapped?: false) } }
|
131
147
|
|
132
|
-
|
148
|
+
specify { expect(subject.load(objects)).to satisfy { |objects| objects.all?(&:nil?) } }
|
149
|
+
end
|
133
150
|
end
|
134
151
|
end
|
135
152
|
end
|
@@ -58,15 +58,15 @@ describe Chewy::Type::Import do
|
|
58
58
|
specify do
|
59
59
|
dummy_cities.first.destroy
|
60
60
|
|
61
|
-
|
62
|
-
|
63
|
-
))
|
64
|
-
|
65
|
-
expect(CitiesIndex.client).to receive(:bulk).with(hash_including(
|
66
|
-
body: [{index: {_id: 2, data: {'name' => "name1"}}}, {index: {_id: 3, data: {'name' => "name2"}}}]
|
67
|
-
))
|
61
|
+
imported = []
|
62
|
+
allow(CitiesIndex.client).to receive(:bulk) { |params| imported << params[:body]; nil }
|
68
63
|
|
69
64
|
city.import dummy_cities.map(&:id), batch_size: 2
|
65
|
+
expect(imported.flatten).to match_array([
|
66
|
+
{index: {_id: 2, data: {'name' => 'name1'}}},
|
67
|
+
{index: {_id: 3, data: {'name' => 'name2'}}},
|
68
|
+
{delete: {_id: dummy_cities.first.id}}
|
69
|
+
])
|
70
70
|
end
|
71
71
|
|
72
72
|
specify do
|
@@ -130,7 +130,7 @@ describe Chewy::Type::Import do
|
|
130
130
|
end
|
131
131
|
|
132
132
|
dummy_cities.first.destroy
|
133
|
-
city.import dummy_cities, batch_size:
|
133
|
+
city.import dummy_cities, batch_size: 2
|
134
134
|
expect(outer_payload).to eq({type: CitiesIndex::City, import: {delete: 1, index: 2}})
|
135
135
|
end
|
136
136
|
|
@@ -140,7 +140,7 @@ describe Chewy::Type::Import do
|
|
140
140
|
outer_payload = payload
|
141
141
|
end
|
142
142
|
|
143
|
-
city.import dummy_cities, batch_size:
|
143
|
+
city.import dummy_cities, batch_size: 2
|
144
144
|
expect(outer_payload).to eq({type: CitiesIndex::City, import: {index: 3}})
|
145
145
|
end
|
146
146
|
|
@@ -159,12 +159,12 @@ describe Chewy::Type::Import do
|
|
159
159
|
outer_payload = payload
|
160
160
|
end
|
161
161
|
|
162
|
-
city.import dummy_cities, batch_size:
|
162
|
+
city.import dummy_cities, batch_size: 2
|
163
163
|
expect(outer_payload).to eq({
|
164
164
|
type: CitiesIndex::City,
|
165
165
|
errors: {
|
166
166
|
index: {
|
167
|
-
'MapperParsingException[object mapping for [city] tried to parse as object, but got EOF, has a concrete value been provided to it?]' => ['1', '2', '3']
|
167
|
+
'MapperParsingException[object mapping for [city] tried to parse field [name] as object, but got EOF, has a concrete value been provided to it?]' => ['1', '2', '3']
|
168
168
|
}
|
169
169
|
},
|
170
170
|
import: {index: 3}
|
@@ -199,7 +199,7 @@ describe Chewy::Type::Import do
|
|
199
199
|
|
200
200
|
specify { expect(city.import(dummy_cities)).to eq(false) }
|
201
201
|
specify { expect(city.import(dummy_cities.map(&:id))).to eq(false) }
|
202
|
-
specify { expect(city.import(dummy_cities, batch_size:
|
202
|
+
specify { expect(city.import(dummy_cities, batch_size: 2)).to eq(false) }
|
203
203
|
end
|
204
204
|
end
|
205
205
|
|
@@ -209,7 +209,7 @@ describe Chewy::Type::Import do
|
|
209
209
|
|
210
210
|
before do
|
211
211
|
stub_model(:country)
|
212
|
-
stub_model(:city)
|
212
|
+
stub_model(:city) { belongs_to :country }
|
213
213
|
end
|
214
214
|
|
215
215
|
before do
|
@@ -279,15 +279,15 @@ describe Chewy::Type::Import do
|
|
279
279
|
end
|
280
280
|
end
|
281
281
|
end
|
282
|
-
|
282
|
+
|
283
283
|
context 'root id', :orm do
|
284
284
|
let(:canada) { Country.create(id: 1, name: 'Canada', country_code: 'CA', rating: 4) }
|
285
285
|
let(:country) { CountriesIndex::Country }
|
286
|
-
|
286
|
+
|
287
287
|
before do
|
288
288
|
stub_model(:country)
|
289
289
|
end
|
290
|
-
|
290
|
+
|
291
291
|
before do
|
292
292
|
stub_index(:countries) do
|
293
293
|
define_type Country do
|
@@ -298,8 +298,8 @@ describe Chewy::Type::Import do
|
|
298
298
|
end
|
299
299
|
end
|
300
300
|
end
|
301
|
-
|
302
|
-
specify { expect(
|
301
|
+
|
302
|
+
specify { expect(country.import(canada)).to eq(true) }
|
303
303
|
specify { expect { country.import(canada) }.to update_index(country).and_reindex(canada.country_code) }
|
304
304
|
|
305
305
|
specify do
|
@@ -309,7 +309,7 @@ describe Chewy::Type::Import do
|
|
309
309
|
|
310
310
|
country.import canada
|
311
311
|
end
|
312
|
-
|
312
|
+
|
313
313
|
specify do
|
314
314
|
canada.update_attributes(rating: 9)
|
315
315
|
|
@@ -319,7 +319,7 @@ describe Chewy::Type::Import do
|
|
319
319
|
|
320
320
|
country.import canada
|
321
321
|
end
|
322
|
-
|
322
|
+
|
323
323
|
specify do
|
324
324
|
canada.destroy
|
325
325
|
|
@@ -329,7 +329,7 @@ describe Chewy::Type::Import do
|
|
329
329
|
|
330
330
|
country.import canada
|
331
331
|
end
|
332
|
-
|
332
|
+
|
333
333
|
end # END root id
|
334
334
|
end
|
335
335
|
|