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
@@ -2,37 +2,33 @@ require 'spec_helper'
2
2
 
3
3
  describe Chewy::Search::Parameters::Indices do
4
4
  before do
5
- stub_index(:first) do
6
- define_type :one
7
- end
8
-
9
- stub_index(:second) do
10
- define_type :three
11
- end
5
+ stub_index(:first)
6
+ stub_index(:second)
7
+ stub_index(:third)
12
8
  end
13
9
 
14
- subject { described_class.new(indices: FirstIndex, types: SecondIndex::Three) }
10
+ subject { described_class.new(indices: [FirstIndex, SecondIndex]) }
15
11
 
16
12
  describe '#initialize' do
17
- specify { expect(described_class.new.value).to eq(indices: [], types: []) }
18
- specify { expect(described_class.new(nil).value).to eq(indices: [], types: []) }
19
- specify { expect(described_class.new(foo: :whatever).value).to eq(indices: [], types: []) }
20
- specify { expect(subject.value).to eq(indices: [FirstIndex], types: [SecondIndex::Three]) }
13
+ specify { expect(described_class.new.value).to eq(indices: []) }
14
+ specify { expect(described_class.new(nil).value).to eq(indices: []) }
15
+ specify { expect(described_class.new(foo: :whatever).value).to eq(indices: []) }
16
+ specify { expect(subject.value).to eq(indices: [FirstIndex, SecondIndex]) }
21
17
  end
22
18
 
23
19
  describe '#replace!' do
24
20
  specify do
25
21
  expect { subject.replace!(nil) }
26
22
  .to change { subject.value }
27
- .from(indices: [FirstIndex], types: [SecondIndex::Three])
28
- .to(indices: [], types: [])
23
+ .from(indices: [FirstIndex, SecondIndex])
24
+ .to(indices: [])
29
25
  end
30
26
 
31
27
  specify do
32
- expect { subject.replace!(indices: SecondIndex, types: FirstIndex::One) }
28
+ expect { subject.replace!(indices: SecondIndex) }
33
29
  .to change { subject.value }
34
- .from(indices: [FirstIndex], types: [SecondIndex::Three])
35
- .to(indices: [SecondIndex], types: [FirstIndex::One])
30
+ .from(indices: [FirstIndex, SecondIndex])
31
+ .to(indices: [SecondIndex])
36
32
  end
37
33
  end
38
34
 
@@ -43,10 +39,10 @@ describe Chewy::Search::Parameters::Indices do
43
39
  end
44
40
 
45
41
  specify do
46
- expect { subject.update!(indices: SecondIndex, types: [FirstIndex::One, SecondIndex::Three]) }
42
+ expect { subject.update!(indices: ThirdIndex) }
47
43
  .to change { subject.value }
48
- .from(indices: [FirstIndex], types: [SecondIndex::Three])
49
- .to(indices: [FirstIndex, SecondIndex], types: [SecondIndex::Three, FirstIndex::One])
44
+ .from(indices: [FirstIndex, SecondIndex])
45
+ .to(indices: [FirstIndex, SecondIndex, ThirdIndex])
50
46
  end
51
47
  end
52
48
 
@@ -57,10 +53,8 @@ describe Chewy::Search::Parameters::Indices do
57
53
  end
58
54
 
59
55
  specify do
60
- expect { subject.merge!(described_class.new(indices: SecondIndex, types: [FirstIndex::One, SecondIndex::Three])) }
61
- .to change { subject.value }
62
- .from(indices: [FirstIndex], types: [SecondIndex::Three])
63
- .to(indices: [FirstIndex, SecondIndex], types: [SecondIndex::Three, FirstIndex::One])
56
+ expect { subject.merge!(described_class.new(indices: SecondIndex)) }
57
+ .not_to change { subject.value }
64
58
  end
65
59
  end
66
60
 
@@ -69,7 +63,7 @@ describe Chewy::Search::Parameters::Indices do
69
63
  specify do
70
64
  expect(described_class.new(
71
65
  indices: FirstIndex
72
- ).render).to eq(index: %w[first], type: %w[one])
66
+ ).render).to eq(index: %w[first])
73
67
  end
74
68
  specify do
75
69
  expect(described_class.new(
@@ -78,113 +72,28 @@ describe Chewy::Search::Parameters::Indices do
78
72
  end
79
73
  specify do
80
74
  expect(described_class.new(
81
- types: FirstIndex::One
82
- ).render).to eq(index: %w[first], type: %w[one])
83
- end
84
- specify do
85
- expect(described_class.new(
86
- types: :whatever
87
- ).render).to eq({})
88
- end
89
- specify do
90
- expect(described_class.new(
91
- indices: FirstIndex, types: SecondIndex::Three
92
- ).render).to eq(index: %w[first second], type: %w[one three])
93
- end
94
- specify do
95
- expect(described_class.new(
96
- indices: FirstIndex, types: :one
97
- ).render).to eq(index: %w[first], type: %w[one])
98
- end
99
- specify do
100
- expect(described_class.new(
101
- indices: FirstIndex, types: :whatever
102
- ).render).to eq(index: %w[first], type: %w[one])
103
- end
104
- specify do
105
- expect(described_class.new(
106
- indices: FirstIndex, types: %i[one whatever]
107
- ).render).to eq(index: %w[first], type: %w[one])
108
- end
109
- specify do
110
- expect(described_class.new(
111
- indices: :whatever, types: SecondIndex::Three
112
- ).render).to eq(index: %w[second whatever], type: %w[three])
113
- end
114
- specify do
115
- expect(described_class.new(
116
- indices: :whatever, types: [SecondIndex::Three, :whatever]
117
- ).render).to eq(index: %w[second whatever], type: %w[three whatever])
118
- end
119
- specify do
120
- expect(described_class.new(
121
- indices: [FirstIndex, :whatever], types: FirstIndex::One
122
- ).render).to eq(index: %w[first whatever], type: %w[one])
123
- end
124
- specify do
125
- expect(described_class.new(
126
- indices: FirstIndex, types: [FirstIndex::One, :whatever]
127
- ).render).to eq(index: %w[first], type: %w[one])
128
- end
129
- specify do
130
- expect(described_class.new(
131
- indices: FirstIndex, types: [SecondIndex::Three, :whatever]
132
- ).render).to eq(index: %w[first second], type: %w[one three])
133
- end
134
- specify do
135
- expect(described_class.new(
136
- indices: [FirstIndex, :whatever], types: [FirstIndex::One, :whatever]
137
- ).render).to eq(index: %w[first whatever], type: %w[one whatever])
138
- end
139
- specify do
140
- expect(described_class.new(
141
- indices: [FirstIndex, :whatever], types: [SecondIndex::Three, FirstIndex::One]
142
- ).render).to eq(index: %w[first second whatever], type: %w[one three])
75
+ indices: [FirstIndex, :whatever]
76
+ ).render).to eq(index: %w[first whatever])
143
77
  end
144
78
  end
145
79
 
146
80
  describe '#==' do
147
81
  specify { expect(described_class.new).to eq(described_class.new) }
148
82
  specify do
149
- expect(described_class.new(indices: SecondIndex, types: [SecondIndex::Three, :whatever]))
150
- .to eq(described_class.new(indices: SecondIndex, types: :whatever))
151
- end
152
- specify do
153
- expect(described_class.new(indices: :first, types: %w[one]))
83
+ expect(described_class.new(indices: :first))
154
84
  .to eq(described_class.new(indices: FirstIndex))
155
85
  end
156
86
  specify do
157
- expect(described_class.new(indices: FirstIndex, types: SecondIndex::Three))
158
- .not_to eq(described_class.new(indices: FirstIndex))
87
+ expect(described_class.new(indices: FirstIndex))
88
+ .to eq(described_class.new(indices: FirstIndex))
159
89
  end
160
90
  end
161
91
 
162
92
  describe '#indices' do
163
93
  specify do
164
94
  expect(described_class.new(
165
- indices: [FirstIndex, :whatever],
166
- types: [SecondIndex::Three, :whatever]
167
- ).indices).to contain_exactly(FirstIndex, SecondIndex)
168
- end
169
- end
170
-
171
- describe '#types' do
172
- specify do
173
- expect(described_class.new(
174
- indices: [FirstIndex, :whatever],
175
- types: [SecondIndex::Three, :whatever]
176
- ).types).to contain_exactly(
177
- FirstIndex::One, SecondIndex::Three
178
- )
179
- end
180
-
181
- specify do
182
- expect(described_class.new(
183
- indices: [FirstIndex, :whatever],
184
- types: [FirstIndex::One, SecondIndex::Three, :whatever]
185
- ).types).to contain_exactly(
186
- FirstIndex::One, SecondIndex::Three
187
- )
95
+ indices: [FirstIndex, :whatever]
96
+ ).indices).to contain_exactly(FirstIndex)
188
97
  end
189
98
  end
190
99
  end
@@ -0,0 +1,5 @@
1
+ require 'chewy/search/parameters/hash_storage_examples'
2
+
3
+ describe Chewy::Search::Parameters::Knn do
4
+ it_behaves_like :hash_storage, :knn
5
+ end
@@ -4,26 +4,29 @@ describe Chewy::Search::Parameters::Order do
4
4
  subject { described_class.new(%i[foo bar]) }
5
5
 
6
6
  describe '#initialize' do
7
- specify { expect(described_class.new.value).to eq({}) }
8
- specify { expect(described_class.new(nil).value).to eq({}) }
9
- specify { expect(described_class.new('').value).to eq({}) }
10
- specify { expect(described_class.new(42).value).to eq('42' => nil) }
11
- specify { expect(described_class.new([42, 43]).value).to eq('42' => nil, '43' => nil) }
12
- specify { expect(described_class.new(a: 1).value).to eq('a' => 1) }
13
- specify { expect(described_class.new(['', 43, a: 1]).value).to eq('a' => 1, '43' => nil) }
7
+ specify { expect(described_class.new.value).to eq([]) }
8
+ specify { expect(described_class.new(nil).value).to eq([]) }
9
+ specify { expect(described_class.new('').value).to eq([]) }
10
+ specify { expect(described_class.new(42).value).to eq(['42']) }
11
+ specify { expect(described_class.new([42, 43]).value).to eq(%w[42 43]) }
12
+ specify { expect(described_class.new([42, 42]).value).to eq(%w[42 42]) }
13
+ specify { expect(described_class.new([42, [43, 44]]).value).to eq(%w[42 43 44]) }
14
+ specify { expect(described_class.new(a: 1).value).to eq([{'a' => 1}]) }
15
+ specify { expect(described_class.new(['a', {a: 1}, {a: 2}]).value).to eq(['a', {'a' => 1}, {'a' => 2}]) }
16
+ specify { expect(described_class.new(['', 43, {a: 1}]).value).to eq(['43', {'a' => 1}]) }
14
17
  end
15
18
 
16
19
  describe '#replace!' do
17
20
  specify do
18
21
  expect { subject.replace!(foo: {}) }
19
22
  .to change { subject.value }
20
- .from('foo' => nil, 'bar' => nil).to('foo' => {})
23
+ .from(%w[foo bar]).to([{'foo' => {}}])
21
24
  end
22
25
 
23
26
  specify do
24
27
  expect { subject.replace!(nil) }
25
28
  .to change { subject.value }
26
- .from('foo' => nil, 'bar' => nil).to({})
29
+ .from(%w[foo bar]).to([])
27
30
  end
28
31
  end
29
32
 
@@ -31,7 +34,7 @@ describe Chewy::Search::Parameters::Order do
31
34
  specify do
32
35
  expect { subject.update!(foo: {}) }
33
36
  .to change { subject.value }
34
- .from('foo' => nil, 'bar' => nil).to('foo' => {}, 'bar' => nil)
37
+ .from(%w[foo bar]).to(['foo', 'bar', {'foo' => {}}])
35
38
  end
36
39
 
37
40
  specify { expect { subject.update!(nil) }.not_to change { subject.value } }
@@ -41,7 +44,7 @@ describe Chewy::Search::Parameters::Order do
41
44
  specify do
42
45
  expect { subject.merge!(described_class.new(foo: {})) }
43
46
  .to change { subject.value }
44
- .from('foo' => nil, 'bar' => nil).to('foo' => {}, 'bar' => nil)
47
+ .from(%w[foo bar]).to(['foo', 'bar', {'foo' => {}}])
45
48
  end
46
49
 
47
50
  specify { expect { subject.merge!(described_class.new) }.not_to change { subject.value } }
@@ -51,6 +54,7 @@ describe Chewy::Search::Parameters::Order do
51
54
  specify { expect(described_class.new.render).to be_nil }
52
55
  specify { expect(described_class.new(:foo).render).to eq(sort: ['foo']) }
53
56
  specify { expect(described_class.new([:foo, {bar: 42}, :baz]).render).to eq(sort: ['foo', {'bar' => 42}, 'baz']) }
57
+ specify { expect(described_class.new([:foo, {bar: 42}, {bar: 43}, :baz]).render).to eq(sort: ['foo', {'bar' => 42}, {'bar' => 43}, 'baz']) }
54
58
  end
55
59
 
56
60
  describe '#==' do
@@ -59,7 +63,10 @@ describe Chewy::Search::Parameters::Order do
59
63
  specify { expect(described_class.new(:foo)).not_to eq(described_class.new(:bar)) }
60
64
  specify { expect(described_class.new(%i[foo bar])).to eq(described_class.new(%i[foo bar])) }
61
65
  specify { expect(described_class.new(%i[foo bar])).not_to eq(described_class.new(%i[bar foo])) }
66
+ specify { expect(described_class.new(%i[foo foo])).not_to eq(described_class.new(%i[foo])) }
62
67
  specify { expect(described_class.new(foo: {a: 42})).to eq(described_class.new(foo: {a: 42})) }
63
68
  specify { expect(described_class.new(foo: {a: 42})).not_to eq(described_class.new(foo: {b: 42})) }
69
+ specify { expect(described_class.new(['foo', {'foo' => 42}])).not_to eq(described_class.new([{'foo' => 42}, 'foo'])) }
70
+ specify { expect(described_class.new([{'foo' => 42}, {'foo' => 43}])).not_to eq(described_class.new([{'foo' => 43}, {'foo' => 42}])) }
64
71
  end
65
72
  end
@@ -4,19 +4,46 @@ shared_examples :query_storage do |param_name|
4
4
  subject { described_class.new(must: {foo: 'bar'}, should: {moo: 'baz'}) }
5
5
 
6
6
  describe '#initialize' do
7
- specify { expect(described_class.new.value.to_h).to eq(must: [], should: [], must_not: [], minimum_should_match: nil) }
8
- specify { expect(described_class.new(nil).value.to_h).to eq(must: [], should: [], must_not: [], minimum_should_match: nil) }
9
- specify { expect(described_class.new(foobar: {}).value.to_h).to eq(must: [{foobar: {}}], should: [], must_not: [], minimum_should_match: nil) }
10
- specify { expect(described_class.new(must: {}, should: {}, must_not: {}).value.to_h).to eq(must: [], should: [], must_not: [], minimum_should_match: nil) }
7
+ specify do
8
+ expect(described_class.new.value.to_h)
9
+ .to eq(must: [], should: [], must_not: [], minimum_should_match: nil)
10
+ end
11
+ specify do
12
+ expect(described_class.new(nil).value.to_h)
13
+ .to eq(must: [], should: [], must_not: [], minimum_should_match: nil)
14
+ end
15
+ specify do
16
+ expect(described_class.new(foobar: {}).value.to_h)
17
+ .to eq(must: [{foobar: {}}], should: [], must_not: [], minimum_should_match: nil)
18
+ end
19
+ specify do
20
+ expect(described_class.new(must: {}, should: {}, must_not: {}).value.to_h)
21
+ .to eq(must: [], should: [], must_not: [], minimum_should_match: nil)
22
+ end
11
23
  specify do
12
24
  expect(described_class.new(must: {foo: 'bar'}, should: {foo: 'bar'}, foobar: {}).value.to_h)
13
25
  .to eq(must: [{foo: 'bar'}], should: [{foo: 'bar'}], must_not: [], minimum_should_match: nil)
14
26
  end
15
- specify { expect(subject.value.to_h).to eq(must: [{foo: 'bar'}], should: [{moo: 'baz'}], must_not: [], minimum_should_match: nil) }
16
- specify { expect(described_class.new(proc { match foo: 'bar' }).value.to_h).to eq(must: [match: {foo: 'bar'}], should: [], must_not: [], minimum_should_match: nil) }
17
- specify { expect(described_class.new(must: proc { match foo: 'bar' }).value.to_h).to eq(must: [match: {foo: 'bar'}], should: [], must_not: [], minimum_should_match: nil) }
18
- specify { expect(described_class.new(minimum_should_match: 3).value.to_h).to eq(must: [], should: [], must_not: [], minimum_should_match: 3) }
19
- specify { expect(described_class.new(must: {foo: 'bar'}, minimum_should_match: 3).value.to_h).to eq(must: [{foo: 'bar'}], should: [], must_not: [], minimum_should_match: 3) }
27
+ specify do
28
+ expect(subject.value.to_h)
29
+ .to eq(must: [{foo: 'bar'}], should: [{moo: 'baz'}], must_not: [], minimum_should_match: nil)
30
+ end
31
+ specify do
32
+ expect(described_class.new(proc { match foo: 'bar' }).value.to_h)
33
+ .to eq(must: [match: {foo: 'bar'}], should: [], must_not: [], minimum_should_match: nil)
34
+ end
35
+ specify do
36
+ expect(described_class.new(must: proc { match foo: 'bar' }).value.to_h)
37
+ .to eq(must: [match: {foo: 'bar'}], should: [], must_not: [], minimum_should_match: nil)
38
+ end
39
+ specify do
40
+ expect(described_class.new(minimum_should_match: 3).value.to_h)
41
+ .to eq(must: [], should: [], must_not: [], minimum_should_match: 3)
42
+ end
43
+ specify do
44
+ expect(described_class.new(must: {foo: 'bar'}, minimum_should_match: 3).value.to_h)
45
+ .to eq(must: [{foo: 'bar'}], should: [], must_not: [], minimum_should_match: 3)
46
+ end
20
47
  specify do
21
48
  expect(described_class.new(must: [proc { match foo: 'bar' }, {moo: 'baz'}]).value.to_h)
22
49
  .to eq(must: [{match: {foo: 'bar'}}, {moo: 'baz'}], should: [], must_not: [], minimum_should_match: nil)
@@ -73,14 +100,16 @@ shared_examples :query_storage do |param_name|
73
100
  expect { subject.and(moo: 'baz') }
74
101
  .to change { subject.value.to_h }
75
102
  .from(must: [{foo: 'bar'}], should: [{moo: 'baz'}], must_not: [], minimum_should_match: nil)
76
- .to(must: [{bool: {must: {foo: 'bar'}, should: {moo: 'baz'}}}, {moo: 'baz'}], should: [], must_not: [], minimum_should_match: nil)
103
+ .to(must: [{bool: {must: {foo: 'bar'}, should: {moo: 'baz'}}},
104
+ {moo: 'baz'}], should: [], must_not: [], minimum_should_match: nil)
77
105
  end
78
106
 
79
107
  specify do
80
108
  expect { subject.and([{moo: 'baz'}, {doo: 'scooby'}]) }
81
109
  .to change { subject.value.to_h }
82
110
  .from(must: [{foo: 'bar'}], should: [{moo: 'baz'}], must_not: [], minimum_should_match: nil)
83
- .to(must: [{bool: {must: {foo: 'bar'}, should: {moo: 'baz'}}}, bool: {must: [{moo: 'baz'}, {doo: 'scooby'}]}], should: [], must_not: [], minimum_should_match: nil)
111
+ .to(must: [{bool: {must: {foo: 'bar'}, should: {moo: 'baz'}}},
112
+ bool: {must: [{moo: 'baz'}, {doo: 'scooby'}]}], should: [], must_not: [], minimum_should_match: nil)
84
113
  end
85
114
 
86
115
  specify do
@@ -93,7 +122,8 @@ shared_examples :query_storage do |param_name|
93
122
  expect { subject.and(should: {foo: 'bar'}) }
94
123
  .to change { subject.value.to_h }
95
124
  .from(must: [{foo: 'bar'}], should: [{moo: 'baz'}], must_not: [], minimum_should_match: nil)
96
- .to(must: [{bool: {must: {foo: 'bar'}, should: {moo: 'baz'}}}, {bool: {should: {foo: 'bar'}}}], should: [], must_not: [], minimum_should_match: nil)
125
+ .to(must: [{bool: {must: {foo: 'bar'}, should: {moo: 'baz'}}},
126
+ {bool: {should: {foo: 'bar'}}}], should: [], must_not: [], minimum_should_match: nil)
97
127
  end
98
128
 
99
129
  context do
@@ -113,14 +143,16 @@ shared_examples :query_storage do |param_name|
113
143
  expect { subject.or(moo: 'baz') }
114
144
  .to change { subject.value.to_h }
115
145
  .from(must: [{foo: 'bar'}], should: [{moo: 'baz'}], must_not: [], minimum_should_match: nil)
116
- .to(must: [], should: [{bool: {must: {foo: 'bar'}, should: {moo: 'baz'}}}, {moo: 'baz'}], must_not: [], minimum_should_match: nil)
146
+ .to(must: [], should: [{bool: {must: {foo: 'bar'}, should: {moo: 'baz'}}},
147
+ {moo: 'baz'}], must_not: [], minimum_should_match: nil)
117
148
  end
118
149
 
119
150
  specify do
120
151
  expect { subject.or([{moo: 'baz'}, {doo: 'scooby'}]) }
121
152
  .to change { subject.value.to_h }
122
153
  .from(must: [{foo: 'bar'}], should: [{moo: 'baz'}], must_not: [], minimum_should_match: nil)
123
- .to(must: [], should: [{bool: {must: {foo: 'bar'}, should: {moo: 'baz'}}}, bool: {must: [{moo: 'baz'}, {doo: 'scooby'}]}], must_not: [], minimum_should_match: nil)
154
+ .to(must: [], should: [{bool: {must: {foo: 'bar'}, should: {moo: 'baz'}}},
155
+ bool: {must: [{moo: 'baz'}, {doo: 'scooby'}]}], must_not: [], minimum_should_match: nil)
124
156
  end
125
157
 
126
158
  specify do
@@ -133,7 +165,8 @@ shared_examples :query_storage do |param_name|
133
165
  expect { subject.or(should: {foo: 'bar'}) }
134
166
  .to change { subject.value.to_h }
135
167
  .from(must: [{foo: 'bar'}], should: [{moo: 'baz'}], must_not: [], minimum_should_match: nil)
136
- .to(must: [], should: [{bool: {must: {foo: 'bar'}, should: {moo: 'baz'}}}, {bool: {should: {foo: 'bar'}}}], must_not: [], minimum_should_match: nil)
168
+ .to(must: [], should: [{bool: {must: {foo: 'bar'}, should: {moo: 'baz'}}},
169
+ {bool: {should: {foo: 'bar'}}}], must_not: [], minimum_should_match: nil)
137
170
  end
138
171
 
139
172
  context do
@@ -160,7 +193,12 @@ shared_examples :query_storage do |param_name|
160
193
  expect { subject.not([{moo: 'baz'}, {doo: 'scooby'}]) }
161
194
  .to change { subject.value.to_h }
162
195
  .from(must: [{foo: 'bar'}], should: [{moo: 'baz'}], must_not: [], minimum_should_match: nil)
163
- .to(must: [{foo: 'bar'}], should: [{moo: 'baz'}], must_not: [{bool: {must: [{moo: 'baz'}, {doo: 'scooby'}]}}], minimum_should_match: nil)
196
+ .to(
197
+ must: [{foo: 'bar'}],
198
+ should: [{moo: 'baz'}],
199
+ must_not: [{bool: {must: [{moo: 'baz'}, {doo: 'scooby'}]}}],
200
+ minimum_should_match: nil
201
+ )
164
202
  end
165
203
 
166
204
  specify do
@@ -173,7 +211,11 @@ shared_examples :query_storage do |param_name|
173
211
  expect { subject.not(should: {foo: 'bar'}) }
174
212
  .to change { subject.value.to_h }
175
213
  .from(must: [{foo: 'bar'}], should: [{moo: 'baz'}], must_not: [], minimum_should_match: nil)
176
- .to(must: [{foo: 'bar'}], should: [{moo: 'baz'}], must_not: [{bool: {should: {foo: 'bar'}}}], minimum_should_match: nil)
214
+ .to(
215
+ must: [{foo: 'bar'}], should: [{moo: 'baz'}],
216
+ must_not: [{bool: {should: {foo: 'bar'}}}],
217
+ minimum_should_match: nil
218
+ )
177
219
  end
178
220
 
179
221
  context do
@@ -223,7 +265,8 @@ shared_examples :query_storage do |param_name|
223
265
  expect { subject.update!(must: proc { match foo: 'bar' }) }
224
266
  .to change { subject.value.to_h }
225
267
  .from(must: [{foo: 'bar'}], should: [{moo: 'baz'}], must_not: [], minimum_should_match: nil)
226
- .to(must: [{foo: 'bar'}, {match: {foo: 'bar'}}], should: [{moo: 'baz'}], must_not: [], minimum_should_match: nil)
268
+ .to(must: [{foo: 'bar'},
269
+ {match: {foo: 'bar'}}], should: [{moo: 'baz'}], must_not: [], minimum_should_match: nil)
227
270
  end
228
271
 
229
272
  specify do
@@ -237,7 +280,8 @@ shared_examples :query_storage do |param_name|
237
280
  expect { subject.update!(foobar: {foo: 'bar'}) }
238
281
  .to change { subject.value.to_h }
239
282
  .from(must: [{foo: 'bar'}], should: [{moo: 'baz'}], must_not: [], minimum_should_match: nil)
240
- .to(must: [{foo: 'bar'}, {foobar: {foo: 'bar'}}], should: [{moo: 'baz'}], must_not: [], minimum_should_match: nil)
283
+ .to(must: [{foo: 'bar'},
284
+ {foobar: {foo: 'bar'}}], should: [{moo: 'baz'}], must_not: [], minimum_should_match: nil)
241
285
  end
242
286
 
243
287
  specify do
@@ -279,7 +323,8 @@ shared_examples :query_storage do |param_name|
279
323
  expect { subject.merge!(described_class.new(moo: 'baz')) }
280
324
  .to change { subject.value.to_h }
281
325
  .from(must: [{foo: 'bar'}], should: [{moo: 'baz'}], must_not: [], minimum_should_match: nil)
282
- .to(must: [{bool: {must: {foo: 'bar'}, should: {moo: 'baz'}}}, {moo: 'baz'}], should: [], must_not: [], minimum_should_match: nil)
326
+ .to(must: [{bool: {must: {foo: 'bar'}, should: {moo: 'baz'}}},
327
+ {moo: 'baz'}], should: [], must_not: [], minimum_should_match: nil)
283
328
  end
284
329
 
285
330
  specify do
@@ -292,7 +337,8 @@ shared_examples :query_storage do |param_name|
292
337
  expect { subject.merge!(described_class.new(should: {foo: 'bar'})) }
293
338
  .to change { subject.value.to_h }
294
339
  .from(must: [{foo: 'bar'}], should: [{moo: 'baz'}], must_not: [], minimum_should_match: nil)
295
- .to(must: [{bool: {must: {foo: 'bar'}, should: {moo: 'baz'}}}, {bool: {should: {foo: 'bar'}}}], should: [], must_not: [], minimum_should_match: nil)
340
+ .to(must: [{bool: {must: {foo: 'bar'}, should: {moo: 'baz'}}},
341
+ {bool: {should: {foo: 'bar'}}}], should: [], must_not: [], minimum_should_match: nil)
296
342
  end
297
343
 
298
344
  context do
@@ -20,7 +20,10 @@ describe Chewy::Search::Parameters::SearchAfter do
20
20
  end
21
21
 
22
22
  describe '#merge!' do
23
- specify { expect { subject.merge!(described_class.new(:baz)) }.to change { subject.value }.from([:foo, 42]).to([:baz]) }
23
+ specify do
24
+ expect { subject.merge!(described_class.new(:baz)) }
25
+ .to change { subject.value }.from([:foo, 42]).to([:baz])
26
+ end
24
27
  specify { expect { subject.merge!(described_class.new) }.not_to change { subject.value }.from([:foo, 42]) }
25
28
  end
26
29
 
@@ -12,8 +12,14 @@ describe Chewy::Search::Parameters::Source do
12
12
  specify { expect(described_class.new(true).value).to eq(includes: [], excludes: [], enabled: true) }
13
13
  specify { expect(described_class.new(a: 1).value).to eq(includes: [], excludes: [], enabled: true) }
14
14
  specify { expect(described_class.new(includes: :foo).value).to eq(includes: %w[foo], excludes: [], enabled: true) }
15
- specify { expect(described_class.new(includes: :foo, excludes: 42).value).to eq(includes: %w[foo], excludes: %w[42], enabled: true) }
16
- specify { expect(described_class.new(includes: :foo, excludes: 42, enabled: false).value).to eq(includes: %w[foo], excludes: %w[42], enabled: true) }
15
+ specify do
16
+ expect(described_class.new(includes: :foo, excludes: 42).value)
17
+ .to eq(includes: %w[foo], excludes: %w[42], enabled: true)
18
+ end
19
+ specify do
20
+ expect(described_class.new(includes: :foo, excludes: 42, enabled: false).value)
21
+ .to eq(includes: %w[foo], excludes: %w[42], enabled: true)
22
+ end
17
23
  end
18
24
 
19
25
  describe '#replace!' do
@@ -0,0 +1,5 @@
1
+ require 'chewy/search/parameters/bool_storage_examples'
2
+
3
+ describe Chewy::Search::Parameters::TrackTotalHits do
4
+ it_behaves_like :bool_storage, :track_total_hits
5
+ end
@@ -13,7 +13,7 @@ describe Chewy::Search::Parameters do
13
13
 
14
14
  specify { expect(subject.storages[:limit]).to equal(limit) }
15
15
  specify { expect(subject.storages[:limit].value).to eq(3) }
16
- specify { expect(subject.storages[:order].value).to eq('foo' => nil) }
16
+ specify { expect(subject.storages[:order].value).to eq(['foo']) }
17
17
 
18
18
  specify { expect { described_class.new(offset: limit) }.to raise_error(TypeError) }
19
19
  end
@@ -55,7 +55,10 @@ describe Chewy::Search::Parameters do
55
55
  subject { described_class.new(limit: 10, offset: 20, order: :foo) }
56
56
 
57
57
  specify { expect { subject.only!([:limit]) }.to change { subject.clone }.to(described_class.new(limit: 10)) }
58
- specify { expect { subject.only!(%i[offset order]) }.to change { subject.clone }.to(described_class.new(offset: 20, order: :foo)) }
58
+ specify do
59
+ expect { subject.only!(%i[offset order]) }
60
+ .to change { subject.clone }.to(described_class.new(offset: 20, order: :foo))
61
+ end
59
62
  specify { expect { subject.only!(%i[limit something]) }.to raise_error NameError }
60
63
  specify { expect { subject.only!([]) }.to raise_error ArgumentError }
61
64
  end
@@ -63,8 +66,14 @@ describe Chewy::Search::Parameters do
63
66
  describe '#except!' do
64
67
  subject { described_class.new(limit: 10, offset: 20, order: :foo) }
65
68
 
66
- specify { expect { subject.except!([:limit]) }.to change { subject.clone }.to(described_class.new(offset: 20, order: :foo)) }
67
- specify { expect { subject.except!(%i[offset order]) }.to change { subject.clone }.to(described_class.new(limit: 10)) }
69
+ specify do
70
+ expect { subject.except!([:limit]) }
71
+ .to change { subject.clone }.to(described_class.new(offset: 20, order: :foo))
72
+ end
73
+ specify do
74
+ expect { subject.except!(%i[offset order]) }
75
+ .to change { subject.clone }.to(described_class.new(limit: 10))
76
+ end
68
77
  specify { expect { subject.except!(%i[limit something]) }.to raise_error NameError }
69
78
  specify { expect { subject.except!([]) }.to raise_error ArgumentError }
70
79
  end
@@ -119,6 +128,11 @@ describe Chewy::Search::Parameters do
119
128
  specify { expect(subject.render).to eq(body: {}, allow_partial_search_results: true) }
120
129
  end
121
130
 
131
+ context do
132
+ subject { described_class.new(ignore_unavailable: true) }
133
+ specify { expect(subject.render).to eq(body: {}, ignore_unavailable: true) }
134
+ end
135
+
122
136
  context do
123
137
  subject { described_class.new(query: {foo: 'bar'}, filter: {moo: 'baz'}) }
124
138
  specify { expect(subject.render).to eq(body: {query: {bool: {must: {foo: 'bar'}, filter: {moo: 'baz'}}}}) }