chewy 5.1.0 → 7.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (234) 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/workflows/ruby.yml +73 -0
  7. data/.rubocop.yml +13 -8
  8. data/.rubocop_todo.yml +110 -22
  9. data/CHANGELOG.md +449 -347
  10. data/CODE_OF_CONDUCT.md +14 -0
  11. data/CONTRIBUTING.md +63 -0
  12. data/Gemfile +3 -7
  13. data/Guardfile +3 -1
  14. data/LICENSE.txt +1 -1
  15. data/README.md +423 -311
  16. data/chewy.gemspec +8 -10
  17. data/gemfiles/rails.5.2.activerecord.gemfile +9 -14
  18. data/gemfiles/rails.6.0.activerecord.gemfile +11 -0
  19. data/gemfiles/rails.6.1.activerecord.gemfile +13 -0
  20. data/gemfiles/rails.7.0.activerecord.gemfile +13 -0
  21. data/lib/chewy/config.rb +42 -60
  22. data/lib/chewy/errors.rb +4 -10
  23. data/lib/chewy/fields/base.rb +80 -20
  24. data/lib/chewy/fields/root.rb +7 -17
  25. data/lib/chewy/index/actions.rb +62 -35
  26. data/lib/chewy/{type → index}/adapter/active_record.rb +18 -4
  27. data/lib/chewy/{type → index}/adapter/base.rb +2 -3
  28. data/lib/chewy/{type → index}/adapter/object.rb +28 -32
  29. data/lib/chewy/{type → index}/adapter/orm.rb +26 -24
  30. data/lib/chewy/index/aliases.rb +14 -5
  31. data/lib/chewy/{type → index}/crutch.rb +5 -5
  32. data/lib/chewy/index/import/bulk_builder.rb +311 -0
  33. data/lib/chewy/{type → index}/import/bulk_request.rb +6 -7
  34. data/lib/chewy/{type → index}/import/journal_builder.rb +11 -12
  35. data/lib/chewy/{type → index}/import/routine.rb +17 -16
  36. data/lib/chewy/{type → index}/import.rb +51 -33
  37. data/lib/chewy/{type → index}/mapping.rb +32 -37
  38. data/lib/chewy/index/observe/active_record_methods.rb +87 -0
  39. data/lib/chewy/index/observe/callback.rb +34 -0
  40. data/lib/chewy/index/observe.rb +17 -0
  41. data/lib/chewy/index/specification.rb +1 -0
  42. data/lib/chewy/{type → index}/syncer.rb +61 -62
  43. data/lib/chewy/{type → index}/witchcraft.rb +15 -9
  44. data/lib/chewy/{type → index}/wrapper.rb +13 -3
  45. data/lib/chewy/index.rb +46 -96
  46. data/lib/chewy/journal.rb +25 -14
  47. data/lib/chewy/minitest/helpers.rb +86 -13
  48. data/lib/chewy/minitest/search_index_receiver.rb +22 -26
  49. data/lib/chewy/multi_search.rb +62 -0
  50. data/lib/chewy/railtie.rb +6 -20
  51. data/lib/chewy/rake_helper.rb +136 -108
  52. data/lib/chewy/rspec/build_query.rb +12 -0
  53. data/lib/chewy/rspec/helpers.rb +55 -0
  54. data/lib/chewy/rspec/update_index.rb +55 -44
  55. data/lib/chewy/rspec.rb +2 -0
  56. data/lib/chewy/runtime.rb +1 -1
  57. data/lib/chewy/search/loader.rb +19 -41
  58. data/lib/chewy/search/parameters/collapse.rb +16 -0
  59. data/lib/chewy/search/parameters/concerns/query_storage.rb +2 -2
  60. data/lib/chewy/search/parameters/ignore_unavailable.rb +27 -0
  61. data/lib/chewy/search/parameters/indices.rb +12 -57
  62. data/lib/chewy/search/parameters/none.rb +1 -3
  63. data/lib/chewy/search/parameters/order.rb +6 -19
  64. data/lib/chewy/search/parameters/source.rb +5 -1
  65. data/lib/chewy/search/parameters/track_total_hits.rb +16 -0
  66. data/lib/chewy/search/parameters.rb +7 -4
  67. data/lib/chewy/search/query_proxy.rb +9 -2
  68. data/lib/chewy/search/request.rb +180 -154
  69. data/lib/chewy/search/response.rb +5 -5
  70. data/lib/chewy/search/scoping.rb +7 -8
  71. data/lib/chewy/search/scrolling.rb +16 -13
  72. data/lib/chewy/search.rb +7 -22
  73. data/lib/chewy/stash.rb +19 -30
  74. data/lib/chewy/strategy/active_job.rb +2 -2
  75. data/lib/chewy/strategy/atomic_no_refresh.rb +18 -0
  76. data/lib/chewy/strategy/base.rb +10 -0
  77. data/lib/chewy/strategy/lazy_sidekiq.rb +64 -0
  78. data/lib/chewy/strategy/sidekiq.rb +3 -2
  79. data/lib/chewy/strategy.rb +5 -19
  80. data/lib/chewy/version.rb +1 -1
  81. data/lib/chewy.rb +36 -80
  82. data/lib/generators/chewy/install_generator.rb +1 -1
  83. data/lib/tasks/chewy.rake +26 -32
  84. data/migration_guide.md +56 -0
  85. data/spec/chewy/config_spec.rb +15 -61
  86. data/spec/chewy/fields/base_spec.rb +432 -145
  87. data/spec/chewy/fields/root_spec.rb +20 -28
  88. data/spec/chewy/fields/time_fields_spec.rb +5 -5
  89. data/spec/chewy/index/actions_spec.rb +388 -55
  90. data/spec/chewy/{type → index}/adapter/active_record_spec.rb +110 -44
  91. data/spec/chewy/{type → index}/adapter/object_spec.rb +21 -6
  92. data/spec/chewy/index/aliases_spec.rb +3 -3
  93. data/spec/chewy/index/import/bulk_builder_spec.rb +494 -0
  94. data/spec/chewy/{type → index}/import/bulk_request_spec.rb +5 -12
  95. data/spec/chewy/{type → index}/import/journal_builder_spec.rb +14 -22
  96. data/spec/chewy/{type → index}/import/routine_spec.rb +19 -19
  97. data/spec/chewy/{type → index}/import_spec.rb +149 -96
  98. data/spec/chewy/index/mapping_spec.rb +135 -0
  99. data/spec/chewy/index/observe/active_record_methods_spec.rb +68 -0
  100. data/spec/chewy/index/observe/callback_spec.rb +139 -0
  101. data/spec/chewy/index/observe_spec.rb +143 -0
  102. data/spec/chewy/index/settings_spec.rb +3 -1
  103. data/spec/chewy/index/specification_spec.rb +20 -30
  104. data/spec/chewy/{type → index}/syncer_spec.rb +14 -19
  105. data/spec/chewy/{type → index}/witchcraft_spec.rb +34 -21
  106. data/spec/chewy/index/wrapper_spec.rb +100 -0
  107. data/spec/chewy/index_spec.rb +69 -137
  108. data/spec/chewy/journal_spec.rb +46 -91
  109. data/spec/chewy/minitest/helpers_spec.rb +122 -14
  110. data/spec/chewy/minitest/search_index_receiver_spec.rb +24 -26
  111. data/spec/chewy/multi_search_spec.rb +84 -0
  112. data/spec/chewy/rake_helper_spec.rb +293 -101
  113. data/spec/chewy/rspec/build_query_spec.rb +34 -0
  114. data/spec/chewy/rspec/helpers_spec.rb +61 -0
  115. data/spec/chewy/rspec/update_index_spec.rb +106 -102
  116. data/spec/chewy/runtime_spec.rb +2 -2
  117. data/spec/chewy/search/loader_spec.rb +19 -53
  118. data/spec/chewy/search/pagination/kaminari_examples.rb +3 -5
  119. data/spec/chewy/search/pagination/kaminari_spec.rb +1 -1
  120. data/spec/chewy/search/parameters/collapse_spec.rb +5 -0
  121. data/spec/chewy/search/parameters/ignore_unavailable_spec.rb +67 -0
  122. data/spec/chewy/search/parameters/indices_spec.rb +26 -118
  123. data/spec/chewy/search/parameters/none_spec.rb +1 -1
  124. data/spec/chewy/search/parameters/order_spec.rb +18 -11
  125. data/spec/chewy/search/parameters/query_storage_examples.rb +67 -21
  126. data/spec/chewy/search/parameters/search_after_spec.rb +4 -1
  127. data/spec/chewy/search/parameters/source_spec.rb +8 -2
  128. data/spec/chewy/search/parameters/track_total_hits_spec.rb +5 -0
  129. data/spec/chewy/search/parameters_spec.rb +23 -7
  130. data/spec/chewy/search/query_proxy_spec.rb +68 -17
  131. data/spec/chewy/search/request_spec.rb +344 -149
  132. data/spec/chewy/search/response_spec.rb +35 -25
  133. data/spec/chewy/search/scrolling_spec.rb +28 -26
  134. data/spec/chewy/search_spec.rb +69 -59
  135. data/spec/chewy/stash_spec.rb +16 -26
  136. data/spec/chewy/strategy/active_job_spec.rb +23 -10
  137. data/spec/chewy/strategy/atomic_no_refresh_spec.rb +60 -0
  138. data/spec/chewy/strategy/atomic_spec.rb +9 -10
  139. data/spec/chewy/strategy/lazy_sidekiq_spec.rb +214 -0
  140. data/spec/chewy/strategy/sidekiq_spec.rb +14 -10
  141. data/spec/chewy/strategy_spec.rb +19 -15
  142. data/spec/chewy_spec.rb +17 -110
  143. data/spec/spec_helper.rb +6 -29
  144. data/spec/support/active_record.rb +43 -5
  145. metadata +102 -198
  146. data/.travis.yml +0 -45
  147. data/Appraisals +0 -81
  148. data/LEGACY_DSL.md +0 -497
  149. data/gemfiles/rails.4.0.activerecord.gemfile +0 -15
  150. data/gemfiles/rails.4.1.activerecord.gemfile +0 -15
  151. data/gemfiles/rails.4.2.activerecord.gemfile +0 -16
  152. data/gemfiles/rails.4.2.mongoid.5.2.gemfile +0 -16
  153. data/gemfiles/rails.5.0.activerecord.gemfile +0 -16
  154. data/gemfiles/rails.5.0.mongoid.6.1.gemfile +0 -16
  155. data/gemfiles/rails.5.1.activerecord.gemfile +0 -16
  156. data/gemfiles/rails.5.1.mongoid.6.3.gemfile +0 -16
  157. data/gemfiles/sequel.4.45.gemfile +0 -11
  158. data/lib/chewy/backports/deep_dup.rb +0 -46
  159. data/lib/chewy/backports/duplicable.rb +0 -91
  160. data/lib/chewy/query/compose.rb +0 -68
  161. data/lib/chewy/query/criteria.rb +0 -191
  162. data/lib/chewy/query/filters.rb +0 -244
  163. data/lib/chewy/query/loading.rb +0 -110
  164. data/lib/chewy/query/nodes/and.rb +0 -25
  165. data/lib/chewy/query/nodes/base.rb +0 -17
  166. data/lib/chewy/query/nodes/bool.rb +0 -34
  167. data/lib/chewy/query/nodes/equal.rb +0 -34
  168. data/lib/chewy/query/nodes/exists.rb +0 -20
  169. data/lib/chewy/query/nodes/expr.rb +0 -28
  170. data/lib/chewy/query/nodes/field.rb +0 -110
  171. data/lib/chewy/query/nodes/has_child.rb +0 -15
  172. data/lib/chewy/query/nodes/has_parent.rb +0 -15
  173. data/lib/chewy/query/nodes/has_relation.rb +0 -59
  174. data/lib/chewy/query/nodes/match_all.rb +0 -11
  175. data/lib/chewy/query/nodes/missing.rb +0 -20
  176. data/lib/chewy/query/nodes/not.rb +0 -25
  177. data/lib/chewy/query/nodes/or.rb +0 -25
  178. data/lib/chewy/query/nodes/prefix.rb +0 -19
  179. data/lib/chewy/query/nodes/query.rb +0 -20
  180. data/lib/chewy/query/nodes/range.rb +0 -63
  181. data/lib/chewy/query/nodes/raw.rb +0 -15
  182. data/lib/chewy/query/nodes/regexp.rb +0 -35
  183. data/lib/chewy/query/nodes/script.rb +0 -20
  184. data/lib/chewy/query/pagination.rb +0 -25
  185. data/lib/chewy/query.rb +0 -1142
  186. data/lib/chewy/search/pagination/will_paginate.rb +0 -43
  187. data/lib/chewy/search/parameters/types.rb +0 -20
  188. data/lib/chewy/strategy/resque.rb +0 -27
  189. data/lib/chewy/strategy/shoryuken.rb +0 -40
  190. data/lib/chewy/type/actions.rb +0 -43
  191. data/lib/chewy/type/adapter/mongoid.rb +0 -67
  192. data/lib/chewy/type/adapter/sequel.rb +0 -93
  193. data/lib/chewy/type/import/bulk_builder.rb +0 -122
  194. data/lib/chewy/type/observe.rb +0 -82
  195. data/lib/chewy/type.rb +0 -117
  196. data/lib/sequel/plugins/chewy_observe.rb +0 -63
  197. data/spec/chewy/query/criteria_spec.rb +0 -700
  198. data/spec/chewy/query/filters_spec.rb +0 -201
  199. data/spec/chewy/query/loading_spec.rb +0 -124
  200. data/spec/chewy/query/nodes/and_spec.rb +0 -12
  201. data/spec/chewy/query/nodes/bool_spec.rb +0 -14
  202. data/spec/chewy/query/nodes/equal_spec.rb +0 -32
  203. data/spec/chewy/query/nodes/exists_spec.rb +0 -18
  204. data/spec/chewy/query/nodes/has_child_spec.rb +0 -59
  205. data/spec/chewy/query/nodes/has_parent_spec.rb +0 -59
  206. data/spec/chewy/query/nodes/match_all_spec.rb +0 -11
  207. data/spec/chewy/query/nodes/missing_spec.rb +0 -16
  208. data/spec/chewy/query/nodes/not_spec.rb +0 -14
  209. data/spec/chewy/query/nodes/or_spec.rb +0 -12
  210. data/spec/chewy/query/nodes/prefix_spec.rb +0 -16
  211. data/spec/chewy/query/nodes/query_spec.rb +0 -12
  212. data/spec/chewy/query/nodes/range_spec.rb +0 -32
  213. data/spec/chewy/query/nodes/raw_spec.rb +0 -11
  214. data/spec/chewy/query/nodes/regexp_spec.rb +0 -43
  215. data/spec/chewy/query/nodes/script_spec.rb +0 -15
  216. data/spec/chewy/query/pagination/kaminari_spec.rb +0 -5
  217. data/spec/chewy/query/pagination/will_paginate_spec.rb +0 -5
  218. data/spec/chewy/query/pagination_spec.rb +0 -39
  219. data/spec/chewy/query_spec.rb +0 -637
  220. data/spec/chewy/search/pagination/will_paginate_examples.rb +0 -63
  221. data/spec/chewy/search/pagination/will_paginate_spec.rb +0 -23
  222. data/spec/chewy/search/parameters/types_spec.rb +0 -5
  223. data/spec/chewy/strategy/resque_spec.rb +0 -46
  224. data/spec/chewy/strategy/shoryuken_spec.rb +0 -66
  225. data/spec/chewy/type/actions_spec.rb +0 -50
  226. data/spec/chewy/type/adapter/mongoid_spec.rb +0 -372
  227. data/spec/chewy/type/adapter/sequel_spec.rb +0 -472
  228. data/spec/chewy/type/import/bulk_builder_spec.rb +0 -279
  229. data/spec/chewy/type/mapping_spec.rb +0 -173
  230. data/spec/chewy/type/observe_spec.rb +0 -137
  231. data/spec/chewy/type/wrapper_spec.rb +0 -98
  232. data/spec/chewy/type_spec.rb +0 -55
  233. data/spec/support/mongoid.rb +0 -93
  234. data/spec/support/sequel.rb +0 -80
@@ -4,27 +4,31 @@ describe Chewy::RakeHelper, :orm do
4
4
  before { Chewy.massacre }
5
5
 
6
6
  before do
7
+ described_class.instance_variable_set(:@journal_exists, journal_exists)
8
+
7
9
  stub_model(:city)
8
10
  stub_model(:country)
9
11
 
10
- stub_index(:places) do
11
- define_type City do
12
- field :name
13
- field :updated_at, type: 'date'
14
- end
15
- define_type Country
12
+ stub_index(:cities) do
13
+ index_scope City
14
+ field :name
15
+ field :updated_at, type: 'date'
16
+ end
17
+ stub_index(:countries) do
18
+ index_scope Country
16
19
  end
17
20
  stub_index(:users)
18
21
 
19
- allow(described_class).to receive(:all_indexes) { [PlacesIndex, UsersIndex] }
22
+ allow(described_class).to receive(:all_indexes) { [CitiesIndex, CountriesIndex, UsersIndex] }
20
23
  end
21
24
 
25
+ let(:journal_exists) { true }
22
26
  let!(:cities) { Array.new(3) { |i| City.create!(name: "Name#{i + 1}") } }
23
27
  let!(:countries) { Array.new(2) { |i| Country.create!(name: "Name#{i + 1}") } }
24
28
  let(:journal) do
25
29
  Chewy::Stash::Journal.import([
26
30
  {
27
- index_name: 'places',
31
+ index_name: 'cities',
28
32
  type_name: 'city',
29
33
  action: 'index',
30
34
  references: cities.first(2).map(&:id).map(&:to_s)
@@ -32,7 +36,7 @@ describe Chewy::RakeHelper, :orm do
32
36
  created_at: 2.minutes.since
33
37
  },
34
38
  {
35
- index_name: 'places',
39
+ index_name: 'countries',
36
40
  type_name: 'country',
37
41
  action: 'index',
38
42
  references: [Base64.encode64(countries.first.id.to_s.to_json)],
@@ -47,87 +51,115 @@ describe Chewy::RakeHelper, :orm do
47
51
  specify do
48
52
  output = StringIO.new
49
53
  expect { described_class.reset(output: output) }
50
- .to update_index(PlacesIndex::City)
54
+ .to update_index(CitiesIndex)
51
55
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
52
- \\AResetting PlacesIndex
53
- Imported PlacesIndex::City in \\d+s, stats: index 3
54
- Imported PlacesIndex::Country in \\d+s, stats: index 2
55
- Applying journal to \\[PlacesIndex::City, PlacesIndex::Country\\], 3 entries, stage 1
56
- Imported PlacesIndex::City in \\d+s, stats: index 2
57
- Imported PlacesIndex::Country in \\d+s, stats: index 1
58
- Imported Chewy::Stash::Specification::Specification in \\d+s, stats: index 1
56
+ \\AResetting CitiesIndex
57
+ Imported CitiesIndex in \\d+s, stats: index 3
58
+ Applying journal to \\[CitiesIndex\\], 2 entries, stage 1
59
+ Imported CitiesIndex in \\d+s, stats: index 2
60
+ Imported Chewy::Stash::Specification in \\d+s, stats: index 1
61
+ Resetting CountriesIndex
62
+ Imported CountriesIndex in \\d+s, stats: index 2
63
+ Applying journal to \\[CountriesIndex\\], 1 entries, stage 1
64
+ Imported CountriesIndex in \\d+s, stats: index 1
65
+ Imported Chewy::Stash::Specification in \\d+s, stats: index 1
59
66
  Resetting UsersIndex
60
- Imported Chewy::Stash::Specification::Specification in \\d+s, stats: index 1
67
+ Imported UsersIndex in 1s, stats:\s
68
+ Imported Chewy::Stash::Specification in \\d+s, stats: index 1
61
69
  Total: \\d+s\\Z
62
70
  OUTPUT
63
71
  end
64
72
 
65
73
  specify do
66
74
  output = StringIO.new
67
- expect { described_class.reset(only: 'places', output: output) }
68
- .to update_index(PlacesIndex::City)
75
+ expect { described_class.reset(only: 'cities', output: output) }
76
+ .to update_index(CitiesIndex)
69
77
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
70
- \\AResetting PlacesIndex
71
- Imported PlacesIndex::City in \\d+s, stats: index 3
72
- Imported PlacesIndex::Country in \\d+s, stats: index 2
73
- Applying journal to \\[PlacesIndex::City, PlacesIndex::Country\\], 3 entries, stage 1
74
- Imported PlacesIndex::City in \\d+s, stats: index 2
75
- Imported PlacesIndex::Country in \\d+s, stats: index 1
76
- Imported Chewy::Stash::Specification::Specification in \\d+s, stats: index 1
78
+ \\AResetting CitiesIndex
79
+ Imported CitiesIndex in \\d+s, stats: index 3
80
+ Applying journal to \\[CitiesIndex\\], 2 entries, stage 1
81
+ Imported CitiesIndex in \\d+s, stats: index 2
82
+ Imported Chewy::Stash::Specification in \\d+s, stats: index 1
77
83
  Total: \\d+s\\Z
78
84
  OUTPUT
79
85
  end
80
86
 
81
87
  specify do
82
88
  output = StringIO.new
83
- expect { described_class.reset(except: PlacesIndex, output: output) }
84
- .not_to update_index(PlacesIndex::City)
89
+ expect { described_class.reset(except: [CitiesIndex, CountriesIndex], output: output) }
90
+ .not_to update_index(CitiesIndex)
85
91
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
86
92
  \\AResetting UsersIndex
87
- Imported Chewy::Stash::Specification::Specification in \\d+s, stats: index 1
93
+ Imported UsersIndex in 1s, stats:\s
94
+ Imported Chewy::Stash::Specification in \\d+s, stats: index 1
88
95
  Total: \\d+s\\Z
89
96
  OUTPUT
90
97
  end
98
+
99
+ context 'when journal is missing' do
100
+ let(:journal_exists) { false }
101
+
102
+ specify do
103
+ output = StringIO.new
104
+ expect { described_class.reset(only: [CitiesIndex], output: output) }
105
+ .to update_index(CitiesIndex)
106
+ expect(output.string).to include(
107
+ "############################################################\n"\
108
+ "WARN: You are risking to lose some changes during the reset.\n" \
109
+ " Please consider enabling journaling.\n" \
110
+ ' See https://github.com/toptal/chewy#journaling'
111
+ )
112
+ end
113
+ end
91
114
  end
92
115
 
93
116
  describe '.upgrade' do
94
117
  specify do
95
118
  output = StringIO.new
96
119
  expect { described_class.upgrade(output: output) }
97
- .to update_index(PlacesIndex::City)
120
+ .to update_index(CitiesIndex)
98
121
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
99
- \\AResetting PlacesIndex
100
- Imported PlacesIndex::City in \\d+s, stats: index 3
101
- Imported PlacesIndex::Country in \\d+s, stats: index 2
102
- Imported Chewy::Stash::Specification::Specification in \\d+s, stats: index 1
122
+ \\AResetting CitiesIndex
123
+ Imported CitiesIndex in \\d+s, stats: index 3
124
+ Imported Chewy::Stash::Specification in \\d+s, stats: index 1
125
+ Resetting CountriesIndex
126
+ Imported CountriesIndex in \\d+s, stats: index 2
127
+ Imported Chewy::Stash::Specification in \\d+s, stats: index 1
103
128
  Resetting UsersIndex
104
- Imported Chewy::Stash::Specification::Specification in \\d+s, stats: index 1
129
+ Imported UsersIndex in 1s, stats:\s
130
+ Imported Chewy::Stash::Specification in \\d+s, stats: index 1
105
131
  Total: \\d+s\\Z
106
132
  OUTPUT
107
133
  end
108
134
 
109
135
  context do
110
- before { PlacesIndex.reset! }
136
+ before do
137
+ CitiesIndex.reset!
138
+ CountriesIndex.reset!
139
+ end
111
140
 
112
141
  specify do
113
142
  output = StringIO.new
114
143
  expect { described_class.upgrade(output: output) }
115
- .not_to update_index(PlacesIndex::City)
144
+ .not_to update_index(CitiesIndex)
116
145
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
117
- \\ASkipping PlacesIndex, the specification didn't change
146
+ \\ASkipping CitiesIndex, the specification didn't change
147
+ Skipping CountriesIndex, the specification didn't change
118
148
  Resetting UsersIndex
119
- Imported Chewy::Stash::Specification::Specification in \\d+s, stats: index 1
149
+ Imported UsersIndex in 1s, stats:\s
150
+ Imported Chewy::Stash::Specification in \\d+s, stats: index 1
120
151
  Total: \\d+s\\Z
121
152
  OUTPUT
122
153
  end
123
154
 
124
155
  specify do
125
156
  output = StringIO.new
126
- expect { described_class.upgrade(except: PlacesIndex, output: output) }
127
- .not_to update_index(PlacesIndex::City)
157
+ expect { described_class.upgrade(except: [CitiesIndex, CountriesIndex], output: output) }
158
+ .not_to update_index(CitiesIndex)
128
159
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
129
160
  \\AResetting UsersIndex
130
- Imported Chewy::Stash::Specification::Specification in \\d+s, stats: index 1
161
+ Imported UsersIndex in 1s, stats:\s
162
+ Imported Chewy::Stash::Specification in \\d+s, stats: index 1
131
163
  Total: \\d+s\\Z
132
164
  OUTPUT
133
165
  end
@@ -137,8 +169,8 @@ Total: \\d+s\\Z
137
169
 
138
170
  specify do
139
171
  output = StringIO.new
140
- expect { described_class.upgrade(except: ['places'], output: output) }
141
- .not_to update_index(PlacesIndex::City)
172
+ expect { described_class.upgrade(except: %w[cities countries], output: output) }
173
+ .not_to update_index(CitiesIndex)
142
174
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
143
175
  \\ANo index specification was changed
144
176
  Total: \\d+s\\Z
@@ -152,45 +184,54 @@ Total: \\d+s\\Z
152
184
  specify do
153
185
  output = StringIO.new
154
186
  expect { described_class.update(output: output) }
155
- .not_to update_index(PlacesIndex::City)
187
+ .not_to update_index(CitiesIndex)
156
188
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
157
- \\ASkipping PlacesIndex, it does not exists \\(use rake chewy:reset\\[places\\] to create and update it\\)
189
+ \\ASkipping CitiesIndex, it does not exists \\(use rake chewy:reset\\[cities\\] to create and update it\\)
190
+ Skipping CountriesIndex, it does not exists \\(use rake chewy:reset\\[countries\\] to create and update it\\)
191
+ Skipping UsersIndex, it does not exists \\(use rake chewy:reset\\[users\\] to create and update it\\)
192
+ Total: \\d+s\\Z
158
193
  OUTPUT
159
194
  end
160
195
 
161
196
  context do
162
- before { PlacesIndex.reset! }
197
+ before do
198
+ CitiesIndex.reset!
199
+ CountriesIndex.reset!
200
+ end
163
201
 
164
202
  specify do
165
203
  output = StringIO.new
166
204
  expect { described_class.update(output: output) }
167
- .to update_index(PlacesIndex::City)
205
+ .to update_index(CitiesIndex)
168
206
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
169
- \\AUpdating PlacesIndex
170
- Imported PlacesIndex::City in \\d+s, stats: index 3
171
- Imported PlacesIndex::Country in \\d+s, stats: index 2
207
+ \\AUpdating CitiesIndex
208
+ Imported CitiesIndex in \\d+s, stats: index 3
209
+ Updating CountriesIndex
210
+ Imported CountriesIndex in \\d+s, stats: index 2
211
+ Skipping UsersIndex, it does not exists \\(use rake chewy:reset\\[users\\] to create and update it\\)
172
212
  Total: \\d+s\\Z
173
213
  OUTPUT
174
214
  end
175
215
 
176
216
  specify do
177
217
  output = StringIO.new
178
- expect { described_class.update(only: 'places#country', output: output) }
179
- .not_to update_index(PlacesIndex::City)
218
+ expect { described_class.update(only: 'countries', output: output) }
219
+ .not_to update_index(CitiesIndex)
180
220
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
181
- \\AUpdating PlacesIndex
182
- Imported PlacesIndex::Country in \\d+s, stats: index 2
221
+ \\AUpdating CountriesIndex
222
+ Imported CountriesIndex in \\d+s, stats: index 2
183
223
  Total: \\d+s\\Z
184
224
  OUTPUT
185
225
  end
186
226
 
187
227
  specify do
188
228
  output = StringIO.new
189
- expect { described_class.update(except: PlacesIndex::Country, output: output) }
190
- .to update_index(PlacesIndex::City)
229
+ expect { described_class.update(except: CountriesIndex, output: output) }
230
+ .to update_index(CitiesIndex)
191
231
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
192
- \\AUpdating PlacesIndex
193
- Imported PlacesIndex::City in \\d+s, stats: index 3
232
+ \\AUpdating CitiesIndex
233
+ Imported CitiesIndex in \\d+s, stats: index 3
234
+ Skipping UsersIndex, it does not exists \\(use rake chewy:reset\\[users\\] to create and update it\\)
194
235
  Total: \\d+s\\Z
195
236
  OUTPUT
196
237
  end
@@ -201,43 +242,50 @@ Total: \\d+s\\Z
201
242
  specify do
202
243
  output = StringIO.new
203
244
  expect { described_class.sync(output: output) }
204
- .to update_index(PlacesIndex::City)
245
+ .to update_index(CitiesIndex)
205
246
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
206
- \\ASynchronizing PlacesIndex::City
207
- Imported PlacesIndex::City in \\d+s, stats: index 3
247
+ \\ASynchronizing CitiesIndex
248
+ Imported CitiesIndex in \\d+s, stats: index 3
208
249
  Missing documents: \\[[^\\]]+\\]
209
250
  Took \\d+s
210
- Synchronizing PlacesIndex::Country
211
- PlacesIndex::Country doesn't support outdated synchronization
212
- Imported PlacesIndex::Country in \\d+s, stats: index 2
251
+ Synchronizing CountriesIndex
252
+ CountriesIndex doesn't support outdated synchronization
253
+ Imported CountriesIndex in \\d+s, stats: index 2
213
254
  Missing documents: \\[[^\\]]+\\]
214
255
  Took \\d+s
256
+ Synchronizing UsersIndex
257
+ UsersIndex doesn't support outdated synchronization
258
+ Skipping UsersIndex, up to date
259
+ Took \\d+s
215
260
  Total: \\d+s\\Z
216
261
  OUTPUT
217
262
  end
218
263
 
219
264
  context do
220
265
  before do
221
- PlacesIndex::City.import(cities.first(2))
222
- PlacesIndex::Country.import
266
+ CitiesIndex.import(cities.first(2))
267
+ CountriesIndex.import
223
268
 
224
- sleep(1) if ActiveSupport::VERSION::STRING < '4.1.0'
225
269
  cities.first.update(name: 'Name5')
226
270
  end
227
271
 
228
272
  specify do
229
273
  output = StringIO.new
230
274
  expect { described_class.sync(output: output) }
231
- .to update_index(PlacesIndex::City)
275
+ .to update_index(CitiesIndex)
232
276
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
233
- \\ASynchronizing PlacesIndex::City
234
- Imported PlacesIndex::City in \\d+s, stats: index 2
277
+ \\ASynchronizing CitiesIndex
278
+ Imported CitiesIndex in \\d+s, stats: index 2
235
279
  Missing documents: \\["#{cities.last.id}"\\]
236
280
  Outdated documents: \\["#{cities.first.id}"\\]
237
281
  Took \\d+s
238
- Synchronizing PlacesIndex::Country
239
- PlacesIndex::Country doesn't support outdated synchronization
240
- Skipping PlacesIndex::Country, up to date
282
+ Synchronizing CountriesIndex
283
+ CountriesIndex doesn't support outdated synchronization
284
+ Skipping CountriesIndex, up to date
285
+ Took \\d+s
286
+ Synchronizing UsersIndex
287
+ UsersIndex doesn't support outdated synchronization
288
+ Skipping UsersIndex, up to date
241
289
  Took \\d+s
242
290
  Total: \\d+s\\Z
243
291
  OUTPUT
@@ -245,11 +293,11 @@ Total: \\d+s\\Z
245
293
 
246
294
  specify do
247
295
  output = StringIO.new
248
- expect { described_class.sync(only: PlacesIndex::City, output: output) }
249
- .to update_index(PlacesIndex::City)
296
+ expect { described_class.sync(only: CitiesIndex, output: output) }
297
+ .to update_index(CitiesIndex)
250
298
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
251
- \\ASynchronizing PlacesIndex::City
252
- Imported PlacesIndex::City in \\d+s, stats: index 2
299
+ \\ASynchronizing CitiesIndex
300
+ Imported CitiesIndex in \\d+s, stats: index 2
253
301
  Missing documents: \\["#{cities.last.id}"\\]
254
302
  Outdated documents: \\["#{cities.first.id}"\\]
255
303
  Took \\d+s
@@ -259,12 +307,16 @@ Total: \\d+s\\Z
259
307
 
260
308
  specify do
261
309
  output = StringIO.new
262
- expect { described_class.sync(except: ['places#city'], output: output) }
263
- .not_to update_index(PlacesIndex::City)
310
+ expect { described_class.sync(except: ['cities'], output: output) }
311
+ .not_to update_index(CitiesIndex)
264
312
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
265
- \\ASynchronizing PlacesIndex::Country
266
- PlacesIndex::Country doesn't support outdated synchronization
267
- Skipping PlacesIndex::Country, up to date
313
+ \\ASynchronizing CountriesIndex
314
+ CountriesIndex doesn't support outdated synchronization
315
+ Skipping CountriesIndex, up to date
316
+ Took \\d+s
317
+ Synchronizing UsersIndex
318
+ UsersIndex doesn't support outdated synchronization
319
+ Skipping UsersIndex, up to date
268
320
  Took \\d+s
269
321
  Total: \\d+s\\Z
270
322
  OUTPUT
@@ -290,12 +342,12 @@ Total: \\d+s\\Z
290
342
  specify do
291
343
  output = StringIO.new
292
344
  expect { described_class.journal_apply(time: Time.now, output: output) }
293
- .to update_index(PlacesIndex::City)
345
+ .to update_index(CitiesIndex)
294
346
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
295
347
  \\AApplying journal entries created after [+-:\\d\\s]+
296
- Applying journal to \\[PlacesIndex::City, PlacesIndex::Country\\], 3 entries, stage 1
297
- Imported PlacesIndex::City in \\d+s, stats: index 2
298
- Imported PlacesIndex::Country in \\d+s, stats: index 1
348
+ Applying journal to \\[CitiesIndex, CountriesIndex\\], 3 entries, stage 1
349
+ Imported CitiesIndex in \\d+s, stats: index 2
350
+ Imported CountriesIndex in \\d+s, stats: index 1
299
351
  Total: \\d+s\\Z
300
352
  OUTPUT
301
353
  end
@@ -303,35 +355,35 @@ Total: \\d+s\\Z
303
355
  specify do
304
356
  output = StringIO.new
305
357
  expect { described_class.journal_apply(time: 3.minutes.since, output: output) }
306
- .not_to update_index(PlacesIndex::City)
358
+ .not_to update_index(CitiesIndex)
307
359
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
308
360
  \\AApplying journal entries created after [+-:\\d\\s]+
309
- Applying journal to \\[PlacesIndex::Country\\], 1 entries, stage 1
310
- Imported PlacesIndex::Country in \\d+s, stats: index 1
361
+ Applying journal to \\[CountriesIndex\\], 1 entries, stage 1
362
+ Imported CountriesIndex in \\d+s, stats: index 1
311
363
  Total: \\d+s\\Z
312
364
  OUTPUT
313
365
  end
314
366
 
315
367
  specify do
316
368
  output = StringIO.new
317
- expect { described_class.journal_apply(time: Time.now, only: PlacesIndex::City, output: output) }
318
- .to update_index(PlacesIndex::City)
369
+ expect { described_class.journal_apply(time: Time.now, only: CitiesIndex, output: output) }
370
+ .to update_index(CitiesIndex)
319
371
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
320
372
  \\AApplying journal entries created after [+-:\\d\\s]+
321
- Applying journal to \\[PlacesIndex::City\\], 2 entries, stage 1
322
- Imported PlacesIndex::City in \\d+s, stats: index 2
373
+ Applying journal to \\[CitiesIndex\\], 2 entries, stage 1
374
+ Imported CitiesIndex in \\d+s, stats: index 2
323
375
  Total: \\d+s\\Z
324
376
  OUTPUT
325
377
  end
326
378
 
327
379
  specify do
328
380
  output = StringIO.new
329
- expect { described_class.journal_apply(time: Time.now, except: PlacesIndex::City, output: output) }
330
- .not_to update_index(PlacesIndex::City)
381
+ expect { described_class.journal_apply(time: Time.now, except: CitiesIndex, output: output) }
382
+ .not_to update_index(CitiesIndex)
331
383
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
332
384
  \\AApplying journal entries created after [+-:\\d\\s]+
333
- Applying journal to \\[PlacesIndex::Country\\], 1 entries, stage 1
334
- Imported PlacesIndex::Country in \\d+s, stats: index 1
385
+ Applying journal to \\[CountriesIndex\\], 1 entries, stage 1
386
+ Imported CountriesIndex in \\d+s, stats: index 1
335
387
  Total: \\d+s\\Z
336
388
  OUTPUT
337
389
  end
@@ -362,7 +414,7 @@ Total: \\d+s\\Z
362
414
 
363
415
  specify do
364
416
  output = StringIO.new
365
- described_class.journal_clean(only: PlacesIndex::City, output: output)
417
+ described_class.journal_clean(only: CitiesIndex, output: output)
366
418
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
367
419
  \\ACleaned up 1 journal entries
368
420
  Total: \\d+s\\Z
@@ -371,11 +423,151 @@ Total: \\d+s\\Z
371
423
 
372
424
  specify do
373
425
  output = StringIO.new
374
- described_class.journal_clean(except: PlacesIndex::City, output: output)
426
+ described_class.journal_clean(except: CitiesIndex, output: output)
375
427
  expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
376
428
  \\ACleaned up 1 journal entries
377
429
  Total: \\d+s\\Z
378
430
  OUTPUT
379
431
  end
432
+
433
+ it 'executes asynchronously' do
434
+ output = StringIO.new
435
+ expect(Chewy.client).to receive(:delete_by_query).with(
436
+ {
437
+ body: {query: {match_all: {}}},
438
+ index: ['chewy_journal'],
439
+ refresh: false,
440
+ requests_per_second: 10.0,
441
+ scroll_size: 200,
442
+ wait_for_completion: false
443
+ }
444
+ ).and_call_original
445
+ described_class.journal_clean(
446
+ output: output,
447
+ delete_by_query_options: {
448
+ wait_for_completion: false,
449
+ requests_per_second: 10.0,
450
+ scroll_size: 200
451
+ }
452
+ )
453
+
454
+ expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
455
+ \\ATask to cleanup the journal has been created, [^\\n]*
456
+ Total: \\d+s\\Z
457
+ OUTPUT
458
+ end
459
+ end
460
+
461
+ describe '.reindex' do
462
+ before do
463
+ journal
464
+ CitiesIndex.create!
465
+ CountriesIndex.create!
466
+ end
467
+
468
+ let(:source_index) { 'cities' }
469
+ let(:dest_index) { 'countries' }
470
+
471
+ context 'with correct arguments' do
472
+ specify do
473
+ output = StringIO.new
474
+ described_class.reindex(source: source_index, dest: dest_index, output: output)
475
+ expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
476
+ \\Source index is cities
477
+ \\Destination index is countries
478
+ cities index successfully reindexed with countries index data
479
+ Total: \\d+s\\Z
480
+ OUTPUT
481
+ end
482
+ end
483
+
484
+ context 'with missing indexes' do
485
+ context 'without dest index' do
486
+ specify do
487
+ output = StringIO.new
488
+ expect { described_class.reindex(source: source_index, output: output) }
489
+ .to raise_error ArgumentError
490
+ end
491
+ end
492
+
493
+ context 'without source index' do
494
+ specify do
495
+ output = StringIO.new
496
+ expect { described_class.reindex(dest: dest_index, output: output) }
497
+ .to raise_error ArgumentError
498
+ end
499
+ end
500
+ end
501
+ end
502
+
503
+ describe '.update_mapping' do
504
+ before do
505
+ journal
506
+ CitiesIndex.create!
507
+ end
508
+
509
+ let(:index_name) { CitiesIndex.index_name }
510
+ let(:nonexistent_index) { 'wrong_index' }
511
+
512
+ context 'with existing index' do
513
+ specify do
514
+ output = StringIO.new
515
+ described_class.update_mapping(name: index_name, output: output)
516
+ expect(output.string).to match(Regexp.new(<<-OUTPUT, Regexp::MULTILINE))
517
+ \\Index name is cities
518
+ cities index successfully updated
519
+ Total: \\d+s\\Z
520
+ OUTPUT
521
+ end
522
+ end
523
+
524
+ context 'with non-existent index name' do
525
+ specify do
526
+ output = StringIO.new
527
+ expect { described_class.update_mapping(name: nonexistent_index, output: output) }
528
+ .to raise_error NameError
529
+ end
530
+ end
531
+ end
532
+
533
+ describe '.delete_by_query_options_from_env' do
534
+ subject(:options) { described_class.delete_by_query_options_from_env(env) }
535
+ let(:env) do
536
+ {
537
+ 'WAIT_FOR_COMPLETION' => 'false',
538
+ 'REQUESTS_PER_SECOND' => '10',
539
+ 'SCROLL_SIZE' => '5000'
540
+ }
541
+ end
542
+
543
+ it 'parses the options' do
544
+ expect(options).to eq(
545
+ wait_for_completion: false,
546
+ requests_per_second: 10.0,
547
+ scroll_size: 5000
548
+ )
549
+ end
550
+
551
+ context 'with different boolean values' do
552
+ it 'parses the option correctly' do
553
+ %w[1 t true TRUE on ON].each do |v|
554
+ expect(described_class.delete_by_query_options_from_env({'WAIT_FOR_COMPLETION' => v}))
555
+ .to eq(wait_for_completion: true)
556
+ end
557
+
558
+ %w[0 f false FALSE off OFF].each do |v|
559
+ expect(described_class.delete_by_query_options_from_env({'WAIT_FOR_COMPLETION' => v}))
560
+ .to eq(wait_for_completion: false)
561
+ end
562
+ end
563
+ end
564
+
565
+ context 'with other env' do
566
+ let(:env) { {'SOME_ENV' => '123', 'REQUESTS_PER_SECOND' => '15'} }
567
+
568
+ it 'parses only the options' do
569
+ expect(options).to eq(requests_per_second: 15.0)
570
+ end
571
+ end
380
572
  end
381
573
  end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe :build_query do
4
+ before do
5
+ stub_model(:city)
6
+ stub_index(:cities) { index_scope City }
7
+ CitiesIndex.create
8
+ end
9
+
10
+ let(:expected_query) do
11
+ {
12
+ index: ['cities'],
13
+ body: {
14
+ query: {
15
+ match: {name: 'name'}
16
+ }
17
+ }
18
+ }
19
+ end
20
+ let(:dummy_query) { {match: {name: 'name'}} }
21
+ let(:unexpected_query) { {match: {name: 'name'}} }
22
+
23
+ context 'build expected query' do
24
+ specify do
25
+ expect(CitiesIndex.query(dummy_query)).to build_query(expected_query)
26
+ end
27
+ end
28
+
29
+ context 'not to build unexpected query' do
30
+ specify do
31
+ expect(CitiesIndex.query(dummy_query)).not_to build_query(unexpected_query)
32
+ end
33
+ end
34
+ end