chewy 0.4.1 → 0.5.0

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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -3
  3. data/CHANGELOG.md +43 -1
  4. data/Gemfile +3 -0
  5. data/README.md +49 -11
  6. data/chewy.gemspec +1 -2
  7. data/gemfiles/Gemfile.rails-3.2 +1 -0
  8. data/gemfiles/Gemfile.rails-4.0 +1 -0
  9. data/lib/chewy.rb +8 -2
  10. data/lib/chewy/backports/deep_dup.rb +46 -0
  11. data/lib/chewy/backports/duplicable.rb +90 -0
  12. data/lib/chewy/config.rb +33 -6
  13. data/lib/chewy/errors.rb +1 -1
  14. data/lib/chewy/fields/base.rb +19 -7
  15. data/lib/chewy/fields/root.rb +13 -0
  16. data/lib/chewy/index/actions.rb +14 -6
  17. data/lib/chewy/index/search.rb +3 -2
  18. data/lib/chewy/query.rb +131 -17
  19. data/lib/chewy/query/compose.rb +27 -17
  20. data/lib/chewy/query/criteria.rb +34 -22
  21. data/lib/chewy/query/loading.rb +94 -10
  22. data/lib/chewy/query/nodes/exists.rb +1 -1
  23. data/lib/chewy/query/nodes/has_relation.rb +1 -1
  24. data/lib/chewy/query/nodes/missing.rb +1 -1
  25. data/lib/chewy/query/pagination.rb +8 -38
  26. data/lib/chewy/query/pagination/kaminari.rb +37 -0
  27. data/lib/chewy/runtime.rb +9 -0
  28. data/lib/chewy/runtime/version.rb +25 -0
  29. data/lib/chewy/type/adapter/active_record.rb +21 -7
  30. data/lib/chewy/type/adapter/base.rb +1 -1
  31. data/lib/chewy/type/adapter/object.rb +9 -6
  32. data/lib/chewy/type/import.rb +7 -4
  33. data/lib/chewy/type/mapping.rb +9 -9
  34. data/lib/chewy/type/wrapper.rb +1 -1
  35. data/lib/chewy/version.rb +1 -1
  36. data/lib/tasks/chewy.rake +40 -21
  37. data/spec/chewy/config_spec.rb +1 -1
  38. data/spec/chewy/fields/base_spec.rb +273 -8
  39. data/spec/chewy/index/actions_spec.rb +1 -2
  40. data/spec/chewy/index/aliases_spec.rb +0 -1
  41. data/spec/chewy/index/search_spec.rb +0 -8
  42. data/spec/chewy/index/settings_spec.rb +0 -2
  43. data/spec/chewy/index_spec.rb +0 -2
  44. data/spec/chewy/query/criteria_spec.rb +85 -18
  45. data/spec/chewy/query/loading_spec.rb +26 -9
  46. data/spec/chewy/query/nodes/and_spec.rb +2 -2
  47. data/spec/chewy/query/nodes/exists_spec.rb +6 -6
  48. data/spec/chewy/query/nodes/missing_spec.rb +4 -4
  49. data/spec/chewy/query/nodes/or_spec.rb +2 -2
  50. data/spec/chewy/query/pagination/kaminari_spec.rb +55 -0
  51. data/spec/chewy/query/pagination_spec.rb +15 -22
  52. data/spec/chewy/query_spec.rb +121 -52
  53. data/spec/chewy/rspec/update_index_spec.rb +0 -1
  54. data/spec/chewy/runtime/version_spec.rb +48 -0
  55. data/spec/chewy/runtime_spec.rb +9 -0
  56. data/spec/chewy/type/adapter/active_record_spec.rb +52 -0
  57. data/spec/chewy/type/adapter/object_spec.rb +33 -0
  58. data/spec/chewy/type/import_spec.rb +1 -3
  59. data/spec/chewy/type/mapping_spec.rb +4 -6
  60. data/spec/chewy/type/observe_spec.rb +0 -2
  61. data/spec/chewy/type/wrapper_spec.rb +0 -2
  62. data/spec/chewy/type_spec.rb +26 -5
  63. data/spec/chewy_spec.rb +0 -2
  64. data/spec/spec_helper.rb +2 -2
  65. metadata +15 -21
  66. data/lib/chewy/fields/default.rb +0 -10
  67. data/spec/chewy/fields/default_spec.rb +0 -6
@@ -1,8 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Chewy::Query do
4
- include ClassHelpers
5
- before { Chewy.client.indices.delete index: '*' }
4
+ before do
5
+ Chewy.client.indices.delete index: '*'
6
+ end
6
7
 
7
8
  before do
8
9
  stub_index(:products) do
@@ -16,6 +17,10 @@ describe Chewy::Query do
16
17
 
17
18
  subject { described_class.new(ProductsIndex) }
18
19
 
20
+ context 'unexistent index' do
21
+ specify { subject.to_a.should == [] }
22
+ end
23
+
19
24
  context 'integration' do
20
25
  let(:products) { 3.times.map { |i| {id: i.next.to_s, name: "Name#{i.next}", age: 10 * i.next}.stringify_keys! } }
21
26
  let(:cities) { 3.times.map { |i| {id: i.next.to_s}.stringify_keys! } }
@@ -27,8 +32,11 @@ describe Chewy::Query do
27
32
  end
28
33
 
29
34
  specify { subject.count.should == 9 }
35
+ specify { subject.first._data.should be_a Hash }
30
36
  specify { subject.limit(6).count.should == 6 }
31
37
  specify { subject.offset(6).count.should == 3 }
38
+ specify { subject.query(match: {name: 'name3'}).highlight(fields: {name: {}}).first.name.should == '<em>Name3</em>' }
39
+ specify { subject.query(match: {name: 'name3'}).highlight(fields: {name: {}}).first._data['_source']['name'].should == 'Name3' }
32
40
  specify { subject.types(:product).count.should == 3 }
33
41
  specify { subject.types(:product, :country).count.should == 6 }
34
42
  specify { subject.filter(term: {age: 10}).count.should == 1 }
@@ -60,39 +68,25 @@ describe Chewy::Query do
60
68
  specify { expect { subject.filter_mode(:or) }.not_to change { subject.criteria.options } }
61
69
  end
62
70
 
71
+ describe '#post_filter_mode' do
72
+ specify { subject.post_filter_mode(:or).should be_a described_class }
73
+ specify { subject.post_filter_mode(:or).should_not == subject }
74
+ specify { subject.post_filter_mode(:or).criteria.options.should include(post_filter_mode: :or) }
75
+ specify { expect { subject.post_filter_mode(:or) }.not_to change { subject.criteria.options } }
76
+ end
77
+
63
78
  describe '#limit' do
64
79
  specify { subject.limit(10).should be_a described_class }
65
80
  specify { subject.limit(10).should_not == subject }
66
- specify { subject.limit(10).criteria.options.should include(size: 10) }
67
- specify { expect { subject.limit(10) }.not_to change { subject.criteria.options } }
81
+ specify { subject.limit(10).criteria.request_options.should include(size: 10) }
82
+ specify { expect { subject.limit(10) }.not_to change { subject.criteria.request_options } }
68
83
  end
69
84
 
70
85
  describe '#offset' do
71
86
  specify { subject.offset(10).should be_a described_class }
72
87
  specify { subject.offset(10).should_not == subject }
73
- specify { subject.offset(10).criteria.options.should include(from: 10) }
74
- specify { expect { subject.offset(10) }.not_to change { subject.criteria.options } }
75
- end
76
-
77
- describe '#none' do
78
- specify { subject.none.should be_a described_class }
79
- specify { subject.none.should_not == subject }
80
- specify { subject.none.criteria.should be_none }
81
-
82
- context do
83
- before { described_class.any_instance.should_not_receive(:_response) }
84
-
85
- specify { subject.none.to_a.should == [] }
86
- specify { subject.query(match: 'hello').none.to_a.should == [] }
87
- specify { subject.none.query(match: 'hello').to_a.should == [] }
88
- end
89
- end
90
-
91
- describe '#query' do
92
- specify { subject.query(match: 'hello').should be_a described_class }
93
- specify { subject.query(match: 'hello').should_not == subject }
94
- specify { subject.query(match: 'hello').criteria.queries.should include(match: 'hello') }
95
- specify { expect { subject.query(match: 'hello') }.not_to change { subject.criteria.queries } }
88
+ specify { subject.offset(10).criteria.request_options.should include(from: 10) }
89
+ specify { expect { subject.offset(10) }.not_to change { subject.criteria.request_options } }
96
90
  end
97
91
 
98
92
  describe '#facets' do
@@ -105,29 +99,27 @@ describe Chewy::Query do
105
99
  before { stub_model(:city) }
106
100
  let(:cities) { 10.times.map { |i| City.create! name: "name#{i}", rating: i % 3 } }
107
101
 
108
- context do
109
- before do
110
- stub_index(:cities) do
111
- define_type :city do
112
- field :rating, type: 'integer'
113
- end
102
+ before do
103
+ stub_index(:cities) do
104
+ define_type :city do
105
+ field :rating, type: 'integer'
114
106
  end
115
107
  end
108
+ end
116
109
 
117
- before { CitiesIndex::City.import! cities }
110
+ before { CitiesIndex::City.import! cities }
118
111
 
119
- specify { CitiesIndex.facets.should == {} }
120
- specify { CitiesIndex.facets(ratings: {terms: {field: 'rating'}}).facets.should == {
121
- 'ratings' => {
122
- '_type' => 'terms', 'missing' => 0, 'total' => 10, 'other' => 0,
123
- 'terms' => [
124
- {'term' => 0, 'count' => 4},
125
- {'term' => 2, 'count' => 3},
126
- {'term' => 1, 'count' => 3}
127
- ]
128
- }
129
- } }
130
- end
112
+ specify { CitiesIndex.facets.should == {} }
113
+ specify { CitiesIndex.facets(ratings: {terms: {field: 'rating'}}).facets.should == {
114
+ 'ratings' => {
115
+ '_type' => 'terms', 'missing' => 0, 'total' => 10, 'other' => 0,
116
+ 'terms' => [
117
+ {'term' => 0, 'count' => 4},
118
+ {'term' => 2, 'count' => 3},
119
+ {'term' => 1, 'count' => 3}
120
+ ]
121
+ }
122
+ } }
131
123
  end
132
124
  end
133
125
 
@@ -156,9 +148,9 @@ describe Chewy::Query do
156
148
  specify { CitiesIndex.aggregations(ratings: {terms: {field: 'rating'}}).aggregations.should == {
157
149
  'ratings' => {
158
150
  'buckets' => [
159
- {'key' => 0, 'doc_count' => 4},
160
- {'key' => 1, 'doc_count' => 3},
161
- {'key' => 2, 'doc_count' => 3}
151
+ {'key' => 0, 'key_as_string' => '0', 'doc_count' => 4},
152
+ {'key' => 1, 'key_as_string' => '1', 'doc_count' => 3},
153
+ {'key' => 2, 'key_as_string' => '2', 'doc_count' => 3}
162
154
  ]
163
155
  }
164
156
  } }
@@ -166,6 +158,72 @@ describe Chewy::Query do
166
158
  end
167
159
  end
168
160
 
161
+ describe '#suggest' do
162
+ specify { subject.suggest(name1: {text: 'hello', term: {field: 'name'}}) }
163
+ specify { subject.suggest(name1: {text: 'hello'}).should_not == subject }
164
+ specify { subject.suggest(name1: {text: 'hello'}).criteria.suggest.should include(name1: {text: 'hello'}) }
165
+ specify { expect { subject.suggest(name1: {text: 'hello'}) }.not_to change { subject.criteria.suggest } }
166
+
167
+ context 'results' do
168
+ before { stub_model(:city) }
169
+ let(:cities) { 10.times.map { |i| City.create! name: "name#{i}" } }
170
+
171
+ context do
172
+ before do
173
+ stub_index(:cities) do
174
+ define_type :city do
175
+ field :name
176
+ end
177
+ end
178
+ end
179
+
180
+ before { CitiesIndex::City.import! cities }
181
+
182
+ specify { CitiesIndex.suggest.should == {} }
183
+ specify { CitiesIndex.suggest(name: {text: 'name', term: {field: 'name'}}).suggest.should == {
184
+ 'name' => [
185
+ {'text' => 'name', 'offset' => 0, 'length' => 4, 'options' => [
186
+ {'text' => 'name0', 'score' => 0.75, 'freq' => 1},
187
+ {'text' => 'name1', 'score' => 0.75, 'freq' => 1},
188
+ {'text' => 'name2', 'score' => 0.75, 'freq' => 1},
189
+ {'text' => 'name3', 'score' => 0.75, 'freq' => 1},
190
+ {'text' => 'name4', 'score' => 0.75, 'freq' => 1}
191
+ ]
192
+ }
193
+ ] }
194
+ }
195
+ end
196
+ end
197
+ end
198
+
199
+ describe '#none' do
200
+ specify { subject.none.should be_a described_class }
201
+ specify { subject.none.should_not == subject }
202
+ specify { subject.none.criteria.should be_none }
203
+
204
+ context do
205
+ before { described_class.any_instance.should_not_receive(:_response) }
206
+
207
+ specify { subject.none.to_a.should == [] }
208
+ specify { subject.query(match: 'hello').none.to_a.should == [] }
209
+ specify { subject.none.query(match: 'hello').to_a.should == [] }
210
+ end
211
+ end
212
+
213
+ describe '#strategy' do
214
+ specify { subject.strategy('query_first').should be_a described_class }
215
+ specify { subject.strategy('query_first').should_not == subject }
216
+ specify { subject.strategy('query_first').criteria.options.should include(strategy: 'query_first') }
217
+ specify { expect { subject.strategy('query_first') }.not_to change { subject.criteria.options } }
218
+ end
219
+
220
+ describe '#query' do
221
+ specify { subject.query(match: 'hello').should be_a described_class }
222
+ specify { subject.query(match: 'hello').should_not == subject }
223
+ specify { subject.query(match: 'hello').criteria.queries.should include(match: 'hello') }
224
+ specify { expect { subject.query(match: 'hello') }.not_to change { subject.criteria.queries } }
225
+ end
226
+
169
227
  describe '#filter' do
170
228
  specify { subject.filter(term: {field: 'hello'}).should be_a described_class }
171
229
  specify { subject.filter(term: {field: 'hello'}).should_not == subject }
@@ -177,6 +235,17 @@ describe Chewy::Query do
177
235
  specify { subject.filter{ name == 'John' }.criteria.filters.should == [{term: {'name' => 'John'}}] }
178
236
  end
179
237
 
238
+ describe '#post_filter' do
239
+ specify { subject.post_filter(term: {field: 'hello'}).should be_a described_class }
240
+ specify { subject.post_filter(term: {field: 'hello'}).should_not == subject }
241
+ specify { expect { subject.post_filter(term: {field: 'hello'}) }.not_to change { subject.criteria.post_filters } }
242
+ specify { subject.post_filter([{term: {field: 'hello'}}, {term: {field: 'world'}}]).criteria.post_filters
243
+ .should == [{term: {field: 'hello'}}, {term: {field: 'world'}}] }
244
+
245
+ specify { expect { subject.post_filter{ name == 'John' } }.not_to change { subject.criteria.post_filters } }
246
+ specify { subject.post_filter{ name == 'John' }.criteria.post_filters.should == [{term: {'name' => 'John'}}] }
247
+ end
248
+
180
249
  describe '#order' do
181
250
  specify { subject.order(field: 'hello').should be_a described_class }
182
251
  specify { subject.order(field: 'hello').should_not == subject }
@@ -251,7 +320,7 @@ describe Chewy::Query do
251
320
  .should == [{term: {'name' => 'name'}}, {term: {'age' => 42}}] }
252
321
  end
253
322
 
254
- describe 'to_a' do
323
+ describe '#to_a' do
255
324
  before { stub_model(:city) }
256
325
  let(:cities) { 3.times.map { |i| City.create! name: "name#{i}", rating: i } }
257
326
 
@@ -282,8 +351,8 @@ describe Chewy::Query do
282
351
  specify { CitiesIndex.all.first._score.should be > 0 }
283
352
  specify { CitiesIndex.query(match: {name: 'name0'}).first._score.should be > 0 }
284
353
 
285
- specify { CitiesIndex.order(:rating).first._explanation.should be_nil }
286
- specify { CitiesIndex.order(:rating).explain.first._explanation.should be_present }
354
+ specify { CitiesIndex.order(:rating).first._data['_explanation'].should be_nil }
355
+ specify { CitiesIndex.order(:rating).explain.first._data['_explanation'].should be_present }
287
356
  end
288
357
 
289
358
  context 'sourceless' do
@@ -1,7 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe :update_index do
4
- include ClassHelpers
5
4
  before { Chewy.client.indices.delete index: '*' }
6
5
 
7
6
  before do
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chewy::Runtime::Version do
4
+ describe '#major' do
5
+ specify { described_class.new('1.2.3').major.should == 1 }
6
+ specify { described_class.new('1.2').major.should == 1 }
7
+ specify { described_class.new(1.2).major.should == 1 }
8
+ specify { described_class.new('1').major.should == 1 }
9
+ specify { described_class.new('').major.should == 0 }
10
+ end
11
+
12
+ describe '#minor' do
13
+ specify { described_class.new('1.2.3').minor.should == 2 }
14
+ specify { described_class.new('1.2').minor.should == 2 }
15
+ specify { described_class.new(1.2).minor.should == 2 }
16
+ specify { described_class.new('1').minor.should == 0 }
17
+ end
18
+
19
+ describe '#patch' do
20
+ specify { described_class.new('1.2.3').patch.should == 3 }
21
+ specify { described_class.new('1.2.3.pre1').patch.should == 3 }
22
+ specify { described_class.new('1.2').patch.should == 0 }
23
+ specify { described_class.new(1.2).patch.should == 0 }
24
+ end
25
+
26
+ describe '#to_s' do
27
+ specify { described_class.new('1.2.3').to_s.should == '1.2.3' }
28
+ specify { described_class.new('1.2.3.pre1').to_s.should == '1.2.3' }
29
+ specify { described_class.new('1.2').to_s.should == '1.2.0' }
30
+ specify { described_class.new(1.2).to_s.should == '1.2.0' }
31
+ specify { described_class.new('1').to_s.should == '1.0.0' }
32
+ specify { described_class.new('').to_s.should == '0.0.0' }
33
+ end
34
+
35
+ describe '#<=>' do
36
+ specify { described_class.new('1.2.3').should == '1.2.3' }
37
+ specify { described_class.new('1.2.3').should be < '1.2.4' }
38
+ specify { described_class.new('1.2.3').should be < '1.2.10' }
39
+ specify { described_class.new('1.10.2').should be == '1.10.2' }
40
+ specify { described_class.new('1.10.2').should be > '1.7.2' }
41
+ specify { described_class.new('2.10.2').should be > '1.7.2' }
42
+ specify { described_class.new('1.10.2').should be < '2.7.2' }
43
+ specify { described_class.new('1.10.2').should be < described_class.new('2.7.2') }
44
+ specify { described_class.new('1.10.2').should be < 2.7 }
45
+ specify { described_class.new('1.10.2').should be < 1.11 }
46
+ specify { described_class.new('1.2.0').should be == '1.2' }
47
+ end
48
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chewy::Runtime do
4
+ describe '.version' do
5
+ specify { described_class.version.should be_a(described_class::Version) }
6
+ specify { described_class.version.should be >= '1.0' }
7
+ specify { described_class.version.should be < '1.3' }
8
+ end
9
+ end
@@ -7,12 +7,26 @@ describe Chewy::Type::Adapter::ActiveRecord do
7
7
  specify { described_class.new(City).name.should == 'City' }
8
8
  specify { described_class.new(City.order(:id)).name.should == 'City' }
9
9
  specify { described_class.new(City, name: 'town').name.should == 'Town' }
10
+
11
+ context do
12
+ before { stub_model('namespace/city') }
13
+
14
+ specify { described_class.new(Namespace::City).name.should == 'City' }
15
+ specify { described_class.new(Namespace::City.order(:id)).name.should == 'City' }
16
+ end
10
17
  end
11
18
 
12
19
  describe '#type_name' do
13
20
  specify { described_class.new(City).type_name.should == 'city' }
14
21
  specify { described_class.new(City.order(:id)).type_name.should == 'city' }
15
22
  specify { described_class.new(City, name: 'town').type_name.should == 'town' }
23
+
24
+ context do
25
+ before { stub_model('namespace/city') }
26
+
27
+ specify { described_class.new(Namespace::City).type_name.should == 'city' }
28
+ specify { described_class.new(Namespace::City.order(:id)).type_name.should == 'city' }
29
+ end
16
30
  end
17
31
 
18
32
  describe '#import' do
@@ -43,6 +57,7 @@ describe Chewy::Type::Adapter::ActiveRecord do
43
57
  {delete: deleted.last(2)}] }
44
58
 
45
59
  specify { import(cities.map(&:id)).should == [{index: cities}] }
60
+ specify { import(deleted.map(&:id)).should == [{delete: deleted.map(&:id)}] }
46
61
  specify { import(cities.map(&:id), batch_size: 2)
47
62
  .should == [{index: cities.first(2)}, {index: cities.last(1)}] }
48
63
  specify { import(cities.map(&:id), deleted.map(&:id))
@@ -52,6 +67,43 @@ describe Chewy::Type::Adapter::ActiveRecord do
52
67
  {index: cities.last(1)},
53
68
  {delete: deleted.first(2).map(&:id)},
54
69
  {delete: deleted.last(1).map(&:id)}] }
70
+
71
+ context do
72
+ before { deleted.map { |object| object.stub(delete_from_index?: true, destroyed?: true) } }
73
+ specify { import(deleted).should == [{delete: deleted}] }
74
+ end
75
+
76
+ context do
77
+ before { deleted.map { |object| object.stub(delete_from_index?: true, destroyed?: false) } }
78
+ specify { import(deleted).should == [{delete: deleted}] }
79
+ end
80
+
81
+ context do
82
+ before { deleted.map { |object| object.stub(delete_from_index?: false, destroyed?: true) } }
83
+ specify { import(deleted).should == [{delete: deleted}] }
84
+ end
85
+
86
+ context do
87
+ before { deleted.map { |object| object.stub(delete_from_index?: false, destroyed?: false) } }
88
+ specify { import(deleted).should == [{index: deleted}] }
89
+ end
90
+ end
91
+
92
+ describe '#delete_from_index?' do
93
+ before do
94
+ stub_model(:city) do
95
+ def delete_from_index?
96
+ rating == 42
97
+ end
98
+ end
99
+ end
100
+ let!(:cities) { 3.times.map { |i| City.create! } }
101
+ let!(:deleted) { 3.times.map { |i| City.create!(rating: 42) } }
102
+ subject { described_class.new(City) }
103
+
104
+ specify { import(cities, deleted).should == [{index: cities, delete: deleted}] }
105
+ specify { import(cities.map(&:id), deleted.map(&:id))
106
+ .should == [{index: cities, delete: deleted}] }
55
107
  end
56
108
 
57
109
  context 'custom primary_key' do
@@ -8,6 +8,12 @@ describe Chewy::Type::Adapter::Object do
8
8
  specify { described_class.new(:products).name.should == 'Products' }
9
9
  specify { described_class.new(Product).name.should == 'Product' }
10
10
  specify { described_class.new(Product, name: 'house').name.should == 'House' }
11
+
12
+ context do
13
+ before { stub_class('namespace/product') }
14
+
15
+ specify { described_class.new(Namespace::Product).name.should == 'Product' }
16
+ end
11
17
  end
12
18
 
13
19
  describe '#type_name' do
@@ -15,6 +21,12 @@ describe Chewy::Type::Adapter::Object do
15
21
  specify { described_class.new(:products).type_name.should == 'products' }
16
22
  specify { described_class.new(Product).type_name.should == 'product' }
17
23
  specify { described_class.new(Product, name: 'house').type_name.should == 'house' }
24
+
25
+ context do
26
+ before { stub_class('namespace/product') }
27
+
28
+ specify { described_class.new(Namespace::Product).type_name.should == 'product' }
29
+ end
18
30
  end
19
31
 
20
32
  describe '#import' do
@@ -41,6 +53,27 @@ describe Chewy::Type::Adapter::Object do
41
53
  {index: objects.first(2)},
42
54
  {index: objects.last(1), delete: deleted.first(1)},
43
55
  {delete: deleted.last(1)}] }
56
+
57
+ context do
58
+ let(:deleted) { 2.times.map { |i| double(delete_from_index?: true, destroyed?: true) } }
59
+ specify { import(deleted).should == [{delete: deleted}] }
60
+ end
61
+
62
+ context do
63
+ let(:deleted) { 2.times.map { |i| double(delete_from_index?: true, destroyed?: false) } }
64
+ specify { import(deleted).should == [{delete: deleted}] }
65
+ end
66
+
67
+
68
+ context do
69
+ let(:deleted) { 2.times.map { |i| double(delete_from_index?: false, destroyed?: true) } }
70
+ specify { import(deleted).should == [{delete: deleted}] }
71
+ end
72
+
73
+ context do
74
+ let(:deleted) { 2.times.map { |i| double(delete_from_index?: false, destroyed?: false) } }
75
+ specify { import(deleted).should == [{index: deleted}] }
76
+ end
44
77
  end
45
78
 
46
79
  context do