chewy 0.10.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +240 -0
  3. data/.rubocop.yml +25 -25
  4. data/Appraisals +12 -10
  5. data/CHANGELOG.md +252 -263
  6. data/Gemfile +5 -1
  7. data/LICENSE.txt +1 -1
  8. data/README.md +142 -78
  9. data/chewy.gemspec +10 -12
  10. data/gemfiles/{rails.4.2.mongoid.5.1.gemfile → rails.5.2.activerecord.gemfile} +6 -4
  11. data/gemfiles/{rails.4.2.activerecord.gemfile → rails.5.2.mongoid.6.4.gemfile} +6 -4
  12. data/gemfiles/{rails.4.0.activerecord.gemfile → rails.6.0.activerecord.gemfile} +6 -3
  13. data/gemfiles/rails.6.1.activerecord.gemfile +19 -0
  14. data/gemfiles/sequel.4.45.gemfile +2 -2
  15. data/lib/chewy.rb +2 -1
  16. data/lib/chewy/backports/duplicable.rb +1 -1
  17. data/lib/chewy/config.rb +10 -39
  18. data/lib/chewy/fields/base.rb +40 -28
  19. data/lib/chewy/fields/root.rb +18 -11
  20. data/lib/chewy/index.rb +3 -1
  21. data/lib/chewy/index/actions.rb +27 -15
  22. data/lib/chewy/index/settings.rb +2 -0
  23. data/lib/chewy/index/specification.rb +12 -10
  24. data/lib/chewy/minitest/helpers.rb +6 -6
  25. data/lib/chewy/minitest/search_index_receiver.rb +17 -17
  26. data/lib/chewy/multi_search.rb +62 -0
  27. data/lib/chewy/railtie.rb +4 -4
  28. data/lib/chewy/rake_helper.rb +5 -5
  29. data/lib/chewy/rspec/update_index.rb +3 -5
  30. data/lib/chewy/search.rb +4 -11
  31. data/lib/chewy/search/loader.rb +1 -1
  32. data/lib/chewy/search/pagination/will_paginate.rb +4 -2
  33. data/lib/chewy/search/parameters.rb +24 -6
  34. data/lib/chewy/search/parameters/allow_partial_search_results.rb +27 -0
  35. data/lib/chewy/search/parameters/concerns/query_storage.rb +4 -3
  36. data/lib/chewy/search/parameters/indices.rb +123 -0
  37. data/lib/chewy/search/parameters/none.rb +1 -3
  38. data/lib/chewy/search/request.rb +100 -74
  39. data/lib/chewy/search/scrolling.rb +7 -6
  40. data/lib/chewy/stash.rb +30 -21
  41. data/lib/chewy/strategy/active_job.rb +1 -1
  42. data/lib/chewy/strategy/atomic.rb +1 -1
  43. data/lib/chewy/strategy/sidekiq.rb +1 -1
  44. data/lib/chewy/type.rb +5 -2
  45. data/lib/chewy/type/adapter/active_record.rb +1 -1
  46. data/lib/chewy/type/adapter/base.rb +9 -9
  47. data/lib/chewy/type/adapter/mongoid.rb +2 -4
  48. data/lib/chewy/type/adapter/orm.rb +7 -4
  49. data/lib/chewy/type/adapter/sequel.rb +5 -7
  50. data/lib/chewy/type/crutch.rb +1 -1
  51. data/lib/chewy/type/import.rb +13 -11
  52. data/lib/chewy/type/import/bulk_builder.rb +1 -1
  53. data/lib/chewy/type/import/bulk_request.rb +4 -2
  54. data/lib/chewy/type/import/journal_builder.rb +3 -3
  55. data/lib/chewy/type/import/routine.rb +3 -3
  56. data/lib/chewy/type/mapping.rb +42 -36
  57. data/lib/chewy/type/observe.rb +16 -12
  58. data/lib/chewy/type/syncer.rb +15 -14
  59. data/lib/chewy/type/witchcraft.rb +11 -7
  60. data/lib/chewy/type/wrapper.rb +14 -4
  61. data/lib/chewy/version.rb +1 -1
  62. data/lib/sequel/plugins/chewy_observe.rb +4 -19
  63. data/migration_guide.md +18 -0
  64. data/spec/chewy/config_spec.rb +16 -21
  65. data/spec/chewy/fields/base_spec.rb +70 -70
  66. data/spec/chewy/fields/root_spec.rb +56 -9
  67. data/spec/chewy/index/actions_spec.rb +63 -7
  68. data/spec/chewy/index/specification_spec.rb +25 -16
  69. data/spec/chewy/index_spec.rb +75 -45
  70. data/spec/chewy/journal_spec.rb +33 -29
  71. data/spec/chewy/minitest/search_index_receiver_spec.rb +11 -9
  72. data/spec/chewy/multi_search_spec.rb +85 -0
  73. data/spec/chewy/rake_helper_spec.rb +123 -95
  74. data/spec/chewy/rspec/update_index_spec.rb +47 -46
  75. data/spec/chewy/runtime_spec.rb +2 -2
  76. data/spec/chewy/search/pagination/kaminari_spec.rb +7 -3
  77. data/spec/chewy/search/pagination/will_paginate_spec.rb +9 -3
  78. data/spec/chewy/search/parameters/indices_spec.rb +190 -0
  79. data/spec/chewy/search/parameters/none_spec.rb +1 -1
  80. data/spec/chewy/search/parameters_spec.rb +21 -4
  81. data/spec/chewy/search/request_spec.rb +101 -70
  82. data/spec/chewy/search/response_spec.rb +27 -17
  83. data/spec/chewy/search/scrolling_spec.rb +25 -16
  84. data/spec/chewy/search_spec.rb +49 -35
  85. data/spec/chewy/stash_spec.rb +15 -13
  86. data/spec/chewy/strategy/active_job_spec.rb +15 -2
  87. data/spec/chewy/strategy/shoryuken_spec.rb +8 -2
  88. data/spec/chewy/strategy/sidekiq_spec.rb +6 -2
  89. data/spec/chewy/type/adapter/active_record_spec.rb +16 -4
  90. data/spec/chewy/type/import/bulk_builder_spec.rb +9 -94
  91. data/spec/chewy/type/import/journal_builder_spec.rb +17 -15
  92. data/spec/chewy/type/import_spec.rb +6 -0
  93. data/spec/chewy/type/mapping_spec.rb +51 -18
  94. data/spec/chewy/type/observe_spec.rb +4 -4
  95. data/spec/chewy/type/witchcraft_spec.rb +31 -0
  96. data/spec/chewy/type/wrapper_spec.rb +3 -1
  97. data/spec/chewy_spec.rb +0 -7
  98. data/spec/spec_helper.rb +5 -1
  99. data/spec/support/active_record.rb +20 -0
  100. metadata +46 -116
  101. data/.travis.yml +0 -53
  102. data/LEGACY_DSL.md +0 -497
  103. data/gemfiles/rails.4.1.activerecord.gemfile +0 -14
  104. data/gemfiles/rails.5.0.activerecord.gemfile +0 -15
  105. data/gemfiles/rails.5.0.mongoid.6.0.gemfile +0 -15
  106. data/gemfiles/rails.5.1.activerecord.gemfile +0 -15
  107. data/gemfiles/rails.5.1.mongoid.6.1.gemfile +0 -15
  108. data/lib/chewy/query.rb +0 -1098
  109. data/lib/chewy/query/compose.rb +0 -68
  110. data/lib/chewy/query/criteria.rb +0 -191
  111. data/lib/chewy/query/filters.rb +0 -227
  112. data/lib/chewy/query/loading.rb +0 -111
  113. data/lib/chewy/query/nodes/and.rb +0 -25
  114. data/lib/chewy/query/nodes/base.rb +0 -17
  115. data/lib/chewy/query/nodes/bool.rb +0 -34
  116. data/lib/chewy/query/nodes/equal.rb +0 -34
  117. data/lib/chewy/query/nodes/exists.rb +0 -20
  118. data/lib/chewy/query/nodes/expr.rb +0 -28
  119. data/lib/chewy/query/nodes/field.rb +0 -110
  120. data/lib/chewy/query/nodes/has_child.rb +0 -15
  121. data/lib/chewy/query/nodes/has_parent.rb +0 -15
  122. data/lib/chewy/query/nodes/has_relation.rb +0 -59
  123. data/lib/chewy/query/nodes/match_all.rb +0 -11
  124. data/lib/chewy/query/nodes/missing.rb +0 -20
  125. data/lib/chewy/query/nodes/not.rb +0 -25
  126. data/lib/chewy/query/nodes/or.rb +0 -25
  127. data/lib/chewy/query/nodes/prefix.rb +0 -19
  128. data/lib/chewy/query/nodes/query.rb +0 -20
  129. data/lib/chewy/query/nodes/range.rb +0 -63
  130. data/lib/chewy/query/nodes/raw.rb +0 -15
  131. data/lib/chewy/query/nodes/regexp.rb +0 -35
  132. data/lib/chewy/query/nodes/script.rb +0 -20
  133. data/lib/chewy/query/pagination.rb +0 -25
  134. data/spec/chewy/query/criteria_spec.rb +0 -700
  135. data/spec/chewy/query/filters_spec.rb +0 -201
  136. data/spec/chewy/query/loading_spec.rb +0 -124
  137. data/spec/chewy/query/nodes/and_spec.rb +0 -12
  138. data/spec/chewy/query/nodes/bool_spec.rb +0 -14
  139. data/spec/chewy/query/nodes/equal_spec.rb +0 -32
  140. data/spec/chewy/query/nodes/exists_spec.rb +0 -18
  141. data/spec/chewy/query/nodes/has_child_spec.rb +0 -59
  142. data/spec/chewy/query/nodes/has_parent_spec.rb +0 -59
  143. data/spec/chewy/query/nodes/match_all_spec.rb +0 -11
  144. data/spec/chewy/query/nodes/missing_spec.rb +0 -16
  145. data/spec/chewy/query/nodes/not_spec.rb +0 -13
  146. data/spec/chewy/query/nodes/or_spec.rb +0 -12
  147. data/spec/chewy/query/nodes/prefix_spec.rb +0 -16
  148. data/spec/chewy/query/nodes/query_spec.rb +0 -12
  149. data/spec/chewy/query/nodes/range_spec.rb +0 -32
  150. data/spec/chewy/query/nodes/raw_spec.rb +0 -11
  151. data/spec/chewy/query/nodes/regexp_spec.rb +0 -43
  152. data/spec/chewy/query/nodes/script_spec.rb +0 -15
  153. data/spec/chewy/query/pagination/kaminari_spec.rb +0 -5
  154. data/spec/chewy/query/pagination/will_paginate_spec.rb +0 -5
  155. data/spec/chewy/query/pagination_spec.rb +0 -39
  156. data/spec/chewy/query_spec.rb +0 -636
  157. data/spec/chewy/search/parameters/indices_boost_spec.rb +0 -83
data/lib/chewy/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Chewy
2
- VERSION = '0.10.0'.freeze
2
+ VERSION = '6.0.0'.freeze
3
3
  end
@@ -36,40 +36,25 @@ module Sequel
36
36
  callback_options = ChewyObserve.extract_callback_options!(args)
37
37
  update_proc = ChewyObserve.update_proc(type_name, *args, &block)
38
38
 
39
- if Chewy.use_after_commit_callbacks
40
- set_callback(:commit, callback_options, &update_proc)
41
- set_callback(:destroy_commit, callback_options, &update_proc)
42
- else
43
- set_callback(:save, callback_options, &update_proc)
44
- set_callback(:destroy, callback_options, &update_proc)
45
- end
39
+ set_callback(:save, callback_options, &update_proc)
40
+ set_callback(:destroy, callback_options, &update_proc)
46
41
  end
47
42
  end
48
43
 
49
44
  # Instance level methods for Sequel::Model
50
45
  #
51
46
  module InstanceMethods
52
- def after_commit
53
- run_callbacks(:commit) do
54
- super
55
- end
56
- end
57
-
58
- def after_destroy_commit
59
- run_callbacks(:destroy_commit) do
60
- super
61
- end
62
- end
63
-
64
47
  def after_save
65
48
  run_callbacks(:save) do
66
49
  super
50
+ db.after_commit {} if Chewy.use_after_commit_callbacks
67
51
  end
68
52
  end
69
53
 
70
54
  def after_destroy
71
55
  run_callbacks(:destroy) do
72
56
  super
57
+ db.after_commit {} if Chewy.use_after_commit_callbacks
73
58
  end
74
59
  end
75
60
  end
@@ -0,0 +1,18 @@
1
+ # Migration guide
2
+
3
+ ## Chewy 5 / ES 5 to Chewy 6 / ES 6
4
+
5
+ In order to upgrade chewy5/ES5 to chewy6/ES6 in the most seamless manner you have to:
6
+ * Upgrade to the latest 5.x stable releases: Chewy 5.2, ES 5.6
7
+ * [Migrate any multi-typed indexes into single-typed](https://www.elastic.co/guide/en/elasticsearch/reference/6.8/removal-of-types.html)
8
+ * Using [multi-index queries](https://github.com/toptal/chewy/pull/657) could be helpful
9
+ * Parent/Child [relationship is deprecated](https://www.elastic.co/guide/en/elasticsearch/reference/6.8/removal-of-types.html#parent-child-mapping-types) in favor of the [join field](https://www.elastic.co/guide/en/elasticsearch/reference/6.8/parent-join.html)
10
+ * Handle deprecation of `string` type & `not_analyzed` value for the `index` mapping parameter:
11
+ * replace fields with `{ type: 'string', index: 'not_analyzed'}` by `{type: 'keyword'}`
12
+ * replace fields with `{ type: 'string', index: 'analyzed'}` by `{type: 'text'}`
13
+ * `PathHierarchy` tokenizer' param `delimiter` now accepts only one argument, [others should be replaced by character filter ](https://discuss.elastic.co/t/multichar-delimiter-in-path-hierarchy-tokenizer/16203)
14
+ * Make sure you don't use any other of the [deprecated ES5 features](https://www.elastic.co/guide/en/elasticsearch/reference/6.8/breaking-changes-6.0.html)
15
+ * Run your test suite on ES6
16
+ * Run manual tests on ES6
17
+ * Perform a [rolling upgrade](https://www.elastic.co/guide/en/elasticsearch/reference/6.8/rolling-upgrades.html) of Elasticsearch
18
+ * Upgrade to Chewy 6
@@ -6,9 +6,6 @@ describe Chewy::Config do
6
6
  its(:logger) { should be_nil }
7
7
  its(:transport_logger) { should be_nil }
8
8
  its(:transport_logger) { should be_nil }
9
- its(:query_mode) { should == :must }
10
- its(:filter_mode) { should == :and }
11
- its(:post_filter_mode) { should be_nil }
12
9
  its(:root_strategy) { should == :base }
13
10
  its(:request_strategy) { should == :atomic }
14
11
  its(:use_after_commit_callbacks) { should == true }
@@ -54,24 +51,6 @@ describe Chewy::Config do
54
51
  end
55
52
  end
56
53
 
57
- describe '#search_class=' do
58
- specify do
59
- expect { subject.search_class = Chewy::Query }
60
- .to change { subject.search_class }
61
- .from(be < Chewy::Search::Request)
62
- .to(be < Chewy::Query)
63
- end
64
-
65
- context do
66
- before { hide_const('Kaminari') }
67
-
68
- specify do
69
- expect(subject.search_class.included_modules)
70
- .to include(Chewy::Search::Pagination::WillPaginate)
71
- end
72
- end
73
- end
74
-
75
54
  describe '#search_class' do
76
55
  context 'nothing is defined' do
77
56
  before do
@@ -137,5 +116,21 @@ describe Chewy::Config do
137
116
  specify do
138
117
  expect(subject.configuration).to include(indices_path: 'app/custom_indices_path')
139
118
  end
119
+
120
+ context 'when Rails::VERSION constant is defined' do
121
+ it 'looks for configuration in "config/chewy.yml"' do
122
+ module Rails
123
+ VERSION = '5.1.1'.freeze
124
+
125
+ def self.root
126
+ Pathname.new(__dir__)
127
+ end
128
+ end
129
+
130
+ expect(File).to receive(:exist?)
131
+ .with(Pathname.new(__dir__).join('config', 'chewy.yml'))
132
+ subject.configuration
133
+ end
134
+ end
140
135
  end
141
136
  end
@@ -10,6 +10,8 @@ describe Chewy::Fields::Base do
10
10
  specify { expect(field.compose(double(value: 'hello'))).to eq(name: 'hello') }
11
11
  specify { expect(field.compose(double(value: %w[hello world]))).to eq(name: %w[hello world]) }
12
12
 
13
+ specify { expect(described_class.new(:name, value: :last_name).compose(double(last_name: 'hello'))).to eq(name: 'hello') }
14
+ specify { expect(described_class.new(:name, value: :last_name).compose('last_name' => 'hello')).to eq(name: 'hello') }
13
15
  specify { expect(described_class.new(:name).compose(double(name: 'hello'))).to eq(name: 'hello') }
14
16
  specify { expect(described_class.new(:false_value).compose(false_value: false)).to eq(false_value: false) }
15
17
  specify { expect(described_class.new(:true_value).compose(true_value: true)).to eq(true_value: true) }
@@ -61,7 +63,7 @@ describe Chewy::Fields::Base do
61
63
  end
62
64
 
63
65
  context 'implicit values' do
64
- let(:field) { described_class.new(:name, type: 'string') }
66
+ let(:field) { described_class.new(:name, type: 'integer') }
65
67
  before do
66
68
  field.children.push(described_class.new(:name))
67
69
  field.children.push(described_class.new(:untouched))
@@ -85,8 +87,8 @@ describe Chewy::Fields::Base do
85
87
 
86
88
  describe '#mappings_hash' do
87
89
  let(:field) { described_class.new(:name, type: :object) }
88
- let(:fields1) { Array.new(2) { |i| described_class.new("name#{i + 1}", type: "string#{i + 1}") } }
89
- let(:fields2) { Array.new(2) { |i| described_class.new("name#{i + 3}", type: "string#{i + 3}") } }
90
+ let(:fields1) { Array.new(2) { |i| described_class.new("name#{i + 1}", type: "integer#{i + 1}") } }
91
+ let(:fields2) { Array.new(2) { |i| described_class.new("name#{i + 3}", type: "integer#{i + 3}") } }
90
92
  before do
91
93
  fields1.each { |m| field.children.push(m) }
92
94
  fields2.each { |m| fields1[0].children.push(m) }
@@ -94,28 +96,30 @@ describe Chewy::Fields::Base do
94
96
 
95
97
  specify do
96
98
  expect(field.mappings_hash).to eq(name: {type: :object, properties: {
97
- name1: {type: 'string1', fields: {
98
- name3: {type: 'string3'}, name4: {type: 'string4'}
99
- }}, name2: {type: 'string2'}
99
+ name1: {type: 'integer1', fields: {
100
+ name3: {type: 'integer3'}, name4: {type: 'integer4'}
101
+ }}, name2: {type: 'integer2'}
100
102
  }})
101
103
  end
102
104
 
103
105
  context do
104
- let(:field) { described_class.new(:name, type: :string) }
105
- let(:fields1) { Array.new(2) { |i| described_class.new("name#{i + 1}") } }
106
+ let(:field) { described_class.new(:name, type: :integer) }
107
+ let(:fields1) do
108
+ [described_class.new(:name1), described_class.new(:name2, type: 'integer')]
109
+ end
106
110
 
107
111
  specify do
108
- expect(field.mappings_hash).to eq(name: {type: :string, fields: {
112
+ expect(field.mappings_hash).to eq(name: {type: :integer, fields: {
109
113
  name1: {type: 'object', properties: {
110
- name3: {type: 'string3'}, name4: {type: 'string4'}
111
- }}, name2: {type: 'string'}
114
+ name3: {type: 'integer3'}, name4: {type: 'integer4'}
115
+ }}, name2: {type: 'integer'}
112
116
  }})
113
117
  end
114
118
  end
115
119
  end
116
120
 
117
121
  context 'integration' do
118
- context 'objects, hashes and arrays' do
122
+ context 'default field type' do
119
123
  before do
120
124
  stub_index(:events) do
121
125
  define_type :event do
@@ -124,26 +128,33 @@ describe Chewy::Fields::Base do
124
128
  field :id
125
129
  field :licenses do
126
130
  field :id
127
- field :name
131
+ field :created_at, type: 'time'
128
132
  end
129
133
  end
130
134
  end
131
135
  end
132
136
  end
133
137
 
138
+ around do |example|
139
+ previous_type = Chewy.default_field_type
140
+ Chewy.default_field_type = 'integer'
141
+ example.run
142
+ Chewy.default_field_type = previous_type
143
+ end
144
+
134
145
  specify do
135
146
  expect(EventsIndex::Event.mappings_hash).to eq(event: {
136
147
  properties: {
137
- id: {type: 'string'},
148
+ id: {type: 'integer'},
138
149
  category: {
139
150
  type: 'object',
140
151
  properties: {
141
- id: {type: 'string'},
152
+ id: {type: 'integer'},
142
153
  licenses: {
143
154
  type: 'object',
144
155
  properties: {
145
- id: {type: 'string'},
146
- name: {type: 'string'}
156
+ id: {type: 'integer'},
157
+ created_at: {type: 'time'}
147
158
  }
148
159
  }
149
160
  }
@@ -151,83 +162,72 @@ describe Chewy::Fields::Base do
151
162
  }
152
163
  })
153
164
  end
165
+ end
154
166
 
155
- context 'default field type' do
156
- around do |example|
157
- previous_type = Chewy.default_field_type
158
- Chewy.default_field_type = 'text'
159
- example.run
160
- Chewy.default_field_type = previous_type
161
- end
162
-
163
- specify do
164
- expect(EventsIndex::Event.mappings_hash).to eq(event: {
165
- properties: {
166
- id: {type: 'text'},
167
- category: {
168
- type: 'object',
169
- properties: {
170
- id: {type: 'text'},
171
- licenses: {
172
- type: 'object',
173
- properties: {
174
- id: {type: 'text'},
175
- name: {type: 'text'}
176
- }
177
- }
178
- }
179
- }
180
- }
181
- })
167
+ context 'objects, hashes and arrays' do
168
+ before do
169
+ stub_index(:events) do
170
+ define_type :event do
171
+ field :id
172
+ field :category do
173
+ field :id
174
+ field :licenses do
175
+ field :id
176
+ field :name
177
+ end
178
+ end
179
+ end
182
180
  end
183
181
  end
184
182
 
183
+ # rubocop:disable Style/BracesAroundHashParameters
185
184
  specify do
186
- expect(EventsIndex::Event.root_object.compose(
187
- id: 1, category: {id: 2, licenses: {id: 3, name: 'Name'}}
188
- )).to eq('id' => 1, 'category' => {'id' => 2, 'licenses' => {'id' => 3, 'name' => 'Name'}})
185
+ expect(EventsIndex::Event.root.compose({
186
+ id: 1, category: {id: 2, licenses: {id: 3, name: 'Name'}}
187
+ })).to eq('id' => 1, 'category' => {'id' => 2, 'licenses' => {'id' => 3, 'name' => 'Name'}})
189
188
  end
190
189
 
191
190
  specify do
192
- expect(EventsIndex::Event.root_object.compose(id: 1, category: [
191
+ expect(EventsIndex::Event.root.compose({id: 1, category: [
193
192
  {id: 2, 'licenses' => {id: 3, name: 'Name1'}},
194
193
  {id: 4, licenses: nil}
195
- ])).to eq('id' => 1, 'category' => [
194
+ ]})).to eq('id' => 1, 'category' => [
196
195
  {'id' => 2, 'licenses' => {'id' => 3, 'name' => 'Name1'}},
197
196
  {'id' => 4, 'licenses' => nil.as_json}
198
197
  ])
199
198
  end
200
199
 
201
200
  specify do
202
- expect(EventsIndex::Event.root_object.compose('id' => 1, category: {id: 2, licenses: [
201
+ expect(EventsIndex::Event.root.compose({'id' => 1, category: {id: 2, licenses: [
203
202
  {id: 3, name: 'Name1'}, {id: 4, name: 'Name2'}
204
- ]})).to eq('id' => 1, 'category' => {'id' => 2, 'licenses' => [
203
+ ]}})).to eq('id' => 1, 'category' => {'id' => 2, 'licenses' => [
205
204
  {'id' => 3, 'name' => 'Name1'}, {'id' => 4, 'name' => 'Name2'}
206
205
  ]})
207
206
  end
208
207
 
209
208
  specify do
210
- expect(EventsIndex::Event.root_object.compose(id: 1, category: [
209
+ expect(EventsIndex::Event.root.compose({id: 1, category: [
211
210
  {id: 2, licenses: [
212
211
  {id: 3, 'name' => 'Name1'}, {id: 4, name: 'Name2'}
213
212
  ]},
214
213
  {id: 5, licenses: []}
215
- ])).to eq('id' => 1, 'category' => [
214
+ ]})).to eq('id' => 1, 'category' => [
216
215
  {'id' => 2, 'licenses' => [
217
216
  {'id' => 3, 'name' => 'Name1'}, {'id' => 4, 'name' => 'Name2'}
218
217
  ]},
219
218
  {'id' => 5, 'licenses' => []}
220
219
  ])
221
220
  end
221
+ # rubocop:enable Style/BracesAroundHashParameters
222
222
 
223
223
  specify do
224
- expect(EventsIndex::Event.root_object.compose(
224
+ expect(EventsIndex::Event.root.compose(
225
225
  double(id: 1, category: double(id: 2, licenses: double(id: 3, name: 'Name')))
226
226
  )).to eq('id' => 1, 'category' => {'id' => 2, 'licenses' => {'id' => 3, 'name' => 'Name'}})
227
227
  end
228
228
 
229
229
  specify do
230
- expect(EventsIndex::Event.root_object.compose(double(id: 1, category: [
230
+ expect(EventsIndex::Event.root.compose(double(id: 1, category: [
231
231
  double(id: 2, licenses: double(id: 3, name: 'Name1')),
232
232
  double(id: 4, licenses: nil)
233
233
  ]))).to eq('id' => 1, 'category' => [
@@ -237,7 +237,7 @@ describe Chewy::Fields::Base do
237
237
  end
238
238
 
239
239
  specify do
240
- expect(EventsIndex::Event.root_object.compose(double(id: 1, category: double(id: 2, licenses: [
240
+ expect(EventsIndex::Event.root.compose(double(id: 1, category: double(id: 2, licenses: [
241
241
  double(id: 3, name: 'Name1'), double(id: 4, name: 'Name2')
242
242
  ])))).to eq('id' => 1, 'category' => {'id' => 2, 'licenses' => [
243
243
  {'id' => 3, 'name' => 'Name1'}, {'id' => 4, 'name' => 'Name2'}
@@ -245,7 +245,7 @@ describe Chewy::Fields::Base do
245
245
  end
246
246
 
247
247
  specify do
248
- expect(EventsIndex::Event.root_object.compose(double(id: 1, category: [
248
+ expect(EventsIndex::Event.root.compose(double(id: 1, category: [
249
249
  double(id: 2, licenses: [
250
250
  double(id: 3, name: 'Name1'), double(id: 4, name: 'Name2')
251
251
  ]),
@@ -263,11 +263,11 @@ describe Chewy::Fields::Base do
263
263
  before do
264
264
  stub_index(:events) do
265
265
  define_type :event do
266
- field :id
266
+ field :id, type: 'integer'
267
267
  field :category, value: -> { categories } do
268
- field :id
268
+ field :id, type: 'integer'
269
269
  field :licenses, value: -> { license } do
270
- field :id
270
+ field :id, type: 'integer'
271
271
  field :name
272
272
  end
273
273
  end
@@ -276,7 +276,7 @@ describe Chewy::Fields::Base do
276
276
  end
277
277
 
278
278
  specify do
279
- expect(EventsIndex::Event.root_object.compose(
279
+ expect(EventsIndex::Event.root.compose(
280
280
  double(id: 1, categories: double(id: 2, license: double(id: 3, name: 'Name')))
281
281
  )).to eq('id' => 1, 'category' => {'id' => 2, 'licenses' => {'id' => 3, 'name' => 'Name'}})
282
282
  end
@@ -286,8 +286,8 @@ describe Chewy::Fields::Base do
286
286
  before do
287
287
  stub_index(:events) do
288
288
  define_type :event do
289
- field :id
290
- field :name, type: 'string' do
289
+ field :id, type: 'integer'
290
+ field :name, type: 'integer' do
291
291
  field :raw, analyzer: 'my_own'
292
292
  end
293
293
  field :category, type: 'object'
@@ -298,11 +298,11 @@ describe Chewy::Fields::Base do
298
298
  specify do
299
299
  expect(EventsIndex::Event.mappings_hash).to eq(event: {
300
300
  properties: {
301
- id: {type: 'string'},
301
+ id: {type: 'integer'},
302
302
  name: {
303
- type: 'string',
303
+ type: 'integer',
304
304
  fields: {
305
- raw: {analyzer: 'my_own', type: 'string'}
305
+ raw: {analyzer: 'my_own', type: Chewy.default_field_type}
306
306
  }
307
307
  },
308
308
  category: {type: 'object'}
@@ -311,7 +311,7 @@ describe Chewy::Fields::Base do
311
311
  end
312
312
 
313
313
  specify do
314
- expect(EventsIndex::Event.root_object.compose(
314
+ expect(EventsIndex::Event.root.compose(
315
315
  double(id: 1, name: 'Jonny', category: double(id: 2, as_json: {'name' => 'Borogoves'}))
316
316
  )).to eq(
317
317
  'id' => 1,
@@ -321,7 +321,7 @@ describe Chewy::Fields::Base do
321
321
  end
322
322
 
323
323
  specify do
324
- expect(EventsIndex::Event.root_object.compose(
324
+ expect(EventsIndex::Event.root.compose(
325
325
  double(id: 1, name: 'Jonny', category: [
326
326
  double(id: 2, as_json: {'name' => 'Borogoves1'}),
327
327
  double(id: 3, as_json: {'name' => 'Borogoves2'})
@@ -386,7 +386,7 @@ describe Chewy::Fields::Base do
386
386
  end
387
387
 
388
388
  specify do
389
- expect(CountriesIndex::Country.root_object.compose(country_with_cities)).to eq('id' => 1, 'cities' => [
389
+ expect(CountriesIndex::Country.root.compose(country_with_cities)).to eq('id' => 1, 'cities' => [
390
390
  {'id' => 1, 'name' => 'City1'}, {'id' => 2, 'name' => 'City2'}
391
391
  ])
392
392
  end
@@ -405,7 +405,7 @@ describe Chewy::Fields::Base do
405
405
  end
406
406
 
407
407
  specify do
408
- expect(CitiesIndex::City.root_object.compose(
408
+ expect(CitiesIndex::City.root.compose(
409
409
  City.create!(id: 1, country: Country.create!(id: 1, name: 'Country'))
410
410
  )).to eq('id' => 1, 'country' => {'id' => 1, 'name' => 'Country'})
411
411
  end
@@ -5,7 +5,7 @@ describe Chewy::Fields::Root do
5
5
 
6
6
  describe '#dynamic_template' do
7
7
  specify do
8
- field.dynamic_template 'hello', type: 'string'
8
+ field.dynamic_template 'hello', type: 'keyword'
9
9
  field.dynamic_template 'hello*', :integer
10
10
  field.dynamic_template 'hello.*'
11
11
  field.dynamic_template(/hello/)
@@ -14,7 +14,7 @@ describe Chewy::Fields::Root do
14
14
  field.dynamic_template(/hello\..*/)
15
15
 
16
16
  expect(field.mappings_hash).to eq(product: {dynamic_templates: [
17
- {template_1: {mapping: {type: 'string'}, match: 'hello'}},
17
+ {template_1: {mapping: {type: 'keyword'}, match: 'hello'}},
18
18
  {template_2: {mapping: {}, match_mapping_type: 'integer', match: 'hello*'}},
19
19
  {template_3: {mapping: {}, path_match: 'hello.*'}},
20
20
  {template_4: {mapping: {}, match: 'hello', match_pattern: 'regexp'}},
@@ -32,10 +32,10 @@ describe Chewy::Fields::Root do
32
32
  end
33
33
 
34
34
  specify do
35
- field.dynamic_template 'hello', type: 'string'
35
+ field.dynamic_template 'hello', type: 'keyword'
36
36
  expect(field.mappings_hash).to eq(product: {dynamic_templates: [
37
37
  {template_42: {mapping: {}, match: ''}},
38
- {template_1: {mapping: {type: 'string'}, match: 'hello'}}
38
+ {template_1: {mapping: {type: 'keyword'}, match: 'hello'}}
39
39
  ]})
40
40
  end
41
41
  end
@@ -53,11 +53,11 @@ describe Chewy::Fields::Root do
53
53
  let(:city) { City.new(name: 'London', rating: 100) }
54
54
 
55
55
  specify do
56
- expect(PlacesIndex::City.send(:build_root).compose(city))
56
+ expect(PlacesIndex::City.root.compose(city))
57
57
  .to match(hash_including('name' => 'London', 'rating' => 100))
58
58
  end
59
59
  specify do
60
- expect(PlacesIndex::City.send(:build_root).compose(city, fields: %i[name borogoves]))
60
+ expect(PlacesIndex::City.root.compose(city, fields: %i[name borogoves]))
61
61
  .to eq('name' => 'London')
62
62
  end
63
63
  end
@@ -74,14 +74,61 @@ describe Chewy::Fields::Root do
74
74
  let(:city) { double(name: 'London', rating: 100) }
75
75
 
76
76
  specify do
77
- expect(PlacesIndex::City.send(:build_root).compose(city))
77
+ expect(PlacesIndex::City.root.compose(city))
78
78
  .to eq('name' => 'London', 'rating' => 100)
79
79
  end
80
80
  specify do
81
- expect(PlacesIndex::City.send(:build_root).compose(city, fields: %i[name borogoves]))
81
+ expect(PlacesIndex::City.root.compose(city, fields: %i[name borogoves]))
82
82
  .to eq('name' => 'London')
83
83
  end
84
84
  end
85
+
86
+ context 'root value provided' do
87
+ before do
88
+ stub_index(:places) do
89
+ define_type :city do
90
+ root value: ->(o) { {name: o.name + 'Modified', rating: o.rating.next} }
91
+ end
92
+ end
93
+ end
94
+
95
+ let(:city) { double(name: 'London', rating: 100) }
96
+
97
+ specify do
98
+ expect(PlacesIndex::City.root.compose(city))
99
+ .to eq('name' => 'LondonModified', 'rating' => 101)
100
+ end
101
+
102
+ specify do
103
+ expect(PlacesIndex::City.root.compose(city, fields: %i[name borogoves]))
104
+ .to eq('name' => 'LondonModified')
105
+ end
106
+ end
107
+
108
+ context 'complex evaluations' do
109
+ before do
110
+ stub_index(:places) do
111
+ define_type :city do
112
+ root value: ->(o) { {name: o.name + 'Modified', rating: o.rating.next} } do
113
+ field :name, value: ->(o) { o[:name] + 'Modified' }
114
+ field :rating
115
+ end
116
+ end
117
+ end
118
+ end
119
+
120
+ let(:city) { double(name: 'London', rating: 100) }
121
+
122
+ specify do
123
+ expect(PlacesIndex::City.root.compose(city))
124
+ .to eq('name' => 'LondonModifiedModified', 'rating' => 101)
125
+ end
126
+
127
+ specify do
128
+ expect(PlacesIndex::City.root.compose(city, fields: %i[name borogoves]))
129
+ .to eq('name' => 'LondonModifiedModified')
130
+ end
131
+ end
85
132
  end
86
133
 
87
134
  describe '#child_hash' do
@@ -94,7 +141,7 @@ describe Chewy::Fields::Root do
94
141
  end
95
142
 
96
143
  specify do
97
- expect(PlacesIndex::City.send(:build_root).child_hash).to match(
144
+ expect(PlacesIndex::City.root.child_hash).to match(
98
145
  name: an_instance_of(Chewy::Fields::Base).and(have_attributes(name: :name)),
99
146
  rating: an_instance_of(Chewy::Fields::Base).and(have_attributes(name: :rating))
100
147
  )