chewy 0.10.1 → 7.3.2

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