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
@@ -1,36 +1,34 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Chewy::Type::Syncer, :orm do
3
+ describe Chewy::Index::Syncer, :orm do
4
4
  before { Chewy.massacre }
5
5
  before do
6
6
  stub_model(:city)
7
7
  stub_index(:cities) do
8
- define_type City do
9
- field :name
10
- field :updated_at, type: 'date'
11
- end
8
+ index_scope City
9
+ field :name
10
+ field :updated_at, type: 'date'
12
11
  end
13
12
  end
14
13
 
15
14
  shared_examples 'sync' do |options = {}|
16
15
  let!(:cities) { Array.new(3) { |i| City.create!(name: "Name#{i + 1}") } }
17
- subject { described_class.new(CitiesIndex::City, **options) }
16
+ subject { described_class.new(CitiesIndex, **options) }
18
17
 
19
18
  describe '#perform' do
20
- before { CitiesIndex::City.import!(cities) }
19
+ before { CitiesIndex.import!(cities) }
21
20
  specify { expect(subject.perform).to eq(0) }
22
21
 
23
22
  context do
24
23
  before do
25
24
  cities.first.destroy
26
- sleep(1) if ActiveSupport::VERSION::STRING < '4.1.0'
27
25
  cities.last.update(name: 'Name5')
28
26
  end
29
27
  let!(:additional_city) { City.create!(name: 'Name4') }
30
28
 
31
29
  specify { expect(subject.perform).to eq(3) }
32
30
  specify do
33
- expect { subject.perform }.to update_index(CitiesIndex::City)
31
+ expect { subject.perform }.to update_index(CitiesIndex)
34
32
  .and_reindex(additional_city, cities.last)
35
33
  .and_delete(cities.first).only
36
34
  end
@@ -39,9 +37,8 @@ describe Chewy::Type::Syncer, :orm do
39
37
  context 'does not support outdated sync' do
40
38
  before do
41
39
  stub_index(:cities) do
42
- define_type City do
43
- field :name
44
- end
40
+ index_scope City
41
+ field :name
45
42
  end
46
43
  end
47
44
 
@@ -56,7 +53,7 @@ describe Chewy::Type::Syncer, :orm do
56
53
 
57
54
  specify { expect(subject.perform).to eq(2) }
58
55
  specify do
59
- expect { subject.perform }.to update_index(CitiesIndex::City)
56
+ expect { subject.perform }.to update_index(CitiesIndex)
60
57
  .and_reindex(additional_city)
61
58
  .and_delete(cities.first).only
62
59
  end
@@ -68,7 +65,7 @@ describe Chewy::Type::Syncer, :orm do
68
65
  specify { expect(subject.missing_ids).to match_array(cities.map(&:id).map(&:to_s)) }
69
66
 
70
67
  context do
71
- before { CitiesIndex::City.import!(cities) }
68
+ before { CitiesIndex.import!(cities) }
72
69
  specify { expect(subject.missing_ids).to eq([]) }
73
70
 
74
71
  context do
@@ -83,12 +80,11 @@ describe Chewy::Type::Syncer, :orm do
83
80
  specify { expect(subject.outdated_ids).to eq([]) }
84
81
 
85
82
  context do
86
- before { CitiesIndex::City.import!(cities) }
83
+ before { CitiesIndex.import!(cities) }
87
84
  specify { expect(subject.outdated_ids).to eq([]) }
88
85
 
89
86
  context do
90
87
  before do
91
- sleep(1) if ActiveSupport::VERSION::STRING < '4.1.0'
92
88
  cities.first.update(name: 'Name4')
93
89
  cities.last.update(name: 'Name5')
94
90
  end
@@ -99,9 +95,8 @@ describe Chewy::Type::Syncer, :orm do
99
95
  context 'does not support outdated sync' do
100
96
  before do
101
97
  stub_index(:cities) do
102
- define_type City do
103
- field :name
104
- end
98
+ index_scope City
99
+ field :name
105
100
  end
106
101
  end
107
102
 
@@ -1,25 +1,23 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Chewy::Type::Witchcraft do
3
+ describe Chewy::Index::Witchcraft do
4
4
  def self.mapping(&block)
5
5
  before do
6
6
  stub_index(:products) do
7
- define_type :product do
8
- witchcraft!
7
+ witchcraft!
9
8
 
10
- instance_exec(&block)
11
- end
9
+ instance_exec(&block)
12
10
  end
13
11
  end
14
12
  end
15
13
 
16
14
  describe '#cauldron' do
17
- let(:type) { ProductsIndex::Product }
15
+ let(:index) { ProductsIndex }
18
16
  let(:object) {}
19
17
 
20
18
  context 'empty mapping' do
21
19
  mapping {}
22
- specify { expect(type.cauldron.brew(object)).to eq({}) }
20
+ specify { expect(index.cauldron.brew(object)).to eq({}) }
23
21
  end
24
22
 
25
23
  context do
@@ -32,18 +30,18 @@ describe Chewy::Type::Witchcraft do
32
30
 
33
31
  context do
34
32
  let(:object) { double(attributes) }
35
- specify { expect(type.cauldron.brew(object)).to eq(attributes.as_json) }
33
+ specify { expect(index.cauldron.brew(object)).to eq(attributes.as_json) }
36
34
  end
37
35
 
38
36
  context do
39
37
  let(:object) { attributes }
40
- specify { expect(type.cauldron.brew(object)).to eq(attributes.as_json) }
38
+ specify { expect(index.cauldron.brew(object)).to eq(attributes.as_json) }
41
39
  end
42
40
 
43
41
  context do
44
42
  let(:object) { double(attributes) }
45
43
  specify do
46
- expect(type.cauldron(fields: %i[name tags]).brew(object))
44
+ expect(index.cauldron(fields: %i[name tags]).brew(object))
47
45
  .to eq('name' => 'Name', 'tags' => %w[Ruby RoR])
48
46
  end
49
47
  end
@@ -51,7 +49,7 @@ describe Chewy::Type::Witchcraft do
51
49
  context do
52
50
  let(:object) { attributes }
53
51
  specify do
54
- expect(type.cauldron(fields: %i[name tags]).brew(object))
52
+ expect(index.cauldron(fields: %i[name tags]).brew(object))
55
53
  .to eq('name' => 'Name', 'tags' => %w[Ruby RoR])
56
54
  end
57
55
  end
@@ -69,7 +67,7 @@ describe Chewy::Type::Witchcraft do
69
67
 
70
68
  context do
71
69
  let(:object) { double(attributes) }
72
- specify { expect(type.cauldron.brew(object)).to eq(attributes.merge(tags: %i[Ruby RoR]).as_json) }
70
+ specify { expect(index.cauldron.brew(object)).to eq(attributes.merge(tags: %i[Ruby RoR]).as_json) }
73
71
  end
74
72
  end
75
73
 
@@ -82,7 +80,7 @@ describe Chewy::Type::Witchcraft do
82
80
  context do
83
81
  let(:object) { double(attributes) }
84
82
  let(:crutches) { double(names: ['Other']) }
85
- specify { expect(type.cauldron.brew(object, crutches)).to eq({name: 'Other'}.as_json) }
83
+ specify { expect(index.cauldron.brew(object, crutches)).to eq({name: 'Other'}.as_json) }
86
84
  end
87
85
  end
88
86
 
@@ -102,7 +100,7 @@ describe Chewy::Type::Witchcraft do
102
100
  ])
103
101
  end
104
102
  specify do
105
- expect(type.cauldron.brew(object)).to eq({queries: [
103
+ expect(index.cauldron.brew(object)).to eq({queries: [
106
104
  {title: 'Title1', body: 'This Body1'},
107
105
  {title: 'Title2', body: 'This Body2'}
108
106
  ]}.as_json)
@@ -124,7 +122,7 @@ describe Chewy::Type::Witchcraft do
124
122
  ])
125
123
  end
126
124
  specify do
127
- expect(type.cauldron.brew(object)).to eq({queries: [
125
+ expect(index.cauldron.brew(object)).to eq({queries: [
128
126
  {title: 'Title1', body: 'This Body1'},
129
127
  {title: 'Title2', body: 'This Body2'}
130
128
  ]}.as_json)
@@ -146,7 +144,7 @@ describe Chewy::Type::Witchcraft do
146
144
  ])
147
145
  end
148
146
  specify do
149
- expect(type.cauldron.brew(object)).to eq({queries: [
147
+ expect(index.cauldron.brew(object)).to eq({queries: [
150
148
  {title: 'Title1', body: 'This Body1'},
151
149
  {title: 'Title2', body: 'This Body2'}
152
150
  ]}.as_json)
@@ -172,7 +170,7 @@ describe Chewy::Type::Witchcraft do
172
170
  ])
173
171
  end
174
172
  specify do
175
- expect(type.cauldron.brew(object, double(second: 'Crutch'))).to eq({queries: [
173
+ expect(index.cauldron.brew(object, double(second: 'Crutch'))).to eq({queries: [
176
174
  {fields: [
177
175
  {first: 'First1', second: 'Value1Second1'},
178
176
  {first: 'First2', second: 'Value1Crutch'}
@@ -193,7 +191,7 @@ describe Chewy::Type::Witchcraft do
193
191
  double(not_present: nil)
194
192
  end
195
193
  specify do
196
- expect(type.cauldron.brew(object)).to eq({not_present: nil}.as_json)
194
+ expect(index.cauldron.brew(object)).to eq({not_present: nil}.as_json)
197
195
  end
198
196
  end
199
197
  end
@@ -208,7 +206,7 @@ describe Chewy::Type::Witchcraft do
208
206
 
209
207
  context do
210
208
  let(:object) { double(attributes) }
211
- specify { expect(type.cauldron.brew(object)).to eq(attributes.as_json) }
209
+ specify { expect(index.cauldron.brew(object)).to eq(attributes.as_json) }
212
210
  end
213
211
  end
214
212
 
@@ -224,7 +222,7 @@ describe Chewy::Type::Witchcraft do
224
222
 
225
223
  context do
226
224
  let(:object) { double(attributes) }
227
- specify { expect(type.cauldron.brew(object)).to eq(attributes.as_json) }
225
+ specify { expect(index.cauldron.brew(object)).to eq(attributes.as_json) }
228
226
  end
229
227
  end
230
228
 
@@ -235,12 +233,12 @@ describe Chewy::Type::Witchcraft do
235
233
 
236
234
  context do
237
235
  let(:object) { double(last_name: 'Name') }
238
- specify { expect(type.cauldron.brew(object)).to eq({name: 'Name'}.as_json) }
236
+ specify { expect(index.cauldron.brew(object)).to eq({name: 'Name'}.as_json) }
239
237
  end
240
238
 
241
239
  context do
242
240
  let(:object) { {'last_name' => 'Name'} }
243
- specify { expect(type.cauldron.brew(object)).to eq({name: 'Name'}.as_json) }
241
+ specify { expect(index.cauldron.brew(object)).to eq({name: 'Name'}.as_json) }
244
242
  end
245
243
  end
246
244
  end
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ describe Chewy::Index::Wrapper do
4
+ before do
5
+ stub_class(:city)
6
+ stub_index(:cities) do
7
+ index_scope City
8
+ end
9
+ end
10
+
11
+ let(:cities_index) { CitiesIndex }
12
+
13
+ describe '.build' do
14
+ specify do
15
+ expect(cities_index.build({}).attributes)
16
+ .to eq('id' => nil, '_score' => nil, '_explanation' => nil)
17
+ end
18
+ specify do
19
+ expect(cities_index.build('_source' => {name: 'Martin'}).attributes)
20
+ .to eq('id' => nil, '_score' => nil, '_explanation' => nil, 'name' => 'Martin')
21
+ end
22
+ specify do
23
+ expect(cities_index.build('_id' => 42).attributes)
24
+ .to eq('id' => 42, '_score' => nil, '_explanation' => nil)
25
+ end
26
+ specify do
27
+ expect(cities_index.build('_id' => 42, '_source' => {'id' => 43}).attributes)
28
+ .to eq('id' => 43, '_score' => nil, '_explanation' => nil)
29
+ end
30
+ specify do
31
+ expect(cities_index.build('_score' => 42, '_explanation' => {foo: 'bar'}).attributes)
32
+ .to eq('id' => nil, '_score' => 42, '_explanation' => {foo: 'bar'})
33
+ end
34
+ specify do
35
+ expect(cities_index.build('_score' => 42, 'borogoves' => {foo: 'bar'})._data)
36
+ .to eq('_score' => 42, 'borogoves' => {foo: 'bar'})
37
+ end
38
+ end
39
+
40
+ describe '#initialize' do
41
+ subject(:city) { cities_index.new(name: 'Martin', age: 42) }
42
+
43
+ it do
44
+ is_expected.to respond_to(:name)
45
+ .and respond_to(:age)
46
+ .and have_attributes(
47
+ name: 'Martin',
48
+ age: 42
49
+ )
50
+ end
51
+
52
+ it { expect { city.population }.to raise_error(NoMethodError) }
53
+
54
+ context 'highlight' do
55
+ subject(:city) do
56
+ cities_index.new(name: 'Martin', age: 42)
57
+ .tap do |city|
58
+ city._data = {
59
+ 'highlight' => {'name' => ['<b>Mar</b>tin']}
60
+ }
61
+ end
62
+ end
63
+
64
+ it do
65
+ is_expected.to respond_to(:name_highlight)
66
+ .and respond_to(:name_highlights)
67
+ .and have_attributes(
68
+ name: 'Martin',
69
+ name_highlight: '<b>Mar</b>tin',
70
+ name_highlights: ['<b>Mar</b>tin']
71
+ )
72
+ end
73
+ end
74
+ end
75
+
76
+ describe '#==' do
77
+ specify { expect(cities_index.new(id: 42)).to eq(cities_index.new(id: 42)) }
78
+ specify { expect(cities_index.new(id: 42, age: 55)).to eq(cities_index.new(id: 42, age: 54)) }
79
+ specify { expect(cities_index.new(id: 42)).not_to eq(cities_index.new(id: 43)) }
80
+ specify { expect(cities_index.new(id: 42, age: 55)).not_to eq(cities_index.new(id: 43, age: 55)) }
81
+ specify { expect(cities_index.new(age: 55)).to eq(cities_index.new(age: 55)) }
82
+ specify { expect(cities_index.new(age: 55)).not_to eq(cities_index.new(age: 54)) }
83
+
84
+ specify { expect(cities_index.new(id: '42')).to eq(City.new.tap { |m| allow(m).to receive_messages(id: 42) }) }
85
+ specify { expect(cities_index.new(id: 42)).not_to eq(City.new.tap { |m| allow(m).to receive_messages(id: 43) }) }
86
+ specify { expect(cities_index.new(id: 42)).not_to eq(Class.new) }
87
+
88
+ context 'models', :orm do
89
+ before do
90
+ stub_model(:city)
91
+ stub_index(:cities) do
92
+ index_scope City
93
+ end
94
+ end
95
+ specify { expect(cities_index.new(id: '42')).to eq(City.new.tap { |m| allow(m).to receive_messages(id: 42) }) }
96
+ specify { expect(cities_index.new(id: 42)).not_to eq(City.new.tap { |m| allow(m).to receive_messages(id: 43) }) }
97
+ specify { expect(cities_index.new(id: 42)).not_to eq(Class.new) }
98
+ end
99
+ end
100
+ end
@@ -2,9 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Chewy::Index do
4
4
  before do
5
- stub_index(:dummies) do
6
- define_type :dummy
7
- end
5
+ stub_index(:dummies)
8
6
  end
9
7
 
10
8
  describe '.import', :orm do
@@ -13,11 +11,11 @@ describe Chewy::Index do
13
11
  stub_model(:country)
14
12
 
15
13
  stub_index(:cities) do
16
- define_type City
14
+ index_scope City
17
15
  end
18
16
 
19
17
  stub_index(:countries) do
20
- define_type Country
18
+ index_scope Country
21
19
  end
22
20
  end
23
21
 
@@ -30,18 +28,13 @@ describe Chewy::Index do
30
28
  end
31
29
 
32
30
  specify do
33
- expect { CitiesIndex.import city: cities.first }.to update_index(CitiesIndex).and_reindex(cities.first).only
34
- expect { CountriesIndex.import city: cities.first }.to update_index(CountriesIndex).and_reindex(countries)
35
- end
36
-
37
- specify do
38
- expect { CitiesIndex.import city: cities.first, country: countries.last }.to update_index(CitiesIndex).and_reindex(cities.first).only
39
- expect { CountriesIndex.import city: cities.first, country: countries.last }.to update_index(CountriesIndex).and_reindex(countries.last).only
31
+ expect { CitiesIndex.import cities.first }.to update_index(CitiesIndex).and_reindex(cities.first).only
32
+ expect { CountriesIndex.import countries.last }.to update_index(CountriesIndex).and_reindex(countries.last).only
40
33
  end
41
34
 
42
35
  specify do
43
36
  expect(CitiesIndex.client).to receive(:bulk).with(hash_including(refresh: false)).once
44
- CitiesIndex.import city: cities.first, refresh: false
37
+ CitiesIndex.import cities.first, refresh: false
45
38
  end
46
39
  end
47
40
 
@@ -64,10 +57,18 @@ describe Chewy::Index do
64
57
  specify { expect(stub_const('DeveloperIndex', Class.new(Chewy::Index)).index_name).to eq('developer') }
65
58
  specify { expect(stub_const('DevelopersIndex', Class.new(Chewy::Index)).index_name).to eq('developers') }
66
59
 
67
- specify { expect(stub_const('DevelopersIndex', Class.new(Chewy::Index)).index_name(suffix: '')).to eq('developers') }
68
- specify { expect(stub_const('DevelopersIndex', Class.new(Chewy::Index)).index_name(suffix: '2013')).to eq('developers_2013') }
69
- specify { expect(stub_const('DevelopersIndex', Class.new(Chewy::Index)).index_name(prefix: '')).to eq('developers') }
70
- specify { expect(stub_const('DevelopersIndex', Class.new(Chewy::Index)).index_name(prefix: 'test')).to eq('test_developers') }
60
+ specify do
61
+ expect(stub_const('DevelopersIndex', Class.new(Chewy::Index)).index_name(suffix: '')).to eq('developers')
62
+ end
63
+ specify do
64
+ expect(stub_const('DevelopersIndex', Class.new(Chewy::Index)).index_name(suffix: '2013')).to eq('developers_2013')
65
+ end
66
+ specify do
67
+ expect(stub_const('DevelopersIndex', Class.new(Chewy::Index)).index_name(prefix: '')).to eq('developers')
68
+ end
69
+ specify do
70
+ expect(stub_const('DevelopersIndex', Class.new(Chewy::Index)).index_name(prefix: 'test')).to eq('test_developers')
71
+ end
71
72
 
72
73
  context do
73
74
  before { allow(Chewy).to receive_messages(configuration: {prefix: 'testing'}) }
@@ -88,18 +89,18 @@ describe Chewy::Index do
88
89
  specify { expect(Class.new(Chewy::Index).prefix).to eq('testing') }
89
90
  end
90
91
 
91
- describe '.define_type' do
92
- specify { expect(DummiesIndex.type_hash['dummy']).to eq(DummiesIndex::Dummy) }
92
+ describe '.index_scope' do
93
+ specify { expect(DummiesIndex.adapter.name).to eq('Default') }
93
94
 
94
95
  context do
95
- before { stub_index(:dummies) { define_type :dummy, name: :borogoves } }
96
- specify { expect(DummiesIndex.type_hash['borogoves']).to eq(DummiesIndex::Borogoves) }
96
+ before { stub_index(:dummies) { index_scope :dummy, name: :borogoves } }
97
+ specify { expect(DummiesIndex.adapter.name).to eq('Borogoves') }
97
98
  end
98
99
 
99
100
  context do
100
101
  before { stub_class(:city) }
101
- before { stub_index(:dummies) { define_type City, name: :country } }
102
- specify { expect(DummiesIndex.type_hash['country']).to eq(DummiesIndex::Country) }
102
+ before { stub_index(:dummies) { index_scope City, name: :country } }
103
+ specify { expect(DummiesIndex.adapter.name).to eq('Country') }
103
104
  end
104
105
 
105
106
  context do
@@ -110,16 +111,16 @@ describe Chewy::Index do
110
111
  expect do
111
112
  Kernel.eval <<-DUMMY_CITY_INDEX
112
113
  class DummyCityIndex2 < Chewy::Index
113
- define_type City
114
- define_type Country
114
+ index_scope City
115
+ index_scope Country
115
116
  end
116
117
  DUMMY_CITY_INDEX
117
- end.to raise_error(/Multiple types are deprecated/)
118
+ end.to raise_error(/Index scope is already defined/)
118
119
 
119
120
  expect do
120
121
  Kernel.eval <<-DUMMY_CITY_INDEX
121
122
  class DummyCityIndex2 < Chewy::Index
122
- define_type City::Nothing
123
+ index_scope City::Nothing
123
124
  end
124
125
  DUMMY_CITY_INDEX
125
126
  end.to raise_error(NameError)
@@ -127,26 +128,6 @@ describe Chewy::Index do
127
128
  end
128
129
  end
129
130
 
130
- describe '.type_hash' do
131
- specify { expect(DummiesIndex.type_hash['dummy']).to eq(DummiesIndex::Dummy) }
132
- specify { expect(DummiesIndex.type_hash).to have_key 'dummy' }
133
- specify { expect(DummiesIndex.type_hash['dummy']).to be < Chewy::Type }
134
- specify { expect(DummiesIndex.type_hash['dummy'].type_name).to eq('dummy') }
135
- end
136
-
137
- describe '.type' do
138
- specify { expect(DummiesIndex.type('dummy')).to eq(DummiesIndex::Dummy) }
139
- specify { expect { DummiesIndex.type('not-the-dummy') }.to raise_error(Chewy::UndefinedType) }
140
- end
141
-
142
- specify { expect(DummiesIndex.type_names).to eq(DummiesIndex.type_hash.keys) }
143
-
144
- describe '.types' do
145
- specify { expect(DummiesIndex.types).to eq(DummiesIndex.type_hash.values) }
146
- specify { expect(DummiesIndex.types(:dummy)).to be_a Chewy::Search::Request }
147
- specify { expect(DummiesIndex.types(:user)).to be_a Chewy::Search::Request }
148
- end
149
-
150
131
  describe '.settings' do
151
132
  before do
152
133
  allow(Chewy).to receive_messages(config: Chewy::Config.send(:new))
@@ -158,7 +139,11 @@ describe Chewy::Index do
158
139
  Chewy.filter :names_nysiis, type: 'phonetic', encoder: 'nysiis', replace: false
159
140
  end
160
141
 
161
- let(:documents) { stub_index(:documents) { settings analysis: {analyzer: [:name, :phone, {sorted: {option: :baz}}]} } }
142
+ let(:documents) do
143
+ stub_index(:documents) do
144
+ settings analysis: {analyzer: [:name, :phone, {sorted: {option: :baz}}]}
145
+ end
146
+ end
162
147
 
163
148
  specify { expect { documents.settings_hash }.to_not change(documents._settings, :inspect) }
164
149
  specify do
@@ -182,20 +167,18 @@ describe Chewy::Index do
182
167
  filter(terms: {colors: colors.flatten(1).map(&:to_s)})
183
168
  end
184
169
 
185
- define_type :city do
186
- def self.by_id; end
187
- field :colors
188
- end
170
+ def self.by_id; end
171
+ field :colors
189
172
  end
190
173
  end
191
174
 
192
175
  specify { expect(described_class.scopes).to eq([]) }
193
- specify { expect(PlacesIndex.scopes).to match_array(%i[by_rating colors]) }
176
+ specify { expect(PlacesIndex.scopes).to match_array(%i[by_rating colors by_id]) }
194
177
 
195
178
  context do
196
179
  before do
197
180
  Chewy.massacre
198
- PlacesIndex::City.import!(
181
+ PlacesIndex.import!(
199
182
  double(colors: ['red']),
200
183
  double(colors: %w[red green]),
201
184
  double(colors: %w[green yellow])
@@ -203,16 +186,12 @@ describe Chewy::Index do
203
186
  end
204
187
 
205
188
  specify do
206
- # This `blank?`` call is for the messed scopes bug reproduction. See #573
207
- PlacesIndex::City.blank?
208
189
  expect(PlacesIndex.colors(:green).map(&:colors))
209
190
  .to contain_exactly(%w[red green], %w[green yellow])
210
191
  end
211
192
 
212
193
  specify do
213
- # This `blank?` call is for the messed scopes bug reproduction. See #573
214
- PlacesIndex::City.blank?
215
- expect(PlacesIndex::City.colors(:green).map(&:colors))
194
+ expect(PlacesIndex.colors(:green).map(&:colors))
216
195
  .to contain_exactly(%w[red green], %w[green yellow])
217
196
  end
218
197
  end
@@ -222,18 +201,20 @@ describe Chewy::Index do
222
201
  before { allow(Chewy).to receive_messages(config: Chewy::Config.send(:new)) }
223
202
 
224
203
  specify { expect(stub_index(:documents).settings_hash).to eq({}) }
225
- specify { expect(stub_index(:documents) { settings number_of_shards: 1 }.settings_hash).to eq(settings: {number_of_shards: 1}) }
204
+ specify do
205
+ expect(stub_index(:documents) do
206
+ settings number_of_shards: 1
207
+ end.settings_hash).to eq(settings: {number_of_shards: 1})
208
+ end
226
209
  end
227
210
 
228
211
  describe '.mappings_hash' do
229
212
  specify { expect(stub_index(:documents).mappings_hash).to eq({}) }
230
- specify { expect(stub_index(:documents) { define_type :document }.mappings_hash).to eq({}) }
213
+ specify { expect(stub_index(:documents) { index_scope :document }.mappings_hash).to eq({}) }
231
214
  specify do
232
215
  expect(stub_index(:documents) do
233
- define_type :document do
234
- field :date, type: 'date'
235
- end
236
- end.mappings_hash).to eq(mappings: {document: {properties: {date: {type: 'date'}}}})
216
+ field :date, type: 'date'
217
+ end.mappings_hash).to eq(mappings: {properties: {date: {type: 'date'}}})
237
218
  end
238
219
  end
239
220
 
@@ -241,20 +222,20 @@ describe Chewy::Index do
241
222
  before { allow(Chewy).to receive_messages(config: Chewy::Config.send(:new)) }
242
223
 
243
224
  specify { expect(stub_index(:documents).specification_hash).to eq({}) }
244
- specify { expect(stub_index(:documents) { settings number_of_shards: 1 }.specification_hash.keys).to eq([:settings]) }
245
225
  specify do
246
226
  expect(stub_index(:documents) do
247
- define_type :document do
248
- field :name
249
- end
227
+ settings number_of_shards: 1
228
+ end.specification_hash.keys).to eq([:settings])
229
+ end
230
+ specify do
231
+ expect(stub_index(:documents) do
232
+ field :name
250
233
  end.specification_hash.keys).to eq([:mappings])
251
234
  end
252
235
  specify do
253
236
  expect(stub_index(:documents) do
254
237
  settings number_of_shards: 1
255
- define_type :document do
256
- field :name
257
- end
238
+ field :name
258
239
  end.specification_hash.keys).to match_array(%i[mappings settings])
259
240
  end
260
241
  end
@@ -265,50 +246,24 @@ describe Chewy::Index do
265
246
  specify { expect(subject.specification).to equal(subject.specification) }
266
247
  end
267
248
 
268
- describe '.default_prefix' do
269
- before { allow(Chewy).to receive_messages(configuration: {prefix: 'testing'}) }
270
-
271
- context do
272
- before { expect(ActiveSupport::Deprecation).to receive(:warn).once }
273
- specify { expect(DummiesIndex.default_prefix).to eq('testing') }
274
- end
275
-
276
- context do
277
- before do
278
- DummiesIndex.class_eval do
279
- def self.default_prefix
280
- 'borogoves'
281
- end
282
- end
283
- end
284
-
285
- before { expect(ActiveSupport::Deprecation).to receive(:warn).once }
286
- specify { expect(DummiesIndex.index_name).to eq('borogoves_dummies') }
287
- end
288
- end
289
-
290
249
  context 'index call inside index', :orm do
291
250
  before do
292
251
  stub_index(:cities) do
293
- define_type :city do
294
- field :country_name, value: (lambda do |city|
295
- CountriesIndex::Country.filter(term: {_id: city.country_id}).first.name
296
- end)
297
- end
252
+ field :country_name, value: (lambda do |city|
253
+ CountriesIndex.filter(term: {_id: city.country_id}).first.name
254
+ end)
298
255
  end
299
256
 
300
257
  stub_index(:countries) do
301
- define_type :country do
302
- field :name
303
- end
258
+ field :name
304
259
  end
305
260
 
306
- CountriesIndex::Country.import!(double(id: 1, name: 'Country'))
261
+ CountriesIndex.import!(double(id: 1, name: 'Country'))
307
262
  end
308
263
 
309
264
  specify do
310
- expect { CitiesIndex::City.import!(double(country_id: 1)) }
311
- .to update_index(CitiesIndex::City).and_reindex(country_name: 'Country')
265
+ expect { CitiesIndex.import!(double(country_id: 1)) }
266
+ .to update_index(CitiesIndex).and_reindex(country_name: 'Country')
312
267
  end
313
268
  end
314
269
  end