chewy 6.0.0 → 7.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +48 -0
  8. data/.rubocop.yml +16 -8
  9. data/.rubocop_todo.yml +110 -22
  10. data/CHANGELOG.md +385 -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 +494 -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 +58 -50
  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 +151 -0
  81. data/lib/chewy/strategy/delayed_sidekiq/worker.rb +52 -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 +14 -39
  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 +202 -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
@@ -3,7 +3,10 @@ require 'spec_helper'
3
3
  describe Chewy::Index::Actions do
4
4
  before { Chewy.massacre }
5
5
 
6
- before { stub_index :dummies }
6
+ before do
7
+ stub_index :dummies
8
+ stub_index :dummies_suffixed
9
+ end
7
10
 
8
11
  describe '.exists?' do
9
12
  specify { expect(DummiesIndex.exists?).to eq(false) }
@@ -25,26 +28,40 @@ describe Chewy::Index::Actions do
25
28
  end
26
29
 
27
30
  context do
28
- before { DummiesIndex.create '2013' }
31
+ before do
32
+ DummiesIndex.create '2013'
33
+ DummiesSuffixedIndex.create 'should_not_appear'
34
+ end
35
+
29
36
  specify { expect(Chewy.client.indices.exists(index: 'dummies')).to eq(true) }
30
37
  specify { expect(Chewy.client.indices.exists(index: 'dummies_2013')).to eq(true) }
31
- specify { expect(DummiesIndex.aliases).to eq([]) }
38
+ specify { expect(DummiesIndex.aliases).to eq(['dummies']) }
32
39
  specify { expect(DummiesIndex.indexes).to eq(['dummies_2013']) }
33
40
  specify { expect(DummiesIndex.create('2013')).to eq(false) }
34
41
  specify { expect(DummiesIndex.create('2014')['acknowledged']).to eq(true) }
35
42
 
36
43
  context do
37
44
  before { DummiesIndex.create '2014' }
45
+
38
46
  specify { expect(DummiesIndex.indexes).to match_array(%w[dummies_2013 dummies_2014]) }
39
47
  end
40
48
  end
41
49
 
42
50
  context do
43
- before { DummiesIndex.create '2013', alias: false }
51
+ before do
52
+ DummiesIndex.create '2013', alias: false
53
+ DummiesSuffixedIndex.create 'should_not_appear'
54
+ end
55
+
44
56
  specify { expect(Chewy.client.indices.exists(index: 'dummies')).to eq(false) }
45
57
  specify { expect(Chewy.client.indices.exists(index: 'dummies_2013')).to eq(true) }
46
58
  specify { expect(DummiesIndex.aliases).to eq([]) }
47
59
  specify { expect(DummiesIndex.indexes).to eq([]) }
60
+ specify { expect(DummiesIndex.exists?).to eq(false) }
61
+ # Unfortunately, without alias we can't figure out that this dummies_2013 index is related to DummiesIndex
62
+ # it would be awesome to have the following specs passing
63
+ # specify { expect(DummiesIndex.indexes).to eq(['dummies_2013']) }
64
+ # specify { expect(DummiesIndex.exists?).to eq(true) }
48
65
  end
49
66
  end
50
67
 
@@ -53,36 +70,62 @@ describe Chewy::Index::Actions do
53
70
  specify { expect(DummiesIndex.create!('2013')['acknowledged']).to eq(true) }
54
71
 
55
72
  context do
56
- before { DummiesIndex.create }
73
+ before do
74
+ DummiesIndex.create
75
+ DummiesSuffixedIndex.create 'should_not_appear'
76
+ end
77
+
78
+ specify do
79
+ expect do
80
+ DummiesIndex.create!
81
+ end.to raise_error(Elasticsearch::Transport::Transport::Errors::BadRequest).with_message(/already exists.*dummies/)
82
+ end
57
83
  specify do
58
- expect { DummiesIndex.create! }.to raise_error(Elasticsearch::Transport::Transport::Errors::BadRequest).with_message(/already exists.*dummies/)
84
+ expect do
85
+ DummiesIndex.create!('2013')
86
+ end.to raise_error(Elasticsearch::Transport::Transport::Errors::BadRequest).with_message(/Invalid alias name \[dummies\]/)
59
87
  end
60
- specify { expect { DummiesIndex.create!('2013') }.to raise_error(Elasticsearch::Transport::Transport::Errors::BadRequest).with_message(/Invalid alias name \[dummies\]/) }
61
88
  end
62
89
 
63
90
  context do
64
- before { DummiesIndex.create! '2013' }
91
+ before do
92
+ DummiesIndex.create! '2013'
93
+ DummiesSuffixedIndex.create! 'should_not_appear'
94
+ end
95
+
65
96
  specify { expect(Chewy.client.indices.exists(index: 'dummies')).to eq(true) }
66
97
  specify { expect(Chewy.client.indices.exists(index: 'dummies_2013')).to eq(true) }
67
- specify { expect(DummiesIndex.aliases).to eq([]) }
98
+ specify { expect(DummiesIndex.aliases).to eq(['dummies']) }
68
99
  specify { expect(DummiesIndex.indexes).to eq(['dummies_2013']) }
69
100
  specify do
70
- expect { DummiesIndex.create!('2013') }.to raise_error(Elasticsearch::Transport::Transport::Errors::BadRequest).with_message(/already exists.*dummies_2013/)
101
+ expect do
102
+ DummiesIndex.create!('2013')
103
+ end.to raise_error(Elasticsearch::Transport::Transport::Errors::BadRequest).with_message(/already exists.*dummies_2013/)
71
104
  end
72
105
  specify { expect(DummiesIndex.create!('2014')['acknowledged']).to eq(true) }
73
106
 
74
107
  context do
75
108
  before { DummiesIndex.create! '2014' }
109
+
76
110
  specify { expect(DummiesIndex.indexes).to match_array(%w[dummies_2013 dummies_2014]) }
77
111
  end
78
112
  end
79
113
 
80
114
  context do
81
- before { DummiesIndex.create! '2013', alias: false }
115
+ before do
116
+ DummiesIndex.create! '2013', alias: false
117
+ DummiesSuffixedIndex.create! 'should_not_appear'
118
+ end
119
+
82
120
  specify { expect(Chewy.client.indices.exists(index: 'dummies')).to eq(false) }
83
121
  specify { expect(Chewy.client.indices.exists(index: 'dummies_2013')).to eq(true) }
84
122
  specify { expect(DummiesIndex.aliases).to eq([]) }
85
123
  specify { expect(DummiesIndex.indexes).to eq([]) }
124
+ specify { expect(DummiesIndex.exists?).to eq(false) }
125
+ # Unfortunately, without alias we can't figure out that this dummies_2013 index is related to DummiesIndex
126
+ # it would be awesome to have the following specs passing
127
+ # specify { expect(DummiesIndex.indexes).to eq(['dummies_2013']) }
128
+ # specify { expect(DummiesIndex.exists?).to eq(true) }
86
129
  end
87
130
  end
88
131
 
@@ -91,27 +134,40 @@ describe Chewy::Index::Actions do
91
134
  specify { expect(DummiesIndex.delete('dummies_2013')).to eq(false) }
92
135
 
93
136
  context do
94
- before { DummiesIndex.create }
137
+ before do
138
+ DummiesIndex.create
139
+ DummiesSuffixedIndex.create 'should_not_appear'
140
+ end
141
+
95
142
  specify { expect(DummiesIndex.delete['acknowledged']).to eq(true) }
96
143
 
97
144
  context do
98
145
  before { DummiesIndex.delete }
99
146
  specify { expect(Chewy.client.indices.exists(index: 'dummies')).to eq(false) }
147
+ specify { expect(Chewy.client.indices.exists(index: 'dummies_suffixed')).to eq(true) }
100
148
  end
101
149
  end
102
150
 
103
151
  context do
104
- before { DummiesIndex.create '2013' }
152
+ before do
153
+ DummiesIndex.create '2013'
154
+ DummiesSuffixedIndex.create 'should_not_appear'
155
+ end
156
+
105
157
  specify { expect(DummiesIndex.delete('2013')['acknowledged']).to eq(true) }
106
158
 
107
159
  context do
108
160
  before { DummiesIndex.delete('2013') }
109
161
  specify { expect(Chewy.client.indices.exists(index: 'dummies')).to eq(false) }
110
162
  specify { expect(Chewy.client.indices.exists(index: 'dummies_2013')).to eq(false) }
163
+ specify { expect(Chewy.client.indices.exists(index: 'dummies_suffixed')).to eq(true) }
111
164
  end
112
165
 
113
166
  context do
114
- before { DummiesIndex.create '2014' }
167
+ before do
168
+ DummiesIndex.create '2014'
169
+ end
170
+
115
171
  specify { expect(DummiesIndex.delete['acknowledged']).to eq(true) }
116
172
 
117
173
  context do
@@ -119,6 +175,7 @@ describe Chewy::Index::Actions do
119
175
  specify { expect(Chewy.client.indices.exists(index: 'dummies')).to eq(false) }
120
176
  specify { expect(Chewy.client.indices.exists(index: 'dummies_2013')).to eq(false) }
121
177
  specify { expect(Chewy.client.indices.exists(index: 'dummies_2014')).to eq(false) }
178
+ specify { expect(Chewy.client.indices.exists(index: 'dummies_suffixed')).to eq(true) }
122
179
  end
123
180
 
124
181
  context do
@@ -126,6 +183,7 @@ describe Chewy::Index::Actions do
126
183
  specify { expect(Chewy.client.indices.exists(index: 'dummies')).to eq(true) }
127
184
  specify { expect(Chewy.client.indices.exists(index: 'dummies_2013')).to eq(true) }
128
185
  specify { expect(Chewy.client.indices.exists(index: 'dummies_2014')).to eq(false) }
186
+ specify { expect(Chewy.client.indices.exists(index: 'dummies_suffixed')).to eq(true) }
129
187
  end
130
188
  end
131
189
  end
@@ -133,30 +191,45 @@ describe Chewy::Index::Actions do
133
191
 
134
192
  describe '.delete!' do
135
193
  specify { expect { DummiesIndex.delete! }.to raise_error(Elasticsearch::Transport::Transport::Errors::NotFound) }
136
- specify { expect { DummiesIndex.delete!('2013') }.to raise_error(Elasticsearch::Transport::Transport::Errors::NotFound) }
194
+ specify do
195
+ expect do
196
+ DummiesIndex.delete!('2013')
197
+ end.to raise_error(Elasticsearch::Transport::Transport::Errors::NotFound)
198
+ end
137
199
 
138
200
  context do
139
- before { DummiesIndex.create }
201
+ before do
202
+ DummiesIndex.create
203
+ DummiesSuffixedIndex.create 'should_not_appear'
204
+ end
205
+
140
206
  specify { expect(DummiesIndex.delete!['acknowledged']).to eq(true) }
141
207
 
142
208
  context do
143
209
  before { DummiesIndex.delete! }
144
210
  specify { expect(Chewy.client.indices.exists(index: 'dummies')).to eq(false) }
211
+ specify { expect(Chewy.client.indices.exists(index: 'dummies_suffixed')).to eq(true) }
145
212
  end
146
213
  end
147
214
 
148
215
  context do
149
- before { DummiesIndex.create '2013' }
216
+ before do
217
+ DummiesIndex.create '2013'
218
+ DummiesSuffixedIndex.create 'should_not_appear'
219
+ end
220
+
150
221
  specify { expect(DummiesIndex.delete!('2013')['acknowledged']).to eq(true) }
151
222
 
152
223
  context do
153
224
  before { DummiesIndex.delete!('2013') }
154
225
  specify { expect(Chewy.client.indices.exists(index: 'dummies')).to eq(false) }
155
226
  specify { expect(Chewy.client.indices.exists(index: 'dummies_2013')).to eq(false) }
227
+ specify { expect(Chewy.client.indices.exists(index: 'dummies_suffixed')).to eq(true) }
156
228
  end
157
229
 
158
230
  context do
159
231
  before { DummiesIndex.create '2014' }
232
+
160
233
  specify { expect(DummiesIndex.delete!['acknowledged']).to eq(true) }
161
234
 
162
235
  context do
@@ -164,6 +237,7 @@ describe Chewy::Index::Actions do
164
237
  specify { expect(Chewy.client.indices.exists(index: 'dummies')).to eq(false) }
165
238
  specify { expect(Chewy.client.indices.exists(index: 'dummies_2013')).to eq(false) }
166
239
  specify { expect(Chewy.client.indices.exists(index: 'dummies_2014')).to eq(false) }
240
+ specify { expect(Chewy.client.indices.exists(index: 'dummies_suffixed')).to eq(true) }
167
241
  end
168
242
 
169
243
  context do
@@ -171,6 +245,7 @@ describe Chewy::Index::Actions do
171
245
  specify { expect(Chewy.client.indices.exists(index: 'dummies')).to eq(true) }
172
246
  specify { expect(Chewy.client.indices.exists(index: 'dummies_2013')).to eq(true) }
173
247
  specify { expect(Chewy.client.indices.exists(index: 'dummies_2014')).to eq(false) }
248
+ specify { expect(Chewy.client.indices.exists(index: 'dummies_suffixed')).to eq(true) }
174
249
  end
175
250
  end
176
251
  end
@@ -184,19 +259,19 @@ describe Chewy::Index::Actions do
184
259
  before { DummiesIndex.purge }
185
260
  specify { expect(DummiesIndex).to be_exists }
186
261
  specify { expect(DummiesIndex.aliases).to eq([]) }
187
- specify { expect(DummiesIndex.indexes).to eq([]) }
262
+ specify { expect(DummiesIndex.indexes).to eq(['dummies']) }
188
263
 
189
264
  context do
190
265
  before { DummiesIndex.purge }
191
266
  specify { expect(DummiesIndex).to be_exists }
192
267
  specify { expect(DummiesIndex.aliases).to eq([]) }
193
- specify { expect(DummiesIndex.indexes).to eq([]) }
268
+ specify { expect(DummiesIndex.indexes).to eq(['dummies']) }
194
269
  end
195
270
 
196
271
  context do
197
272
  before { DummiesIndex.purge('2013') }
198
273
  specify { expect(DummiesIndex).to be_exists }
199
- specify { expect(DummiesIndex.aliases).to eq([]) }
274
+ specify { expect(DummiesIndex.aliases).to eq(['dummies']) }
200
275
  specify { expect(DummiesIndex.indexes).to eq(['dummies_2013']) }
201
276
  end
202
277
  end
@@ -204,20 +279,20 @@ describe Chewy::Index::Actions do
204
279
  context do
205
280
  before { DummiesIndex.purge('2013') }
206
281
  specify { expect(DummiesIndex).to be_exists }
207
- specify { expect(DummiesIndex.aliases).to eq([]) }
282
+ specify { expect(DummiesIndex.aliases).to eq(['dummies']) }
208
283
  specify { expect(DummiesIndex.indexes).to eq(['dummies_2013']) }
209
284
 
210
285
  context do
211
286
  before { DummiesIndex.purge }
212
287
  specify { expect(DummiesIndex).to be_exists }
213
288
  specify { expect(DummiesIndex.aliases).to eq([]) }
214
- specify { expect(DummiesIndex.indexes).to eq([]) }
289
+ specify { expect(DummiesIndex.indexes).to eq(['dummies']) }
215
290
  end
216
291
 
217
292
  context do
218
293
  before { DummiesIndex.purge('2014') }
219
294
  specify { expect(DummiesIndex).to be_exists }
220
- specify { expect(DummiesIndex.aliases).to eq([]) }
295
+ specify { expect(DummiesIndex.aliases).to eq(['dummies']) }
221
296
  specify { expect(DummiesIndex.indexes).to eq(['dummies_2014']) }
222
297
  end
223
298
  end
@@ -231,19 +306,19 @@ describe Chewy::Index::Actions do
231
306
  before { DummiesIndex.purge! }
232
307
  specify { expect(DummiesIndex).to be_exists }
233
308
  specify { expect(DummiesIndex.aliases).to eq([]) }
234
- specify { expect(DummiesIndex.indexes).to eq([]) }
309
+ specify { expect(DummiesIndex.indexes).to eq(['dummies']) }
235
310
 
236
311
  context do
237
312
  before { DummiesIndex.purge! }
238
313
  specify { expect(DummiesIndex).to be_exists }
239
314
  specify { expect(DummiesIndex.aliases).to eq([]) }
240
- specify { expect(DummiesIndex.indexes).to eq([]) }
315
+ specify { expect(DummiesIndex.indexes).to eq(['dummies']) }
241
316
  end
242
317
 
243
318
  context do
244
319
  before { DummiesIndex.purge!('2013') }
245
320
  specify { expect(DummiesIndex).to be_exists }
246
- specify { expect(DummiesIndex.aliases).to eq([]) }
321
+ specify { expect(DummiesIndex.aliases).to eq(['dummies']) }
247
322
  specify { expect(DummiesIndex.indexes).to eq(['dummies_2013']) }
248
323
  end
249
324
  end
@@ -251,20 +326,20 @@ describe Chewy::Index::Actions do
251
326
  context do
252
327
  before { DummiesIndex.purge!('2013') }
253
328
  specify { expect(DummiesIndex).to be_exists }
254
- specify { expect(DummiesIndex.aliases).to eq([]) }
329
+ specify { expect(DummiesIndex.aliases).to eq(['dummies']) }
255
330
  specify { expect(DummiesIndex.indexes).to eq(['dummies_2013']) }
256
331
 
257
332
  context do
258
333
  before { DummiesIndex.purge! }
259
334
  specify { expect(DummiesIndex).to be_exists }
260
335
  specify { expect(DummiesIndex.aliases).to eq([]) }
261
- specify { expect(DummiesIndex.indexes).to eq([]) }
336
+ specify { expect(DummiesIndex.indexes).to eq(['dummies']) }
262
337
  end
263
338
 
264
339
  context do
265
340
  before { DummiesIndex.purge!('2014') }
266
341
  specify { expect(DummiesIndex).to be_exists }
267
- specify { expect(DummiesIndex.aliases).to eq([]) }
342
+ specify { expect(DummiesIndex.aliases).to eq(['dummies']) }
268
343
  specify { expect(DummiesIndex.indexes).to eq(['dummies_2014']) }
269
344
  end
270
345
  end
@@ -274,7 +349,7 @@ describe Chewy::Index::Actions do
274
349
  before do
275
350
  stub_model(:city)
276
351
  stub_index(:cities) do
277
- define_type City
352
+ index_scope City
278
353
  end
279
354
  end
280
355
  let!(:dummy_cities) { Array.new(3) { |i| City.create(id: i + 1, name: "name#{i}") } }
@@ -296,9 +371,8 @@ describe Chewy::Index::Actions do
296
371
  context do
297
372
  before do
298
373
  stub_index(:cities) do
299
- define_type City do
300
- field :name, type: 'object'
301
- end
374
+ index_scope City
375
+ field :name, type: 'object'
302
376
  end
303
377
  end
304
378
 
@@ -310,7 +384,7 @@ describe Chewy::Index::Actions do
310
384
  before do
311
385
  stub_model(:city)
312
386
  stub_index(:cities) do
313
- define_type City
387
+ index_scope City
314
388
  end
315
389
  end
316
390
  let!(:dummy_cities) { Array.new(3) { |i| City.create(id: i + 1, name: "name#{i}") } }
@@ -332,9 +406,8 @@ describe Chewy::Index::Actions do
332
406
  context do
333
407
  before do
334
408
  stub_index(:cities) do
335
- define_type City do
336
- field :name, type: 'object'
337
- end
409
+ index_scope City
410
+ field :name, type: 'object'
338
411
  end
339
412
  end
340
413
 
@@ -346,7 +419,7 @@ describe Chewy::Index::Actions do
346
419
  before do
347
420
  stub_model(:city)
348
421
  stub_index(:cities) do
349
- define_type City
422
+ index_scope City
350
423
  end
351
424
  end
352
425
 
@@ -361,13 +434,13 @@ describe Chewy::Index::Actions do
361
434
 
362
435
  specify { expect(CitiesIndex.all).to have(1).item }
363
436
  specify { expect(CitiesIndex.aliases).to eq([]) }
364
- specify { expect(CitiesIndex.indexes).to eq([]) }
437
+ specify { expect(CitiesIndex.indexes).to eq(['cities']) }
365
438
 
366
439
  context do
367
440
  before { CitiesIndex.reset!('2013') }
368
441
 
369
442
  specify { expect(CitiesIndex.all).to have(1).item }
370
- specify { expect(CitiesIndex.aliases).to eq([]) }
443
+ specify { expect(CitiesIndex.aliases).to eq(['cities']) }
371
444
  specify { expect(CitiesIndex.indexes).to eq(['cities_2013']) }
372
445
  end
373
446
 
@@ -376,7 +449,7 @@ describe Chewy::Index::Actions do
376
449
 
377
450
  specify { expect(CitiesIndex.all).to have(1).item }
378
451
  specify { expect(CitiesIndex.aliases).to eq([]) }
379
- specify { expect(CitiesIndex.indexes).to eq([]) }
452
+ specify { expect(CitiesIndex.indexes).to eq(['cities']) }
380
453
  end
381
454
  end
382
455
 
@@ -384,14 +457,14 @@ describe Chewy::Index::Actions do
384
457
  before { CitiesIndex.reset!('2013') }
385
458
 
386
459
  specify { expect(CitiesIndex.all).to have(1).item }
387
- specify { expect(CitiesIndex.aliases).to eq([]) }
460
+ specify { expect(CitiesIndex.aliases).to eq(['cities']) }
388
461
  specify { expect(CitiesIndex.indexes).to eq(['cities_2013']) }
389
462
 
390
463
  context do
391
464
  before { CitiesIndex.reset!('2014') }
392
465
 
393
466
  specify { expect(CitiesIndex.all).to have(1).item }
394
- specify { expect(CitiesIndex.aliases).to eq([]) }
467
+ specify { expect(CitiesIndex.aliases).to eq(['cities']) }
395
468
  specify { expect(CitiesIndex.indexes).to eq(['cities_2014']) }
396
469
  specify { expect(Chewy.client.indices.exists(index: 'cities_2013')).to eq(false) }
397
470
  end
@@ -401,7 +474,7 @@ describe Chewy::Index::Actions do
401
474
 
402
475
  specify { expect(CitiesIndex.all).to have(1).item }
403
476
  specify { expect(CitiesIndex.aliases).to eq([]) }
404
- specify { expect(CitiesIndex.indexes).to eq([]) }
477
+ specify { expect(CitiesIndex.indexes).to eq(['cities']) }
405
478
  specify { expect(Chewy.client.indices.exists(index: 'cities_2013')).to eq(false) }
406
479
  end
407
480
  end
@@ -437,7 +510,7 @@ describe Chewy::Index::Actions do
437
510
  before do
438
511
  stub_index(:cities) do
439
512
  settings index: {refresh_interval: '2s'}
440
- define_type City
513
+ index_scope City
441
514
  end
442
515
  end
443
516
 
@@ -448,9 +521,11 @@ describe Chewy::Index::Actions do
448
521
  end
449
522
 
450
523
  specify do
451
- expect(CitiesIndex.client.indices).to receive(:put_settings).with(index: name, body: before_import_body).once
524
+ expect(CitiesIndex.client.indices)
525
+ .to receive(:put_settings).with(index: name, body: before_import_body).once
452
526
  expect(CitiesIndex.client.indices).to receive(:put_settings).with(index: name, body: after_import_body).once
453
- expect(CitiesIndex).to receive(:import).with(suffix: suffix, journal: false, refresh: false).and_call_original
527
+ expect(CitiesIndex)
528
+ .to receive(:import).with(suffix: suffix, journal: false, refresh: false).and_call_original
454
529
  expect(CitiesIndex.reset!(suffix)).to eq(true)
455
530
  end
456
531
 
@@ -511,12 +586,11 @@ describe Chewy::Index::Actions do
511
586
  xcontext 'applying journal' do
512
587
  before do
513
588
  stub_index(:cities) do
514
- define_type City do
515
- field :name, value: (lambda do
516
- sleep(rating)
517
- name
518
- end)
519
- end
589
+ index_scope City
590
+ field :name, value: (lambda do
591
+ sleep(rating)
592
+ name
593
+ end)
520
594
  end
521
595
  end
522
596
 
@@ -536,7 +610,7 @@ describe Chewy::Index::Actions do
536
610
  specify 'with journal application' do
537
611
  cities
538
612
  p 'cities created1'
539
- ::ActiveRecord::Base.connection.close if defined?(::ActiveRecord::Base)
613
+ ActiveRecord::Base.connection.close if defined?(ActiveRecord::Base)
540
614
  [
541
615
  parallel_update,
542
616
  Thread.new do
@@ -545,7 +619,7 @@ describe Chewy::Index::Actions do
545
619
  p 'end reset1'
546
620
  end
547
621
  ].map(&:join)
548
- ::ActiveRecord::Base.connection.reconnect! if defined?(::ActiveRecord::Base)
622
+ ActiveRecord::Base.connection.reconnect! if defined?(ActiveRecord::Base)
549
623
  p 'expect1'
550
624
  expect(CitiesIndex::City.pluck(:_id, :name)).to contain_exactly(%w[1 NewName1], %w[2 Name2], %w[3 NewName3])
551
625
  p 'end expect1'
@@ -554,7 +628,7 @@ describe Chewy::Index::Actions do
554
628
  specify 'without journal application' do
555
629
  cities
556
630
  p 'cities created2'
557
- ::ActiveRecord::Base.connection.close if defined?(::ActiveRecord::Base)
631
+ ActiveRecord::Base.connection.close if defined?(ActiveRecord::Base)
558
632
  [
559
633
  parallel_update,
560
634
  Thread.new do
@@ -563,7 +637,7 @@ describe Chewy::Index::Actions do
563
637
  p 'end reset2'
564
638
  end
565
639
  ].map(&:join)
566
- ::ActiveRecord::Base.connection.reconnect! if defined?(::ActiveRecord::Base)
640
+ ActiveRecord::Base.connection.reconnect! if defined?(ActiveRecord::Base)
567
641
  p 'expect2'
568
642
  expect(CitiesIndex::City.pluck(:_id, :name)).to contain_exactly(%w[1 Name1], %w[2 Name2], %w[3 Name3])
569
643
  p 'end expect2'
@@ -586,18 +660,253 @@ describe Chewy::Index::Actions do
586
660
 
587
661
  context 'other options' do
588
662
  specify do
589
- expect(CitiesIndex::City).to receive(:import).with(parallel: true, journal: false).once.and_return(true)
663
+ expect(CitiesIndex).to receive(:import).with(parallel: true, journal: false).once.and_return(true)
590
664
  expect(CitiesIndex.reset!(parallel: true)).to eq(true)
591
665
  end
592
666
 
593
667
  specify do
594
- expect(CitiesIndex::City).to receive(:import).with(suffix: 'suffix', parallel: true, journal: false, refresh: true).once.and_return(true)
668
+ expect(CitiesIndex)
669
+ .to receive(:import)
670
+ .with(suffix: 'suffix', parallel: true, journal: false, refresh: true)
671
+ .once.and_return(true)
595
672
  expect(CitiesIndex.reset!('suffix', parallel: true)).to eq(true)
596
673
  end
597
674
  end
598
675
  end
599
676
 
677
+ describe '.reset' do
678
+ before do
679
+ stub_model(:city)
680
+ stub_index(:cities) do
681
+ index_scope City
682
+ end
683
+ end
684
+
685
+ context do
686
+ before { City.create!(id: 1, name: 'Moscow') }
687
+
688
+ specify { expect(CitiesIndex.reset).to eq(true) }
689
+ specify { expect(CitiesIndex.reset('2013')).to eq(true) }
690
+
691
+ context do
692
+ before { CitiesIndex.reset }
693
+
694
+ specify { expect(CitiesIndex.all).to have(1).item }
695
+ specify { expect(CitiesIndex.aliases).to eq([]) }
696
+ specify { expect(CitiesIndex.indexes).to eq(['cities']) }
697
+ end
698
+ end
699
+ end
700
+
701
+ describe '.sync' do
702
+ before do
703
+ stub_model(:city)
704
+ stub_index(:cities) do
705
+ index_scope City
706
+ field :name
707
+ field :updated_at, type: 'date'
708
+ end
709
+ end
710
+
711
+ let!(:cities) { Array.new(3) { |i| City.create!(name: "Name#{i + 1}") } }
712
+
713
+ before do
714
+ CitiesIndex.import
715
+ cities.first.destroy
716
+ cities.last.update(name: 'Name5')
717
+ end
718
+
719
+ let!(:additional_city) { City.create!(name: 'Name4') }
720
+
721
+ specify do
722
+ expect(CitiesIndex.sync).to match(
723
+ count: 3,
724
+ missing: contain_exactly(cities.first.id.to_s, additional_city.id.to_s),
725
+ outdated: [cities.last.id.to_s]
726
+ )
727
+ end
728
+ specify do
729
+ expect { CitiesIndex.sync }.to update_index(CitiesIndex)
730
+ .and_reindex(additional_city, cities.last)
731
+ .and_delete(cities.first).only
732
+ end
733
+ end
734
+
600
735
  describe '.journal' do
601
736
  specify { expect(DummiesIndex.journal).to be_a(Chewy::Journal) }
602
737
  end
738
+
739
+ describe '.clear_cache' do
740
+ before do
741
+ stub_model(:city)
742
+ stub_index(:cities) do
743
+ index_scope City
744
+ end
745
+ end
746
+
747
+ let(:index_name) { 'test_index' }
748
+ let(:index_name_with_prefix) { 'cities_test_index' }
749
+ let(:unexisted_index_name) { 'wrong_index' }
750
+
751
+ context 'with existing index' do
752
+ before do
753
+ CitiesIndex.create(index_name)
754
+ end
755
+
756
+ specify do
757
+ expect(CitiesIndex)
758
+ .to receive(:clear_cache)
759
+ .and_call_original
760
+ expect { CitiesIndex.clear_cache({index: index_name_with_prefix}) }
761
+ .not_to raise_error
762
+ end
763
+ end
764
+
765
+ context 'with unexisting index' do
766
+ specify do
767
+ expect(CitiesIndex)
768
+ .to receive(:clear_cache)
769
+ .and_call_original
770
+ expect { CitiesIndex.clear_cache({index: unexisted_index_name}) }
771
+ .to raise_error Elasticsearch::Transport::Transport::Errors::NotFound
772
+ end
773
+ end
774
+
775
+ context 'without arguments' do
776
+ before do
777
+ CitiesIndex.create
778
+ end
779
+
780
+ specify do
781
+ expect(CitiesIndex)
782
+ .to receive(:clear_cache)
783
+ .and_call_original
784
+ expect { CitiesIndex.clear_cache }
785
+ .not_to raise_error
786
+ end
787
+ end
788
+ end
789
+
790
+ describe '.reindex' do
791
+ before do
792
+ stub_model(:city)
793
+ stub_index(:cities) do
794
+ index_scope City
795
+ end
796
+ CitiesIndex.create(source_index)
797
+ DummiesIndex.create(dest_index)
798
+ end
799
+
800
+ let(:source_index) { 'source_index' }
801
+ let(:source_index_with_prefix) { 'cities_source_index' }
802
+ let(:dest_index) { 'dest_index' }
803
+ let(:dest_index_with_prefix) { 'dummies_dest_index' }
804
+ let(:unexisting_index) { 'wrong_index' }
805
+
806
+ context 'with existing indexes' do
807
+ specify do
808
+ expect(CitiesIndex)
809
+ .to receive(:reindex)
810
+ .and_call_original
811
+ expect { CitiesIndex.reindex(source: source_index_with_prefix, dest: dest_index_with_prefix) }
812
+ .not_to raise_error
813
+ end
814
+ end
815
+
816
+ context 'with unexisting indexes' do
817
+ context 'source index' do
818
+ specify do
819
+ expect(CitiesIndex)
820
+ .to receive(:reindex)
821
+ .and_call_original
822
+ expect { CitiesIndex.reindex(source: unexisting_index, dest: dest_index_with_prefix) }
823
+ .to raise_error Elasticsearch::Transport::Transport::Errors::NotFound
824
+ end
825
+ end
826
+
827
+ context 'dest index' do
828
+ specify do
829
+ expect(CitiesIndex)
830
+ .to receive(:reindex)
831
+ .and_call_original
832
+ expect { CitiesIndex.reindex(source: source_index_with_prefix, dest: unexisting_index) }
833
+ .not_to raise_error
834
+ end
835
+ end
836
+ end
837
+
838
+ context 'with missing indexes' do
839
+ context 'without dest index' do
840
+ specify do
841
+ expect(DummiesIndex)
842
+ .to receive(:reindex)
843
+ .and_call_original
844
+ expect { DummiesIndex.reindex(source: source_index_with_prefix) }
845
+ .not_to raise_error
846
+ end
847
+ end
848
+
849
+ context 'without source index' do
850
+ specify do
851
+ expect(CitiesIndex)
852
+ .to receive(:reindex)
853
+ .and_call_original
854
+ expect { CitiesIndex.reindex(dest: dest_index_with_prefix) }
855
+ .not_to raise_error
856
+ end
857
+ end
858
+ end
859
+ end
860
+
861
+ describe 'update_mapping' do
862
+ before do
863
+ stub_model(:city)
864
+ stub_index(:cities) do
865
+ index_scope City
866
+ end
867
+ CitiesIndex.create
868
+ end
869
+
870
+ let(:index_name) { CitiesIndex.index_name }
871
+ let(:body_hash) { {properties: {new_field: {type: :text}}} }
872
+ let(:unexisting_index) { 'wrong_index' }
873
+ let(:empty_body_hash) { {} }
874
+
875
+ context 'with existing index' do
876
+ specify do
877
+ expect { CitiesIndex.update_mapping(index_name, body_hash) }
878
+ .not_to raise_error
879
+ end
880
+ end
881
+
882
+ context 'with unexisting arguments' do
883
+ context 'index name' do
884
+ specify do
885
+ expect { CitiesIndex.update_mapping(unexisting_index, body_hash) }
886
+ .to raise_error Elasticsearch::Transport::Transport::Errors::NotFound
887
+ end
888
+ end
889
+
890
+ context 'body hash' do
891
+ specify do
892
+ expect { CitiesIndex.update_mapping(index_name, empty_body_hash) }
893
+ .not_to raise_error
894
+ end
895
+ end
896
+ end
897
+
898
+ context 'with only argument' do
899
+ specify do
900
+ expect { CitiesIndex.update_mapping(index_name) }
901
+ .not_to raise_error
902
+ end
903
+ end
904
+
905
+ context 'without arguments' do
906
+ specify do
907
+ expect { CitiesIndex.update_mapping }
908
+ .not_to raise_error
909
+ end
910
+ end
911
+ end
603
912
  end