chewy 0.5.2 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +26 -4
- data/CHANGELOG.md +16 -0
- data/Gemfile +3 -1
- data/README.md +2 -10
- data/chewy.gemspec +0 -1
- data/gemfiles/Gemfile.rails-3.2.active_record +6 -0
- data/gemfiles/Gemfile.rails-3.2.active_record.kaminari +7 -0
- data/gemfiles/Gemfile.rails-3.2.active_record.will_paginate +7 -0
- data/gemfiles/Gemfile.rails-4.0.active_record +6 -0
- data/gemfiles/Gemfile.rails-4.0.active_record.kaminari +7 -0
- data/gemfiles/Gemfile.rails-4.0.active_record.will_paginate +7 -0
- data/gemfiles/Gemfile.rails-4.0.mongoid +6 -0
- data/gemfiles/Gemfile.rails-4.0.mongoid.kaminari +7 -0
- data/gemfiles/Gemfile.rails-4.0.mongoid.will_paginate +7 -0
- data/gemfiles/Gemfile.rails-4.1.active_record +6 -0
- data/gemfiles/Gemfile.rails-4.1.active_record.kaminari +7 -0
- data/gemfiles/Gemfile.rails-4.1.active_record.will_paginate +7 -0
- data/gemfiles/Gemfile.rails-4.1.mongoid +6 -0
- data/gemfiles/Gemfile.rails-4.1.mongoid.kaminari +7 -0
- data/gemfiles/Gemfile.rails-4.1.mongoid.will_paginate +7 -0
- data/gemfiles/Gemfile.rails-4.2.active_record +6 -0
- data/gemfiles/Gemfile.rails-4.2.active_record.kaminari +7 -0
- data/gemfiles/Gemfile.rails-4.2.active_record.will_paginate +7 -0
- data/gemfiles/Gemfile.rails-4.2.mongoid +6 -0
- data/gemfiles/Gemfile.rails-4.2.mongoid.kaminari +7 -0
- data/gemfiles/Gemfile.rails-4.2.mongoid.will_paginate +7 -0
- data/lib/chewy.rb +33 -5
- data/lib/chewy/config.rb +1 -0
- data/lib/chewy/index/search.rb +6 -3
- data/lib/chewy/query.rb +74 -1
- data/lib/chewy/query/compose.rb +4 -4
- data/lib/chewy/query/pagination.rb +5 -4
- data/lib/chewy/query/pagination/kaminari.rb +1 -1
- data/lib/chewy/query/pagination/will_paginate.rb +27 -0
- data/lib/chewy/type.rb +1 -0
- data/lib/chewy/type/adapter/active_record.rb +2 -2
- data/lib/chewy/type/adapter/mongoid.rb +147 -0
- data/lib/chewy/type/adapter/object.rb +1 -1
- data/lib/chewy/type/import.rb +1 -0
- data/lib/chewy/type/observe.rb +34 -6
- data/lib/chewy/version.rb +1 -1
- data/spec/chewy/config_spec.rb +17 -17
- data/spec/chewy/fields/base_spec.rb +62 -62
- data/spec/chewy/fields/root_spec.rb +5 -5
- data/spec/chewy/index/actions_spec.rb +127 -127
- data/spec/chewy/index/aliases_spec.rb +9 -9
- data/spec/chewy/index/search_spec.rb +4 -4
- data/spec/chewy/index/settings_spec.rb +33 -33
- data/spec/chewy/index_spec.rb +49 -49
- data/spec/chewy/query/criteria_spec.rb +173 -161
- data/spec/chewy/query/filters_spec.rb +76 -76
- data/spec/chewy/query/loading_spec.rb +54 -23
- data/spec/chewy/query/nodes/and_spec.rb +4 -4
- data/spec/chewy/query/nodes/bool_spec.rb +8 -8
- data/spec/chewy/query/nodes/equal_spec.rb +19 -19
- data/spec/chewy/query/nodes/exists_spec.rb +6 -6
- data/spec/chewy/query/nodes/has_child_spec.rb +25 -25
- data/spec/chewy/query/nodes/has_parent_spec.rb +25 -25
- data/spec/chewy/query/nodes/match_all_spec.rb +1 -1
- data/spec/chewy/query/nodes/missing_spec.rb +4 -4
- data/spec/chewy/query/nodes/not_spec.rb +4 -4
- data/spec/chewy/query/nodes/or_spec.rb +4 -4
- data/spec/chewy/query/nodes/prefix_spec.rb +5 -5
- data/spec/chewy/query/nodes/query_spec.rb +2 -2
- data/spec/chewy/query/nodes/range_spec.rb +18 -18
- data/spec/chewy/query/nodes/raw_spec.rb +1 -1
- data/spec/chewy/query/nodes/regexp_spec.rb +18 -18
- data/spec/chewy/query/nodes/script_spec.rb +4 -4
- data/spec/chewy/query/pagination/kaminari_spec.rb +41 -39
- data/spec/chewy/query/pagination/will_paginage_spec.rb +60 -0
- data/spec/chewy/query/pagination_spec.rb +8 -7
- data/spec/chewy/query_spec.rb +166 -167
- data/spec/chewy/rspec/update_index_spec.rb +1 -1
- data/spec/chewy/runtime/version_spec.rb +30 -30
- data/spec/chewy/runtime_spec.rb +3 -3
- data/spec/chewy/type/actions_spec.rb +3 -3
- data/spec/chewy/type/adapter/active_record_spec.rb +143 -143
- data/spec/chewy/type/adapter/mongoid_spec.rb +219 -0
- data/spec/chewy/type/adapter/object_spec.rb +39 -39
- data/spec/chewy/type/import_spec.rb +67 -37
- data/spec/chewy/type/mapping_spec.rb +12 -12
- data/spec/chewy/type/observe_spec.rb +5 -6
- data/spec/chewy/type/wrapper_spec.rb +12 -12
- data/spec/chewy_spec.rb +26 -28
- data/spec/spec_helper.rb +19 -31
- data/spec/support/active_record.rb +52 -0
- data/spec/support/class_helpers.rb +0 -4
- data/spec/support/mongoid.rb +87 -0
- metadata +33 -18
- data/gemfiles/Gemfile.rails-3.2 +0 -15
- data/gemfiles/Gemfile.rails-4.0 +0 -15
@@ -0,0 +1,219 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Chewy::Type::Adapter::Mongoid, :mongoid do
|
4
|
+
before { stub_model(:city) }
|
5
|
+
|
6
|
+
describe '#name' do
|
7
|
+
specify { expect(described_class.new(City).name).to eq('City') }
|
8
|
+
specify { expect(described_class.new(City.order(:id.asc)).name).to eq('City') }
|
9
|
+
specify { expect(described_class.new(City, name: 'town').name).to eq('Town') }
|
10
|
+
|
11
|
+
context do
|
12
|
+
before { stub_model('namespace/city') }
|
13
|
+
|
14
|
+
specify { expect(described_class.new(Namespace::City).name).to eq('City') }
|
15
|
+
specify { expect(described_class.new(Namespace::City.order(:id.asc)).name).to eq('City') }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#type_name' do
|
20
|
+
specify { expect(described_class.new(City).type_name).to eq('city') }
|
21
|
+
specify { expect(described_class.new(City.order(:id.asc)).type_name).to eq('city') }
|
22
|
+
specify { expect(described_class.new(City, name: 'town').type_name).to eq('town') }
|
23
|
+
|
24
|
+
context do
|
25
|
+
before { stub_model('namespace/city') }
|
26
|
+
|
27
|
+
specify { expect(described_class.new(Namespace::City).type_name).to eq('city') }
|
28
|
+
specify { expect(described_class.new(Namespace::City.order(:id.asc)).type_name).to eq('city') }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#import' do
|
33
|
+
def import(*args)
|
34
|
+
result = []
|
35
|
+
subject.import(*args) { |data| result.push data }
|
36
|
+
result
|
37
|
+
end
|
38
|
+
|
39
|
+
context do
|
40
|
+
let!(:cities) { 3.times.map { |i| City.create! }.sort_by(&:id) }
|
41
|
+
let!(:deleted) { 3.times.map { |i| City.create!.tap(&:destroy) }.sort_by(&:id) }
|
42
|
+
subject { described_class.new(City) }
|
43
|
+
|
44
|
+
specify { expect(import).to eq([{index: cities}]) }
|
45
|
+
|
46
|
+
specify { expect(import(City.order(:id.asc))).to eq([{index: cities}]) }
|
47
|
+
specify { expect(import(City.order(:id.asc), batch_size: 2))
|
48
|
+
.to eq([{index: cities.first(2)}, {index: cities.last(1)}]) }
|
49
|
+
|
50
|
+
specify { expect(import(cities)).to eq([{index: cities}]) }
|
51
|
+
specify { expect(import(cities, batch_size: 2))
|
52
|
+
.to eq([{index: cities.first(2)}, {index: cities.last(1)}]) }
|
53
|
+
specify { expect(import(cities, deleted)).to eq([{index: cities, delete: deleted}]) }
|
54
|
+
specify { expect(import(cities, deleted, batch_size: 2)).to eq([
|
55
|
+
{index: cities.first(2)},
|
56
|
+
{index: cities.last(1), delete: deleted.first(1)},
|
57
|
+
{delete: deleted.last(2)}]) }
|
58
|
+
|
59
|
+
specify { expect(import(cities.map(&:id))).to eq([{index: cities}]) }
|
60
|
+
specify { expect(import(deleted.map(&:id))).to eq([{delete: deleted.map(&:id)}]) }
|
61
|
+
specify { expect(import(cities.map(&:id), batch_size: 2))
|
62
|
+
.to eq([{index: cities.first(2)}, {index: cities.last(1)}]) }
|
63
|
+
specify { expect(import(cities.map(&:id), deleted.map(&:id)))
|
64
|
+
.to eq([{index: cities}, {delete: deleted.map(&:id)}]) }
|
65
|
+
specify { expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 2)).to eq([
|
66
|
+
{index: cities.first(2)},
|
67
|
+
{index: cities.last(1)},
|
68
|
+
{delete: deleted.first(2).map(&:id)},
|
69
|
+
{delete: deleted.last(1).map(&:id)}]) }
|
70
|
+
|
71
|
+
specify { expect(import(cities.first, nil)).to eq([{index: [cities.first]}]) }
|
72
|
+
specify { expect(import(cities.first.id, nil)).to eq([{index: [cities.first]}]) }
|
73
|
+
|
74
|
+
context do
|
75
|
+
before { deleted.map { |object| allow(object).to receive_messages(delete_from_index?: true, destroyed?: true) } }
|
76
|
+
specify { expect(import(deleted)).to eq([{delete: deleted}]) }
|
77
|
+
end
|
78
|
+
|
79
|
+
context do
|
80
|
+
before { deleted.map { |object| allow(object).to receive_messages(delete_from_index?: true, destroyed?: false) } }
|
81
|
+
specify { expect(import(deleted)).to eq([{delete: deleted}]) }
|
82
|
+
end
|
83
|
+
|
84
|
+
context do
|
85
|
+
before { deleted.map { |object| allow(object).to receive_messages(delete_from_index?: false, destroyed?: true) } }
|
86
|
+
specify { expect(import(deleted)).to eq([{delete: deleted}]) }
|
87
|
+
end
|
88
|
+
|
89
|
+
context do
|
90
|
+
before { deleted.map { |object| allow(object).to receive_messages(delete_from_index?: false, destroyed?: false) } }
|
91
|
+
specify { expect(import(deleted)).to eq([{index: deleted}]) }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe '#delete_from_index?' do
|
96
|
+
before do
|
97
|
+
stub_model(:city) do
|
98
|
+
def delete_from_index?
|
99
|
+
rating == 42
|
100
|
+
end
|
101
|
+
end
|
102
|
+
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
|
+
end
|
112
|
+
|
113
|
+
context 'default scope' do
|
114
|
+
let!(:cities) { 3.times.map { |i| City.create!(rating: i/2) }.sort_by(&:id) }
|
115
|
+
let!(:deleted) { 2.times.map { |i| City.create!.tap(&:destroy) }.sort_by(&:id) }
|
116
|
+
subject { described_class.new(City.where(rating: 0)) }
|
117
|
+
|
118
|
+
specify { expect(import).to eq([{index: cities.first(2)}]) }
|
119
|
+
|
120
|
+
specify { expect(import(City.order(:id.asc))).to eq([{index: cities.first(2)}]) }
|
121
|
+
xspecify { expect(import(City.order(:id.asc), batch_size: 1))
|
122
|
+
.to eq([{index: [cities.first]}, {index: [cities.second]}]) }
|
123
|
+
|
124
|
+
specify { expect(import(cities)).to eq([{index: cities}]) }
|
125
|
+
specify { expect(import(cities, batch_size: 2))
|
126
|
+
.to eq([{index: cities.first(2)}, {index: cities.last(1)}]) }
|
127
|
+
|
128
|
+
specify { expect(import(cities.map(&:id)))
|
129
|
+
.to eq([{index: cities.first(2)}, {delete: [cities.last.id]}]) }
|
130
|
+
xspecify { expect(import(cities.map(&:id), batch_size: 1))
|
131
|
+
.to eq([{index: [cities.first]}, {index: [cities.second]}, {delete: [cities.last.id]}]) }
|
132
|
+
specify { expect(import(cities.map(&:id), deleted.map(&:id)))
|
133
|
+
.to eq([{index: cities.first(2)}, {delete: [cities.last.id] + deleted.map(&:id)}]) }
|
134
|
+
specify { expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 2)).to eq([
|
135
|
+
{index: cities.first(2)},
|
136
|
+
{delete: [cities.last.id] + deleted.first(1).map(&:id)},
|
137
|
+
{delete: deleted.last(1).map(&:id)}]) }
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'error handling' do
|
141
|
+
let!(:cities) { 6.times.map { |i| City.create! }.sort_by(&:id) }
|
142
|
+
let!(:deleted) { 4.times.map { |i| City.create!.tap(&:destroy) }.sort_by(&:id) }
|
143
|
+
let(:ids) { (cities + deleted).map(&:id) }
|
144
|
+
subject { described_class.new(City) }
|
145
|
+
|
146
|
+
let(:data_comparer) do
|
147
|
+
->(ids, data) { objects = (data[:index] || data[:delete]).first(2); objects.map { |o| o.respond_to?(:id) ? o.id : o }.sort != ids.map(&:id).sort }
|
148
|
+
end
|
149
|
+
|
150
|
+
context 'implicit scope' do
|
151
|
+
specify { expect(subject.import { |data| true }).to eq(true) }
|
152
|
+
specify { expect(subject.import { |data| false }).to eq(false) }
|
153
|
+
specify { expect(subject.import(batch_size: 2, &data_comparer.curry[cities[0..1]])).to eq(false) }
|
154
|
+
specify { expect(subject.import(batch_size: 2, &data_comparer.curry[cities[2..3]])).to eq(false) }
|
155
|
+
specify { expect(subject.import(batch_size: 2, &data_comparer.curry[cities[4..5]])).to eq(false) }
|
156
|
+
specify { expect(subject.import(batch_size: 2, &data_comparer.curry[deleted[0..1]])).to eq(true) }
|
157
|
+
specify { expect(subject.import(batch_size: 2, &data_comparer.curry[deleted[2..3]])).to eq(true) }
|
158
|
+
end
|
159
|
+
|
160
|
+
context 'explicit scope' do
|
161
|
+
let(:scope) { mongoid? ? City.where(:id.in => ids) : City.where(id: ids) }
|
162
|
+
|
163
|
+
specify { expect(subject.import(scope) { |data| true }).to eq(true) }
|
164
|
+
specify { expect(subject.import(scope) { |data| false }).to eq(false) }
|
165
|
+
specify { expect(subject.import(scope, batch_size: 2, &data_comparer.curry[cities[0..1]])).to eq(false) }
|
166
|
+
specify { expect(subject.import(scope, batch_size: 2, &data_comparer.curry[cities[2..3]])).to eq(false) }
|
167
|
+
specify { expect(subject.import(scope, batch_size: 2, &data_comparer.curry[cities[4..5]])).to eq(false) }
|
168
|
+
specify { expect(subject.import(scope, batch_size: 2, &data_comparer.curry[deleted[0..1]])).to eq(true) }
|
169
|
+
specify { expect(subject.import(scope, batch_size: 2, &data_comparer.curry[deleted[2..3]])).to eq(true) }
|
170
|
+
end
|
171
|
+
|
172
|
+
context 'objects' do
|
173
|
+
specify { expect(subject.import(cities + deleted) { |data| true }).to eq(true) }
|
174
|
+
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..1]])).to eq(false) }
|
176
|
+
specify { expect(subject.import(cities + deleted, batch_size: 2, &data_comparer.curry[cities[2..3]])).to eq(false) }
|
177
|
+
specify { expect(subject.import(cities + deleted, batch_size: 2, &data_comparer.curry[cities[4..5]])).to eq(false) }
|
178
|
+
specify { expect(subject.import(cities + deleted, batch_size: 2, &data_comparer.curry[deleted[0..1]])).to eq(false) }
|
179
|
+
specify { expect(subject.import(cities + deleted, batch_size: 2, &data_comparer.curry[deleted[2..3]])).to eq(false) }
|
180
|
+
end
|
181
|
+
|
182
|
+
context 'ids' do
|
183
|
+
specify { expect(subject.import(ids) { |data| true }).to eq(true) }
|
184
|
+
specify { expect(subject.import(ids) { |data| false }).to eq(false) }
|
185
|
+
specify { expect(subject.import(ids, batch_size: 2, &data_comparer.curry[cities[0..1]])).to eq(false) }
|
186
|
+
specify { expect(subject.import(ids, batch_size: 2, &data_comparer.curry[cities[2..3]])).to eq(false) }
|
187
|
+
specify { expect(subject.import(ids, batch_size: 2, &data_comparer.curry[cities[4..5]])).to eq(false) }
|
188
|
+
specify { expect(subject.import(ids, batch_size: 2, &data_comparer.curry[deleted[0..1]])).to eq(false) }
|
189
|
+
specify { expect(subject.import(ids, batch_size: 2, &data_comparer.curry[deleted[2..3]])).to eq(false) }
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
describe '#load' do
|
195
|
+
context do
|
196
|
+
let!(:cities) { 3.times.map { |i| City.create!(rating: i/2) }.sort_by(&:id) }
|
197
|
+
let!(:deleted) { 2.times.map { |i| City.create!.tap(&:destroy) }.sort_by(&:id) }
|
198
|
+
|
199
|
+
let(:type) { double(type_name: 'user') }
|
200
|
+
|
201
|
+
subject { described_class.new(City) }
|
202
|
+
|
203
|
+
specify { expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type)).to eq(cities) }
|
204
|
+
specify { expect(subject.load(cities.map { |c| double(id: c.id) }.reverse, _type: type)).to eq(cities.reverse) }
|
205
|
+
specify { expect(subject.load(deleted.map { |c| double(id: c.id) }, _type: type)).to eq([nil, nil]) }
|
206
|
+
specify { expect(subject.load((cities + deleted).map { |c| double(id: c.id) }, _type: type)).to eq([*cities, nil, nil]) }
|
207
|
+
specify { expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: ->{ where(rating: 0) }))
|
208
|
+
.to eq(cities.first(2) + [nil]) }
|
209
|
+
specify { expect(subject.load(cities.map { |c| double(id: c.id) },
|
210
|
+
_type: type, scope: ->{ where(rating: 0) }, user: {scope: ->{ where(rating: 1)}}))
|
211
|
+
.to eq([nil, nil] + cities.last(1)) }
|
212
|
+
specify { expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: City.where(rating: 1)))
|
213
|
+
.to eq([nil, nil] + cities.last(1)) }
|
214
|
+
specify { expect(subject.load(cities.map { |c| double(id: c.id) },
|
215
|
+
_type: type, scope: City.where(rating: 1), user: {scope: ->{ where(rating: 0)}}))
|
216
|
+
.to eq(cities.first(2) + [nil]) }
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
@@ -4,28 +4,28 @@ describe Chewy::Type::Adapter::Object do
|
|
4
4
|
before { stub_class(:product) }
|
5
5
|
|
6
6
|
describe '#name' do
|
7
|
-
specify { described_class.new('product').name.
|
8
|
-
specify { described_class.new(:products).name.
|
9
|
-
specify { described_class.new(Product).name.
|
10
|
-
specify { described_class.new(Product, name: 'house').name.
|
7
|
+
specify { expect(described_class.new('product').name).to eq('Product') }
|
8
|
+
specify { expect(described_class.new(:products).name).to eq('Products') }
|
9
|
+
specify { expect(described_class.new(Product).name).to eq('Product') }
|
10
|
+
specify { expect(described_class.new(Product, name: 'house').name).to eq('House') }
|
11
11
|
|
12
12
|
context do
|
13
13
|
before { stub_class('namespace/product') }
|
14
14
|
|
15
|
-
specify { described_class.new(Namespace::Product).name.
|
15
|
+
specify { expect(described_class.new(Namespace::Product).name).to eq('Product') }
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
describe '#type_name' do
|
20
|
-
specify { described_class.new('product').type_name.
|
21
|
-
specify { described_class.new(:products).type_name.
|
22
|
-
specify { described_class.new(Product).type_name.
|
23
|
-
specify { described_class.new(Product, name: 'house').type_name.
|
20
|
+
specify { expect(described_class.new('product').type_name).to eq('product') }
|
21
|
+
specify { expect(described_class.new(:products).type_name).to eq('products') }
|
22
|
+
specify { expect(described_class.new(Product).type_name).to eq('product') }
|
23
|
+
specify { expect(described_class.new(Product, name: 'house').type_name).to eq('house') }
|
24
24
|
|
25
25
|
context do
|
26
26
|
before { stub_class('namespace/product') }
|
27
27
|
|
28
|
-
specify { described_class.new(Namespace::Product).type_name.
|
28
|
+
specify { expect(described_class.new(Namespace::Product).type_name).to eq('product') }
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -36,61 +36,61 @@ describe Chewy::Type::Adapter::Object do
|
|
36
36
|
result
|
37
37
|
end
|
38
38
|
|
39
|
-
specify { subject.import(3.times.map { |i| double }) { |data| true }.
|
40
|
-
specify { subject.import(3.times.map { |i| double }) { |data| false }.
|
39
|
+
specify { expect(subject.import(3.times.map { |i| double }) { |data| true }).to eq(true) }
|
40
|
+
specify { expect(subject.import(3.times.map { |i| double }) { |data| false }).to eq(false) }
|
41
41
|
|
42
42
|
context do
|
43
43
|
let(:objects) { 3.times.map { |i| double } }
|
44
44
|
let(:deleted) { 2.times.map { |i| double(destroyed?: true) } }
|
45
45
|
subject { described_class.new('product') }
|
46
46
|
|
47
|
-
specify { import.
|
48
|
-
specify { import(objects).
|
49
|
-
specify { import(objects, batch_size: 2)
|
50
|
-
.
|
51
|
-
specify { import(objects, deleted).
|
52
|
-
specify { import(objects, deleted, batch_size: 2).
|
47
|
+
specify { expect(import).to eq([]) }
|
48
|
+
specify { expect(import(objects)).to eq([{index: objects}]) }
|
49
|
+
specify { expect(import(objects, batch_size: 2))
|
50
|
+
.to eq([{index: objects.first(2)}, {index: objects.last(1)}]) }
|
51
|
+
specify { expect(import(objects, deleted)).to eq([{index: objects, delete: deleted}]) }
|
52
|
+
specify { expect(import(objects, deleted, batch_size: 2)).to eq([
|
53
53
|
{index: objects.first(2)},
|
54
54
|
{index: objects.last(1), delete: deleted.first(1)},
|
55
|
-
{delete: deleted.last(1)}] }
|
55
|
+
{delete: deleted.last(1)}]) }
|
56
56
|
|
57
|
-
specify { import(objects.first, nil).
|
57
|
+
specify { expect(import(objects.first, nil)).to eq([{index: [objects.first]}]) }
|
58
58
|
|
59
59
|
context do
|
60
60
|
let(:deleted) { 2.times.map { |i| double(delete_from_index?: true, destroyed?: true) } }
|
61
|
-
specify { import(deleted).
|
61
|
+
specify { expect(import(deleted)).to eq([{delete: deleted}]) }
|
62
62
|
end
|
63
63
|
|
64
64
|
context do
|
65
65
|
let(:deleted) { 2.times.map { |i| double(delete_from_index?: true, destroyed?: false) } }
|
66
|
-
specify { import(deleted).
|
66
|
+
specify { expect(import(deleted)).to eq([{delete: deleted}]) }
|
67
67
|
end
|
68
68
|
|
69
69
|
|
70
70
|
context do
|
71
71
|
let(:deleted) { 2.times.map { |i| double(delete_from_index?: false, destroyed?: true) } }
|
72
|
-
specify { import(deleted).
|
72
|
+
specify { expect(import(deleted)).to eq([{delete: deleted}]) }
|
73
73
|
end
|
74
74
|
|
75
75
|
context do
|
76
76
|
let(:deleted) { 2.times.map { |i| double(delete_from_index?: false, destroyed?: false) } }
|
77
|
-
specify { import(deleted).
|
77
|
+
specify { expect(import(deleted)).to eq([{index: deleted}]) }
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
81
|
context do
|
82
82
|
let(:products) { 3.times.map { |i| double.tap { |product|
|
83
|
-
product.
|
83
|
+
allow(product).to receive(:is_a?).with(Product).and_return(true)
|
84
84
|
} } }
|
85
85
|
let(:non_product) { double }
|
86
86
|
subject { described_class.new(Product) }
|
87
87
|
|
88
|
-
specify { import(products).
|
88
|
+
specify { expect(import(products)).to eq([{index: products}]) }
|
89
89
|
specify { expect { import(products, non_product) {} }.to raise_error }
|
90
90
|
end
|
91
91
|
|
92
92
|
context 'error handling' do
|
93
|
-
let(:products) { 3.times.map { |i| double.tap { |product| product.
|
93
|
+
let(:products) { 3.times.map { |i| double.tap { |product| allow(product).to receive_messages(rating: i.next) } } }
|
94
94
|
let(:deleted) { 2.times.map { |i| double(destroyed?: true, rating: i + 4) } }
|
95
95
|
subject { described_class.new('product') }
|
96
96
|
|
@@ -98,13 +98,13 @@ describe Chewy::Type::Adapter::Object do
|
|
98
98
|
->(n, data) { (data[:index] || data[:delete]).first.rating != n }
|
99
99
|
end
|
100
100
|
|
101
|
-
specify { subject.import(products, deleted) { |data| true }.
|
102
|
-
specify { subject.import(products, deleted) { |data| false }.
|
103
|
-
specify { subject.import(products, deleted, batch_size: 1, &data_comparer.curry[1]).
|
104
|
-
specify { subject.import(products, deleted, batch_size: 1, &data_comparer.curry[2]).
|
105
|
-
specify { subject.import(products, deleted, batch_size: 1, &data_comparer.curry[3]).
|
106
|
-
specify { subject.import(products, deleted, batch_size: 1, &data_comparer.curry[4]).
|
107
|
-
specify { subject.import(products, deleted, batch_size: 1, &data_comparer.curry[5]).
|
101
|
+
specify { expect(subject.import(products, deleted) { |data| true }).to eq(true) }
|
102
|
+
specify { expect(subject.import(products, deleted) { |data| false }).to eq(false) }
|
103
|
+
specify { expect(subject.import(products, deleted, batch_size: 1, &data_comparer.curry[1])).to eq(false) }
|
104
|
+
specify { expect(subject.import(products, deleted, batch_size: 1, &data_comparer.curry[2])).to eq(false) }
|
105
|
+
specify { expect(subject.import(products, deleted, batch_size: 1, &data_comparer.curry[3])).to eq(false) }
|
106
|
+
specify { expect(subject.import(products, deleted, batch_size: 1, &data_comparer.curry[4])).to eq(false) }
|
107
|
+
specify { expect(subject.import(products, deleted, batch_size: 1, &data_comparer.curry[5])).to eq(false) }
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
@@ -113,23 +113,23 @@ describe Chewy::Type::Adapter::Object do
|
|
113
113
|
subject { described_class.new('product') }
|
114
114
|
let(:objects) { 3.times.map { |i| double } }
|
115
115
|
|
116
|
-
specify { subject.load(objects).
|
116
|
+
specify { expect(subject.load(objects)).to eq(objects) }
|
117
117
|
end
|
118
118
|
|
119
119
|
context do
|
120
|
-
before { Product.
|
120
|
+
before { allow(Product).to receive(:wrap) { |object| allow(object).to receive_messages(wrapped?: true); object } }
|
121
121
|
subject { described_class.new(Product) }
|
122
122
|
let(:objects) { 3.times.map { |i| double(wrapped?: false) } }
|
123
123
|
|
124
|
-
specify { subject.load(objects).
|
124
|
+
specify { expect(subject.load(objects)).to satisfy { |objects| objects.all?(&:wrapped?) } }
|
125
125
|
end
|
126
126
|
|
127
127
|
context do
|
128
|
-
before { Product.
|
128
|
+
before { allow(Product).to receive(:wrap) { |object| nil } }
|
129
129
|
subject { described_class.new(Product) }
|
130
130
|
let(:objects) { 3.times.map { |i| double(wrapped?: false) } }
|
131
131
|
|
132
|
-
specify { subject.load(objects).
|
132
|
+
specify { expect(subject.load(objects)).to satisfy { |objects| objects.all?(&:nil?) } }
|
133
133
|
end
|
134
134
|
end
|
135
135
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Chewy::Type::Import do
|
4
|
-
before { Chewy.
|
4
|
+
before { Chewy.massacre }
|
5
5
|
|
6
6
|
before do
|
7
7
|
stub_model(:city)
|
@@ -15,23 +15,33 @@ describe Chewy::Type::Import do
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
let!(:dummy_cities) { 3.times.map { |i| City.create(name: "name#{i}") } }
|
18
|
+
let!(:dummy_cities) { 3.times.map { |i| City.create(id: i + 1, name: "name#{i}") } }
|
19
19
|
let(:city) { CitiesIndex::City }
|
20
20
|
|
21
|
-
describe '.import' do
|
22
|
-
specify { city.import.
|
23
|
-
specify { city.import([]).
|
24
|
-
specify { city.import(dummy_cities).
|
25
|
-
specify { city.import(dummy_cities.map(&:id)).
|
21
|
+
describe '.import', :orm do
|
22
|
+
specify { expect(city.import).to eq(true) }
|
23
|
+
specify { expect(city.import([])).to eq(true) }
|
24
|
+
specify { expect(city.import(dummy_cities)).to eq(true) }
|
25
|
+
specify { expect(city.import(dummy_cities.map(&:id))).to eq(true) }
|
26
26
|
|
27
27
|
specify { expect { city.import([]) }.not_to update_index(city) }
|
28
28
|
specify { expect { city.import }.to update_index(city).and_reindex(dummy_cities) }
|
29
29
|
specify { expect { city.import dummy_cities }.to update_index(city).and_reindex(dummy_cities) }
|
30
30
|
specify { expect { city.import dummy_cities.map(&:id) }.to update_index(city).and_reindex(dummy_cities) }
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
|
32
|
+
describe 'criteria-driven importing' do
|
33
|
+
let(:names) { %w(name0 name1) }
|
34
|
+
|
35
|
+
context 'mongoid', :mongoid do
|
36
|
+
specify { expect { city.import(City.where(:name.in => names)) }.to update_index(city).and_reindex(dummy_cities.first(2)) }
|
37
|
+
specify { expect { city.import(City.where(:name.in => names).map(&:id)) }.to update_index(city).and_reindex(dummy_cities.first(2)) }
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'active record', :active_record do
|
41
|
+
specify { expect { city.import(City.where(name: names)) }.to update_index(city).and_reindex(dummy_cities.first(2)) }
|
42
|
+
specify { expect { city.import(City.where(name: names).map(&:id)) }.to update_index(city).and_reindex(dummy_cities.first(2)) }
|
43
|
+
end
|
44
|
+
end
|
35
45
|
|
36
46
|
specify do
|
37
47
|
dummy_cities.first.destroy
|
@@ -47,15 +57,16 @@ describe Chewy::Type::Import do
|
|
47
57
|
|
48
58
|
specify do
|
49
59
|
dummy_cities.first.destroy
|
60
|
+
|
50
61
|
expect(CitiesIndex.client).to receive(:bulk).with(hash_including(
|
51
62
|
body: [{delete: {_id: dummy_cities.first.id}}]
|
52
63
|
))
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
city.import dummy_cities.map(&:id), batch_size:
|
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
|
+
))
|
68
|
+
|
69
|
+
city.import dummy_cities.map(&:id), batch_size: 2
|
59
70
|
end
|
60
71
|
|
61
72
|
specify do
|
@@ -70,15 +81,34 @@ describe Chewy::Type::Import do
|
|
70
81
|
|
71
82
|
context 'scoped' do
|
72
83
|
before do
|
84
|
+
names = %w(name0 name1)
|
85
|
+
|
86
|
+
criteria = if defined?(::Mongoid)
|
87
|
+
{ :name.in => names }
|
88
|
+
else
|
89
|
+
{ name: names }
|
90
|
+
end
|
91
|
+
|
73
92
|
stub_index(:cities) do
|
74
|
-
define_type City.where(
|
93
|
+
define_type City.where(criteria) do
|
75
94
|
field :name
|
76
95
|
end
|
77
96
|
end
|
78
97
|
end
|
79
98
|
|
80
99
|
specify { expect { city.import }.to update_index(city).and_reindex(dummy_cities.first(2)) }
|
81
|
-
|
100
|
+
|
101
|
+
context 'mongoid', :mongoid do
|
102
|
+
specify do
|
103
|
+
expect { city.import City.where(_id: dummy_cities.first.id) }.to update_index(city).and_reindex(dummy_cities.first).only
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'active record', :active_record do
|
108
|
+
specify do
|
109
|
+
expect { city.import City.where(id: dummy_cities.first.id) }.to update_index(city).and_reindex(dummy_cities.first).only
|
110
|
+
end
|
111
|
+
end
|
82
112
|
end
|
83
113
|
|
84
114
|
context 'instrumentation payload' do
|
@@ -90,7 +120,7 @@ describe Chewy::Type::Import do
|
|
90
120
|
|
91
121
|
dummy_cities.first.destroy
|
92
122
|
city.import dummy_cities
|
93
|
-
outer_payload.
|
123
|
+
expect(outer_payload).to eq({type: CitiesIndex::City, import: {delete: 1, index: 2}})
|
94
124
|
end
|
95
125
|
|
96
126
|
specify do
|
@@ -101,7 +131,7 @@ describe Chewy::Type::Import do
|
|
101
131
|
|
102
132
|
dummy_cities.first.destroy
|
103
133
|
city.import dummy_cities, batch_size: 1
|
104
|
-
outer_payload.
|
134
|
+
expect(outer_payload).to eq({type: CitiesIndex::City, import: {delete: 1, index: 2}})
|
105
135
|
end
|
106
136
|
|
107
137
|
specify do
|
@@ -111,7 +141,7 @@ describe Chewy::Type::Import do
|
|
111
141
|
end
|
112
142
|
|
113
143
|
city.import dummy_cities, batch_size: 1
|
114
|
-
outer_payload.
|
144
|
+
expect(outer_payload).to eq({type: CitiesIndex::City, import: {index: 3}})
|
115
145
|
end
|
116
146
|
|
117
147
|
context do
|
@@ -130,7 +160,7 @@ describe Chewy::Type::Import do
|
|
130
160
|
end
|
131
161
|
|
132
162
|
city.import dummy_cities, batch_size: 1
|
133
|
-
outer_payload.
|
163
|
+
expect(outer_payload).to eq({
|
134
164
|
type: CitiesIndex::City,
|
135
165
|
errors: {
|
136
166
|
index: {
|
@@ -138,7 +168,7 @@ describe Chewy::Type::Import do
|
|
138
168
|
}
|
139
169
|
},
|
140
170
|
import: {index: 3}
|
141
|
-
}
|
171
|
+
})
|
142
172
|
end
|
143
173
|
end
|
144
174
|
end
|
@@ -153,9 +183,9 @@ describe Chewy::Type::Import do
|
|
153
183
|
end
|
154
184
|
end
|
155
185
|
|
156
|
-
specify { city.import(dummy_cities).
|
157
|
-
specify { city.import(dummy_cities.map(&:id)).
|
158
|
-
specify { city.import(dummy_cities, batch_size: 1).
|
186
|
+
specify { expect(city.import(dummy_cities)).to eq(false) }
|
187
|
+
specify { expect(city.import(dummy_cities.map(&:id))).to eq(false) }
|
188
|
+
specify { expect(city.import(dummy_cities, batch_size: 1)).to eq(false) }
|
159
189
|
end
|
160
190
|
|
161
191
|
context do
|
@@ -167,15 +197,15 @@ describe Chewy::Type::Import do
|
|
167
197
|
end
|
168
198
|
end
|
169
199
|
|
170
|
-
specify { city.import(dummy_cities).
|
171
|
-
specify { city.import(dummy_cities.map(&:id)).
|
172
|
-
specify { city.import(dummy_cities, batch_size: 1).
|
200
|
+
specify { expect(city.import(dummy_cities)).to eq(false) }
|
201
|
+
specify { expect(city.import(dummy_cities.map(&:id))).to eq(false) }
|
202
|
+
specify { expect(city.import(dummy_cities, batch_size: 1)).to eq(false) }
|
173
203
|
end
|
174
204
|
end
|
175
205
|
|
176
|
-
context 'parent-child relationship' do
|
177
|
-
let(:country) { Country.create(name: 'country') }
|
178
|
-
let(:another_country) { Country.create(name: 'another country') }
|
206
|
+
context 'parent-child relationship', :orm do
|
207
|
+
let(:country) { Country.create(id: 1, name: 'country') }
|
208
|
+
let(:another_country) { Country.create(id: 2, name: 'another country') }
|
179
209
|
|
180
210
|
before do
|
181
211
|
stub_model(:country)
|
@@ -198,10 +228,10 @@ describe Chewy::Type::Import do
|
|
198
228
|
|
199
229
|
before { CountriesIndex::Country.import(country) }
|
200
230
|
|
201
|
-
let(:child_city) { City.create(country_id: country.id, name: 'city') }
|
231
|
+
let(:child_city) { City.create(id: 4, country_id: country.id, name: 'city') }
|
202
232
|
let(:city) { CountriesIndex::City }
|
203
233
|
|
204
|
-
specify { city.import(child_city).
|
234
|
+
specify { expect(city.import(child_city)).to eq(true) }
|
205
235
|
specify { expect { city.import child_city }.to update_index(city).and_reindex(child_city) }
|
206
236
|
|
207
237
|
specify do
|
@@ -251,8 +281,8 @@ describe Chewy::Type::Import do
|
|
251
281
|
end
|
252
282
|
end
|
253
283
|
|
254
|
-
describe '.import!' do
|
255
|
-
specify { expect { city.import
|
284
|
+
describe '.import!', :orm do
|
285
|
+
specify { expect { city.import! }.not_to raise_error }
|
256
286
|
|
257
287
|
context do
|
258
288
|
before do
|