chewy 6.0.0 → 7.6.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 (188) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +39 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  5. data/.github/PULL_REQUEST_TEMPLATE.md +16 -0
  6. data/.github/dependabot.yml +42 -0
  7. data/.github/workflows/ruby.yml +60 -0
  8. data/.rubocop.yml +16 -8
  9. data/.rubocop_todo.yml +110 -22
  10. data/CHANGELOG.md +396 -105
  11. data/CODE_OF_CONDUCT.md +14 -0
  12. data/CONTRIBUTING.md +63 -0
  13. data/Gemfile +4 -10
  14. data/Guardfile +3 -1
  15. data/README.md +497 -275
  16. data/chewy.gemspec +5 -20
  17. data/gemfiles/base.gemfile +12 -0
  18. data/gemfiles/rails.6.1.activerecord.gemfile +10 -15
  19. data/gemfiles/rails.7.0.activerecord.gemfile +14 -0
  20. data/gemfiles/rails.7.1.activerecord.gemfile +14 -0
  21. data/lib/chewy/config.rb +60 -52
  22. data/lib/chewy/elastic_client.rb +31 -0
  23. data/lib/chewy/errors.rb +7 -10
  24. data/lib/chewy/fields/base.rb +79 -13
  25. data/lib/chewy/fields/root.rb +4 -14
  26. data/lib/chewy/index/actions.rb +54 -37
  27. data/lib/chewy/{type → index}/adapter/active_record.rb +30 -6
  28. data/lib/chewy/{type → index}/adapter/base.rb +2 -3
  29. data/lib/chewy/{type → index}/adapter/object.rb +27 -31
  30. data/lib/chewy/{type → index}/adapter/orm.rb +17 -18
  31. data/lib/chewy/index/aliases.rb +14 -5
  32. data/lib/chewy/index/crutch.rb +40 -0
  33. data/lib/chewy/index/import/bulk_builder.rb +311 -0
  34. data/lib/chewy/{type → index}/import/bulk_request.rb +6 -7
  35. data/lib/chewy/{type → index}/import/journal_builder.rb +11 -12
  36. data/lib/chewy/{type → index}/import/routine.rb +18 -17
  37. data/lib/chewy/{type → index}/import.rb +76 -32
  38. data/lib/chewy/{type → index}/mapping.rb +29 -34
  39. data/lib/chewy/index/observe/active_record_methods.rb +87 -0
  40. data/lib/chewy/index/observe/callback.rb +34 -0
  41. data/lib/chewy/index/observe.rb +17 -0
  42. data/lib/chewy/index/specification.rb +1 -0
  43. data/lib/chewy/{type → index}/syncer.rb +59 -59
  44. data/lib/chewy/{type → index}/witchcraft.rb +11 -7
  45. data/lib/chewy/{type → index}/wrapper.rb +2 -2
  46. data/lib/chewy/index.rb +67 -94
  47. data/lib/chewy/journal.rb +25 -14
  48. data/lib/chewy/log_subscriber.rb +5 -1
  49. data/lib/chewy/minitest/helpers.rb +86 -13
  50. data/lib/chewy/minitest/search_index_receiver.rb +24 -26
  51. data/lib/chewy/railtie.rb +6 -20
  52. data/lib/chewy/rake_helper.rb +169 -113
  53. data/lib/chewy/rspec/build_query.rb +12 -0
  54. data/lib/chewy/rspec/helpers.rb +55 -0
  55. data/lib/chewy/rspec/update_index.rb +55 -44
  56. data/lib/chewy/rspec.rb +2 -0
  57. data/lib/chewy/runtime/version.rb +1 -1
  58. data/lib/chewy/runtime.rb +1 -1
  59. data/lib/chewy/search/loader.rb +19 -41
  60. data/lib/chewy/search/parameters/collapse.rb +16 -0
  61. data/lib/chewy/search/parameters/concerns/query_storage.rb +2 -2
  62. data/lib/chewy/search/parameters/ignore_unavailable.rb +27 -0
  63. data/lib/chewy/search/parameters/indices.rb +13 -58
  64. data/lib/chewy/search/parameters/knn.rb +16 -0
  65. data/lib/chewy/search/parameters/order.rb +6 -19
  66. data/lib/chewy/search/parameters/source.rb +5 -1
  67. data/lib/chewy/search/parameters/storage.rb +1 -1
  68. data/lib/chewy/search/parameters/track_total_hits.rb +16 -0
  69. data/lib/chewy/search/parameters.rb +6 -4
  70. data/lib/chewy/search/query_proxy.rb +9 -2
  71. data/lib/chewy/search/request.rb +169 -134
  72. data/lib/chewy/search/response.rb +5 -5
  73. data/lib/chewy/search/scoping.rb +7 -8
  74. data/lib/chewy/search/scrolling.rb +13 -13
  75. data/lib/chewy/search.rb +9 -19
  76. data/lib/chewy/stash.rb +19 -30
  77. data/lib/chewy/strategy/active_job.rb +1 -1
  78. data/lib/chewy/strategy/atomic_no_refresh.rb +18 -0
  79. data/lib/chewy/strategy/base.rb +10 -0
  80. data/lib/chewy/strategy/delayed_sidekiq/scheduler.rb +168 -0
  81. data/lib/chewy/strategy/delayed_sidekiq/worker.rb +76 -0
  82. data/lib/chewy/strategy/delayed_sidekiq.rb +30 -0
  83. data/lib/chewy/strategy/lazy_sidekiq.rb +64 -0
  84. data/lib/chewy/strategy/sidekiq.rb +2 -1
  85. data/lib/chewy/strategy.rb +6 -19
  86. data/lib/chewy/version.rb +1 -1
  87. data/lib/chewy.rb +39 -86
  88. data/lib/generators/chewy/install_generator.rb +1 -1
  89. data/lib/tasks/chewy.rake +36 -32
  90. data/migration_guide.md +46 -8
  91. data/spec/chewy/config_spec.rb +16 -41
  92. data/spec/chewy/elastic_client_spec.rb +26 -0
  93. data/spec/chewy/fields/base_spec.rb +432 -147
  94. data/spec/chewy/fields/root_spec.rb +20 -28
  95. data/spec/chewy/fields/time_fields_spec.rb +5 -5
  96. data/spec/chewy/index/actions_spec.rb +368 -59
  97. data/spec/chewy/{type → index}/adapter/active_record_spec.rb +156 -40
  98. data/spec/chewy/{type → index}/adapter/object_spec.rb +21 -6
  99. data/spec/chewy/index/aliases_spec.rb +3 -3
  100. data/spec/chewy/index/import/bulk_builder_spec.rb +494 -0
  101. data/spec/chewy/{type → index}/import/bulk_request_spec.rb +5 -12
  102. data/spec/chewy/{type → index}/import/journal_builder_spec.rb +9 -19
  103. data/spec/chewy/{type → index}/import/routine_spec.rb +19 -19
  104. data/spec/chewy/{type → index}/import_spec.rb +164 -98
  105. data/spec/chewy/index/mapping_spec.rb +135 -0
  106. data/spec/chewy/index/observe/active_record_methods_spec.rb +68 -0
  107. data/spec/chewy/index/observe/callback_spec.rb +139 -0
  108. data/spec/chewy/index/observe_spec.rb +143 -0
  109. data/spec/chewy/index/settings_spec.rb +3 -1
  110. data/spec/chewy/index/specification_spec.rb +20 -30
  111. data/spec/chewy/{type → index}/syncer_spec.rb +14 -19
  112. data/spec/chewy/{type → index}/witchcraft_spec.rb +20 -22
  113. data/spec/chewy/index/wrapper_spec.rb +100 -0
  114. data/spec/chewy/index_spec.rb +60 -105
  115. data/spec/chewy/journal_spec.rb +25 -74
  116. data/spec/chewy/minitest/helpers_spec.rb +123 -15
  117. data/spec/chewy/minitest/search_index_receiver_spec.rb +28 -30
  118. data/spec/chewy/multi_search_spec.rb +4 -5
  119. data/spec/chewy/rake_helper_spec.rb +315 -55
  120. data/spec/chewy/rspec/build_query_spec.rb +34 -0
  121. data/spec/chewy/rspec/helpers_spec.rb +61 -0
  122. data/spec/chewy/rspec/update_index_spec.rb +74 -71
  123. data/spec/chewy/runtime_spec.rb +2 -2
  124. data/spec/chewy/search/loader_spec.rb +19 -53
  125. data/spec/chewy/search/pagination/kaminari_examples.rb +4 -6
  126. data/spec/chewy/search/pagination/kaminari_spec.rb +2 -2
  127. data/spec/chewy/search/parameters/collapse_spec.rb +5 -0
  128. data/spec/chewy/search/parameters/ignore_unavailable_spec.rb +67 -0
  129. data/spec/chewy/search/parameters/indices_spec.rb +26 -117
  130. data/spec/chewy/search/parameters/knn_spec.rb +5 -0
  131. data/spec/chewy/search/parameters/order_spec.rb +18 -11
  132. data/spec/chewy/search/parameters/query_storage_examples.rb +67 -21
  133. data/spec/chewy/search/parameters/search_after_spec.rb +4 -1
  134. data/spec/chewy/search/parameters/source_spec.rb +8 -2
  135. data/spec/chewy/search/parameters/track_total_hits_spec.rb +5 -0
  136. data/spec/chewy/search/parameters_spec.rb +18 -4
  137. data/spec/chewy/search/query_proxy_spec.rb +68 -17
  138. data/spec/chewy/search/request_spec.rb +292 -110
  139. data/spec/chewy/search/response_spec.rb +12 -12
  140. data/spec/chewy/search/scrolling_spec.rb +10 -17
  141. data/spec/chewy/search_spec.rb +40 -34
  142. data/spec/chewy/stash_spec.rb +9 -21
  143. data/spec/chewy/strategy/active_job_spec.rb +16 -16
  144. data/spec/chewy/strategy/atomic_no_refresh_spec.rb +60 -0
  145. data/spec/chewy/strategy/atomic_spec.rb +9 -10
  146. data/spec/chewy/strategy/delayed_sidekiq_spec.rb +208 -0
  147. data/spec/chewy/strategy/lazy_sidekiq_spec.rb +214 -0
  148. data/spec/chewy/strategy/sidekiq_spec.rb +12 -12
  149. data/spec/chewy/strategy_spec.rb +19 -15
  150. data/spec/chewy_spec.rb +24 -107
  151. data/spec/spec_helper.rb +3 -22
  152. data/spec/support/active_record.rb +25 -7
  153. metadata +78 -339
  154. data/.circleci/config.yml +0 -240
  155. data/Appraisals +0 -81
  156. data/gemfiles/rails.5.2.activerecord.gemfile +0 -17
  157. data/gemfiles/rails.5.2.mongoid.6.4.gemfile +0 -17
  158. data/gemfiles/rails.6.0.activerecord.gemfile +0 -17
  159. data/gemfiles/sequel.4.45.gemfile +0 -11
  160. data/lib/chewy/backports/deep_dup.rb +0 -46
  161. data/lib/chewy/backports/duplicable.rb +0 -91
  162. data/lib/chewy/search/pagination/will_paginate.rb +0 -43
  163. data/lib/chewy/search/parameters/types.rb +0 -20
  164. data/lib/chewy/strategy/resque.rb +0 -27
  165. data/lib/chewy/strategy/shoryuken.rb +0 -40
  166. data/lib/chewy/type/actions.rb +0 -43
  167. data/lib/chewy/type/adapter/mongoid.rb +0 -67
  168. data/lib/chewy/type/adapter/sequel.rb +0 -93
  169. data/lib/chewy/type/crutch.rb +0 -32
  170. data/lib/chewy/type/import/bulk_builder.rb +0 -122
  171. data/lib/chewy/type/observe.rb +0 -82
  172. data/lib/chewy/type.rb +0 -120
  173. data/lib/sequel/plugins/chewy_observe.rb +0 -63
  174. data/spec/chewy/search/pagination/will_paginate_examples.rb +0 -63
  175. data/spec/chewy/search/pagination/will_paginate_spec.rb +0 -23
  176. data/spec/chewy/search/parameters/types_spec.rb +0 -5
  177. data/spec/chewy/strategy/resque_spec.rb +0 -46
  178. data/spec/chewy/strategy/shoryuken_spec.rb +0 -70
  179. data/spec/chewy/type/actions_spec.rb +0 -50
  180. data/spec/chewy/type/adapter/mongoid_spec.rb +0 -372
  181. data/spec/chewy/type/adapter/sequel_spec.rb +0 -472
  182. data/spec/chewy/type/import/bulk_builder_spec.rb +0 -194
  183. data/spec/chewy/type/mapping_spec.rb +0 -175
  184. data/spec/chewy/type/observe_spec.rb +0 -137
  185. data/spec/chewy/type/wrapper_spec.rb +0 -100
  186. data/spec/chewy/type_spec.rb +0 -55
  187. data/spec/support/mongoid.rb +0 -93
  188. data/spec/support/sequel.rb +0 -80
@@ -13,14 +13,12 @@ describe Chewy::Journal do
13
13
  end
14
14
 
15
15
  stub_index("#{namespace}cities") do
16
- define_type City do
17
- default_import_options journal: true
18
- end
16
+ index_scope City
17
+ default_import_options journal: true
19
18
  end
20
19
  stub_index("#{namespace}countries") do
21
- define_type Country do
22
- default_import_options journal: true
23
- end
20
+ index_scope Country
21
+ default_import_options journal: true
24
22
  end
25
23
 
26
24
  Chewy.massacre
@@ -67,63 +65,54 @@ describe Chewy::Journal do
67
65
  expected_journal = [
68
66
  {
69
67
  'index_name' => "#{namespace}cities",
70
- 'type_name' => 'city',
71
68
  'action' => 'index',
72
69
  'references' => ['1'].map(&Base64.method(:encode64)),
73
70
  'created_at' => time.utc.as_json
74
71
  },
75
72
  {
76
73
  'index_name' => "#{namespace}cities",
77
- 'type_name' => 'city',
78
74
  'action' => 'index',
79
75
  'references' => ['2'].map(&Base64.method(:encode64)),
80
76
  'created_at' => time.utc.as_json
81
77
  },
82
78
  {
83
79
  'index_name' => "#{namespace}countries",
84
- 'type_name' => 'country',
85
80
  'action' => 'index',
86
81
  'references' => ['1'].map(&Base64.method(:encode64)),
87
82
  'created_at' => time.utc.as_json
88
83
  },
89
84
  {
90
85
  'index_name' => "#{namespace}countries",
91
- 'type_name' => 'country',
92
86
  'action' => 'index',
93
87
  'references' => ['2'].map(&Base64.method(:encode64)),
94
88
  'created_at' => time.utc.as_json
95
89
  },
96
90
  {
97
91
  'index_name' => "#{namespace}countries",
98
- 'type_name' => 'country',
99
92
  'action' => 'index',
100
93
  'references' => ['3'].map(&Base64.method(:encode64)),
101
94
  'created_at' => time.utc.as_json
102
95
  },
103
96
  {
104
97
  'index_name' => "#{namespace}cities",
105
- 'type_name' => 'city',
106
98
  'action' => 'index',
107
99
  'references' => %w[1 2].map(&Base64.method(:encode64)),
108
100
  'created_at' => import_time.utc.as_json
109
101
  },
110
102
  {
111
103
  'index_name' => "#{namespace}countries",
112
- 'type_name' => 'country',
113
104
  'action' => 'index',
114
105
  'references' => %w[1 2 3].map(&Base64.method(:encode64)),
115
106
  'created_at' => import_time.utc.as_json
116
107
  },
117
108
  {
118
109
  'index_name' => "#{namespace}cities",
119
- 'type_name' => 'city',
120
110
  'action' => 'index',
121
111
  'references' => ['1'].map(&Base64.method(:encode64)),
122
112
  'created_at' => update_time.utc.as_json
123
113
  },
124
114
  {
125
115
  'index_name' => "#{namespace}countries",
126
- 'type_name' => 'country',
127
116
  'action' => 'delete',
128
117
  'references' => ['2'].map(&Base64.method(:encode64)),
129
118
  'created_at' => destroy_time.utc.as_json
@@ -137,7 +126,7 @@ describe Chewy::Journal do
137
126
  expect(journal_entries.size).to eq 4
138
127
 
139
128
  # simulate lost data
140
- Chewy.client.delete(index: "#{Chewy.settings[:prefix]}_cities", type: 'city', id: 1, refresh: true)
129
+ Chewy.client.delete(index: "#{Chewy.settings[:prefix]}_cities", id: 1, refresh: true)
141
130
  expect(cities_index.count).to eq 1
142
131
 
143
132
  described_class.new.apply(time)
@@ -166,14 +155,12 @@ describe Chewy::Journal do
166
155
  end
167
156
 
168
157
  stub_index(:cities) do
169
- define_type City do
170
- default_import_options journal: true
171
- end
158
+ index_scope City
159
+ default_import_options journal: true
172
160
  end
173
161
  stub_index(:countries) do
174
- define_type Country do
175
- default_import_options journal: true
176
- end
162
+ index_scope Country
163
+ default_import_options journal: true
177
164
  end
178
165
  end
179
166
 
@@ -192,8 +179,8 @@ describe Chewy::Journal do
192
179
  Array.new(2) { |i| Country.create!(id: i + 1) }
193
180
 
194
181
  # simulate lost data
195
- Chewy.client.delete(index: 'cities', type: 'city', id: 1, refresh: true)
196
- Chewy.client.delete(index: 'countries', type: 'country', id: 1, refresh: true)
182
+ Chewy.client.delete(index: 'cities', id: 1, refresh: true)
183
+ Chewy.client.delete(index: 'countries', id: 1, refresh: true)
197
184
  expect(CitiesIndex.all.to_a.length).to eq 1
198
185
  expect(CountriesIndex.all.to_a.length).to eq 1
199
186
 
@@ -203,7 +190,7 @@ describe Chewy::Journal do
203
190
  expect(CountriesIndex.all.to_a.length).to eq 1
204
191
 
205
192
  # Replay on both
206
- Chewy.client.delete(index: 'cities', type: 'city', id: 1, refresh: true)
193
+ Chewy.client.delete(index: 'cities', id: 1, refresh: true)
207
194
  expect(CitiesIndex.all.to_a.length).to eq 1
208
195
  expect(described_class.new(CitiesIndex, CountriesIndex).apply(time)).to eq(4)
209
196
  expect(CitiesIndex.all.to_a.length).to eq 2
@@ -212,59 +199,23 @@ describe Chewy::Journal do
212
199
  end
213
200
  end
214
201
 
215
- context 'retries' do
216
- let(:time) { Time.now.to_i }
217
- before do
218
- Timecop.freeze
219
- Chewy.strategy(:urgent)
220
- City.create!(id: 1)
221
- end
222
-
223
- after do
224
- Chewy.strategy.pop
225
- Timecop.return
226
- end
227
-
228
- specify 'journal was cleaned after the first call' do
229
- expect(Chewy::Stash::Journal).to receive(:entries).exactly(2).and_call_original
230
- expect(described_class.new.apply(time)).to eq(1)
231
- end
232
-
233
- context 'endless journal' do
234
- let(:count_of_checks) { 10 } # default
235
- let!(:journal_entries) do
236
- record = Chewy::Stash::Journal.entries(time).first
237
- Array.new(count_of_checks) do |i|
238
- Chewy::Stash::Journal::Journal.new(
239
- record.attributes.merge(
240
- 'created_at' => time.to_i + i,
241
- 'references' => [i.to_s]
242
- )
243
- )
244
- end
245
- end
246
-
247
- specify '10 retries by default' do
248
- expect(Chewy::Stash::Journal)
249
- .to receive(:entries).exactly(count_of_checks) { [journal_entries.shift].compact }
250
- expect(described_class.new.apply(time)).to eq(10)
251
- end
202
+ context 'when order is not preserved' do
203
+ let(:time) { Time.now }
252
204
 
253
- specify 'with :once parameter set' do
254
- expect(Chewy::Stash::Journal)
255
- .to receive(:entries).exactly(1) { [journal_entries.shift].compact }
256
- expect(described_class.new.apply(time, retries: 1)).to eq(1)
205
+ it 'paginates properly through all items' do
206
+ Chewy.strategy(:urgent) do
207
+ Timecop.travel(time + 1.minute) { City.create!(id: 2) }
208
+ Timecop.travel(time + 3.minute) { City.create!(id: 4) }
209
+ Timecop.travel(time + 2.minute) { City.create!(id: 1) }
210
+ Timecop.travel(time + 4.minute) { City.create!(id: 3) }
257
211
  end
258
212
 
259
- context 'with retries parameter set' do
260
- let(:retries) { 5 }
213
+ CitiesIndex.purge!
214
+ expect(CitiesIndex.all.to_a.length).to eq 0
261
215
 
262
- specify do
263
- expect(Chewy::Stash::Journal)
264
- .to receive(:entries).exactly(retries) { [journal_entries.shift].compact }
265
- expect(described_class.new.apply(time, retries: retries)).to eq(5)
266
- end
267
- end
216
+ # Replay on specific index
217
+ expect(described_class.new(CitiesIndex).apply(time, fetch_limit: 2)).to eq(4)
218
+ expect(CitiesIndex.all.to_a.map(&:id).sort).to eq([1, 2, 3, 4])
268
219
  end
269
220
  end
270
221
  end
@@ -10,7 +10,11 @@ describe :minitest_helper do
10
10
  expect(haystack).to include(needle)
11
11
  end
12
12
 
13
- include ::Chewy::Minitest::Helpers
13
+ include Chewy::Minitest::Helpers
14
+
15
+ def assert_equal(expected, actual, message)
16
+ raise message unless expected == actual
17
+ end
14
18
 
15
19
  before do
16
20
  Chewy.massacre
@@ -18,8 +22,112 @@ describe :minitest_helper do
18
22
 
19
23
  before do
20
24
  stub_index(:dummies) do
21
- define_type :dummy do
22
- root value: ->(_o) { {} }
25
+ root value: ->(_o) { {} }
26
+ end
27
+ end
28
+
29
+ describe 'mock_elasticsearch_response' do
30
+ let(:hits) do
31
+ [
32
+ {
33
+ '_index' => 'dummies',
34
+ '_type' => '_doc',
35
+ '_id' => '2',
36
+ '_score' => 3.14,
37
+ '_source' => source
38
+ }
39
+ ]
40
+ end
41
+
42
+ let(:source) { {'name' => 'some_name', id: '2'} }
43
+ let(:sources) { [source] }
44
+
45
+ context 'mocks by raw response' do
46
+ let(:raw_response) do
47
+ {
48
+ 'took' => 4,
49
+ 'timed_out' => false,
50
+ '_shards' => {
51
+ 'total' => 1,
52
+ 'successful' => 1,
53
+ 'skipped' => 0,
54
+ 'failed' => 0
55
+ },
56
+ 'hits' => {
57
+ 'total' => {
58
+ 'value' => 1,
59
+ 'relation' => 'eq'
60
+ },
61
+ 'max_score' => 1.0,
62
+ 'hits' => hits
63
+ }
64
+ }
65
+ end
66
+
67
+ specify do
68
+ mock_elasticsearch_response(DummiesIndex, raw_response) do
69
+ expect(DummiesIndex.query({}).hits).to eq(hits)
70
+ end
71
+ end
72
+ end
73
+
74
+ context 'mocks by response sources' do
75
+ specify do
76
+ mock_elasticsearch_response_sources(DummiesIndex, sources) do
77
+ expect(DummiesIndex.query({}).hits).to eq(hits)
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ describe 'assert correct elasticsearch query' do
84
+ let(:query) do
85
+ DummiesIndex.filter.should { multi_match foo: 'bar' }.filter { match foo: 'bar' }
86
+ end
87
+
88
+ let(:expected_query) do
89
+ {
90
+ index: ['dummies'],
91
+ body: {
92
+ query: {
93
+ bool: {
94
+ filter: {
95
+ bool: {
96
+ must: {
97
+ match: {foo: 'bar'}
98
+ },
99
+ should: {
100
+ multi_match: {foo: 'bar'}
101
+ }
102
+ }
103
+ }
104
+ }
105
+ }
106
+ }
107
+ }
108
+ end
109
+
110
+ context 'will be built' do
111
+ specify do
112
+ expect { assert_elasticsearch_query(query, expected_query) }.not_to raise_error
113
+ end
114
+ end
115
+
116
+ context 'will not be built' do
117
+ let(:unexpected_query) do
118
+ {
119
+ index: ['what?'],
120
+ body: {}
121
+ }
122
+ end
123
+
124
+ let(:unexpected_query_error_message) do
125
+ 'got {:index=>["dummies"], :body=>{:query=>{:bool=>{:filter=>{:bool=>{:must=>{:match=>{:foo=>"bar"}}, :should=>{:multi_match=>{:foo=>"bar"}}}}}}}} instead of expected query.'
126
+ end
127
+
128
+ specify do
129
+ expect { assert_elasticsearch_query(query, unexpected_query) }
130
+ .to raise_error(RuntimeError, unexpected_query_error_message)
23
131
  end
24
132
  end
25
133
  end
@@ -27,45 +135,45 @@ describe :minitest_helper do
27
135
  context 'assert_indexes' do
28
136
  specify 'doesn\'t fail when index updates correctly' do
29
137
  expect do
30
- assert_indexes DummiesIndex::Dummy do
31
- DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}]
138
+ assert_indexes DummiesIndex do
139
+ DummiesIndex.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}]
32
140
  end
33
141
  end.to_not raise_error
34
142
  end
35
143
 
36
144
  specify 'fails when index doesn\'t update' do
37
145
  expect do
38
- assert_indexes DummiesIndex::Dummy do
146
+ assert_indexes DummiesIndex do
39
147
  end
40
148
  end.to raise_error(RSpec::Expectations::ExpectationNotMetError)
41
149
  end
42
150
 
43
151
  specify 'SearchIndexReceiver catches the indexes' do
44
- receiver = assert_indexes DummiesIndex::Dummy do
45
- DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}]
152
+ receiver = assert_indexes DummiesIndex do
153
+ DummiesIndex.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}]
46
154
  end
47
155
 
48
156
  expect(receiver).to be_a(SearchIndexReceiver)
49
157
 
50
158
  expect(
51
- receiver.indexes_for(DummiesIndex::Dummy)
159
+ receiver.indexes_for(DummiesIndex)
52
160
  .map { |index| index[:_id] }
53
161
  ).to match_array([41, 42])
54
162
  end
55
163
 
56
164
  specify 'Real index is bypassed when asserting' do
57
- expect(DummiesIndex::Dummy).not_to receive(:bulk)
165
+ expect(DummiesIndex).not_to receive(:bulk)
58
166
 
59
- assert_indexes DummiesIndex::Dummy do
60
- DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}]
167
+ assert_indexes DummiesIndex do
168
+ DummiesIndex.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}]
61
169
  end
62
170
  end
63
171
 
64
172
  specify 'Real index is allowed when asserting' do
65
- expect(DummiesIndex::Dummy).to receive(:bulk)
173
+ expect(DummiesIndex).to receive(:bulk)
66
174
 
67
- assert_indexes DummiesIndex::Dummy, bypass_actual_index: false do
68
- DummiesIndex::Dummy.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}]
175
+ assert_indexes DummiesIndex, bypass_actual_index: false do
176
+ DummiesIndex.bulk body: [{index: {_id: 42, data: {}}}, {index: {_id: 41, data: {}}}]
69
177
  end
70
178
  end
71
179
  end
@@ -24,99 +24,97 @@ describe :search_index_receiver do
24
24
  SearchIndexReceiver.new
25
25
  end
26
26
 
27
+ let(:dummy_class) { Struct.new(:id) }
28
+
27
29
  before do
28
30
  stub_index(:dummies) do
29
- define_type :fizz do
30
- root value: ->(_o) { {} }
31
- end
31
+ root value: ->(_o) { {} }
32
32
  end
33
33
 
34
34
  stub_index(:dummies2) do
35
- define_type :buzz do
36
- root value: ->(_o) { {} }
37
- end
35
+ root value: ->(_o) { {} }
38
36
  end
39
37
  end
40
38
 
41
39
  context 'catch' do
42
40
  specify 'archives more than one type' do
43
- receiver.catch search_request(2), DummiesIndex::Fizz
44
- receiver.catch search_request(3), Dummies2Index::Buzz
45
- expect(receiver.indexes.keys).to match_array([DummiesIndex::Fizz, Dummies2Index::Buzz])
41
+ receiver.catch search_request(2), DummiesIndex
42
+ receiver.catch search_request(3), Dummies2Index
43
+ expect(receiver.indexes.keys).to match_array([DummiesIndex, Dummies2Index])
46
44
  end
47
45
  end
48
46
 
49
47
  context 'indexes_for' do
50
48
  before do
51
- receiver.catch search_request(2), DummiesIndex::Fizz
52
- receiver.catch search_request(3), Dummies2Index::Buzz
49
+ receiver.catch search_request(2), DummiesIndex
50
+ receiver.catch search_request(3), Dummies2Index
53
51
  end
54
52
 
55
53
  specify 'returns indexes for a specific type' do
56
- expect(parse_request(receiver.indexes_for(DummiesIndex::Fizz))).to match_array([1, 2])
54
+ expect(parse_request(receiver.indexes_for(DummiesIndex))).to match_array([1, 2])
57
55
  end
58
56
 
59
57
  specify 'returns only indexes for all types' do
60
58
  index_responses = receiver.indexes
61
- expect(index_responses.keys).to match_array([DummiesIndex::Fizz, Dummies2Index::Buzz])
59
+ expect(index_responses.keys).to match_array([DummiesIndex, Dummies2Index])
62
60
  expect(parse_request(index_responses.values.flatten)).to match_array([1, 2, 1, 2, 3])
63
61
  end
64
62
  end
65
63
 
66
64
  context 'deletes_for' do
67
65
  before do
68
- receiver.catch search_request(2, verb: :delete), DummiesIndex::Fizz
69
- receiver.catch search_request(3, verb: :delete), Dummies2Index::Buzz
66
+ receiver.catch search_request(2, verb: :delete), DummiesIndex
67
+ receiver.catch search_request(3, verb: :delete), Dummies2Index
70
68
  end
71
69
 
72
70
  specify 'returns deletes for a specific type' do
73
- expect(receiver.deletes_for(Dummies2Index::Buzz)).to match_array([1, 2, 3])
71
+ expect(receiver.deletes_for(Dummies2Index)).to match_array([1, 2, 3])
74
72
  end
75
73
 
76
74
  specify 'returns only deletes for all types' do
77
75
  deletes = receiver.deletes
78
- expect(deletes.keys).to match_array([DummiesIndex::Fizz, Dummies2Index::Buzz])
76
+ expect(deletes.keys).to match_array([DummiesIndex, Dummies2Index])
79
77
  expect(deletes.values.flatten).to match_array([1, 2, 1, 2, 3])
80
78
  end
81
79
  end
82
80
 
83
81
  context 'indexed?' do
84
82
  before do
85
- receiver.catch search_request(1), DummiesIndex::Fizz
83
+ receiver.catch search_request(1), DummiesIndex
86
84
  end
87
85
 
88
86
  specify 'validates that an object was indexed' do
89
- dummy = OpenStruct.new(id: 1)
90
- expect(receiver.indexed?(dummy, DummiesIndex::Fizz)).to be(true)
87
+ dummy = dummy_class.new(1)
88
+ expect(receiver.indexed?(dummy, DummiesIndex)).to be(true)
91
89
  end
92
90
 
93
91
  specify 'doesn\'t validate than unindexed objects were indexed' do
94
- dummy = OpenStruct.new(id: 2)
95
- expect(receiver.indexed?(dummy, DummiesIndex::Fizz)).to be(false)
92
+ dummy = dummy_class.new(2)
93
+ expect(receiver.indexed?(dummy, DummiesIndex)).to be(false)
96
94
  end
97
95
  end
98
96
 
99
97
  context 'deleted?' do
100
98
  before do
101
- receiver.catch search_request(1, verb: :delete), DummiesIndex::Fizz
99
+ receiver.catch search_request(1, verb: :delete), DummiesIndex
102
100
  end
103
101
 
104
102
  specify 'validates than an object was deleted' do
105
- dummy = OpenStruct.new(id: 1)
106
- expect(receiver.deleted?(dummy, DummiesIndex::Fizz)).to be(true)
103
+ dummy = dummy_class.new(1)
104
+ expect(receiver.deleted?(dummy, DummiesIndex)).to be(true)
107
105
  end
108
106
 
109
107
  specify 'doesn\'t validate than undeleted objects were deleted' do
110
- dummy = OpenStruct.new(id: 2)
111
- expect(receiver.deleted?(dummy, DummiesIndex::Fizz)).to be(false)
108
+ dummy = dummy_class.new(2)
109
+ expect(receiver.deleted?(dummy, DummiesIndex)).to be(false)
112
110
  end
113
111
  end
114
112
 
115
113
  context 'updated_indexes' do
116
114
  specify 'provides a list of indices updated' do
117
- receiver.catch search_request(2, verb: :delete), DummiesIndex::Fizz
118
- receiver.catch search_request(3, verb: :delete), Dummies2Index::Buzz
119
- expect(receiver.updated_indexes).to match_array([DummiesIndex::Fizz, Dummies2Index::Buzz])
115
+ receiver.catch search_request(2, verb: :delete), DummiesIndex
116
+ receiver.catch search_request(3, verb: :delete), Dummies2Index
117
+ expect(receiver.updated_indexes).to match_array([DummiesIndex, Dummies2Index])
120
118
  end
121
119
  end
122
120
  end
@@ -13,10 +13,9 @@ describe Chewy::MultiSearch do
13
13
  aggs(country: {terms: {field: :country_id}})
14
14
  end
15
15
 
16
- define_type City do
17
- field :name, type: 'keyword'
18
- field :country_id, type: 'keyword'
19
- end
16
+ index_scope City
17
+ field :name, type: 'keyword'
18
+ field :country_id, type: 'keyword'
20
19
  end
21
20
  end
22
21
 
@@ -78,7 +77,7 @@ describe Chewy::MultiSearch do
78
77
  is_expected.to have(2).responses
79
78
  expect(responses[0]).to be_a(Chewy::Search::Response)
80
79
  expect(responses[1]).to be_a(Chewy::Search::Response)
81
- expect(responses[1].wrappers).to all(be_a CitiesIndex::City)
80
+ expect(responses[1].wrappers).to all(be_a CitiesIndex)
82
81
  end
83
82
  end
84
83
  end