chewy 0.8.4 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +34 -0
  3. data/.rubocop_todo.yml +44 -0
  4. data/.travis.yml +20 -60
  5. data/Appraisals +15 -40
  6. data/CHANGELOG.md +42 -0
  7. data/Gemfile +1 -0
  8. data/Guardfile +5 -5
  9. data/README.md +155 -6
  10. data/Rakefile +11 -1
  11. data/chewy.gemspec +5 -7
  12. data/gemfiles/rails.3.2.activerecord.gemfile +1 -0
  13. data/gemfiles/rails.3.2.activerecord.kaminari.gemfile +1 -0
  14. data/gemfiles/rails.3.2.activerecord.will_paginate.gemfile +1 -0
  15. data/gemfiles/rails.4.2.activerecord.gemfile +1 -0
  16. data/gemfiles/rails.4.2.activerecord.kaminari.gemfile +1 -0
  17. data/gemfiles/rails.4.2.activerecord.will_paginate.gemfile +1 -0
  18. data/gemfiles/{rails.4.2.mongoid.4.0.0.gemfile → rails.4.2.mongoid.4.0.gemfile} +2 -1
  19. data/gemfiles/{rails.4.2.mongoid.4.0.0.kaminari.gemfile → rails.4.2.mongoid.4.0.kaminari.gemfile} +2 -1
  20. data/gemfiles/{rails.4.2.mongoid.4.0.0.will_paginate.gemfile → rails.4.2.mongoid.4.0.will_paginate.gemfile} +2 -1
  21. data/gemfiles/{rails.4.2.mongoid.5.1.0.gemfile → rails.4.2.mongoid.5.1.gemfile} +2 -1
  22. data/gemfiles/{rails.4.2.mongoid.5.1.0.kaminari.gemfile → rails.4.2.mongoid.5.1.kaminari.gemfile} +2 -1
  23. data/gemfiles/{rails.4.2.mongoid.5.1.0.will_paginate.gemfile → rails.4.2.mongoid.5.1.will_paginate.gemfile} +2 -1
  24. data/gemfiles/{rails.4.0.activerecord.gemfile → rails.5.0.activerecord.gemfile} +4 -2
  25. data/gemfiles/{rails.4.0.mongoid.4.0.0.kaminari.gemfile → rails.5.0.activerecord.kaminari.gemfile} +4 -2
  26. data/gemfiles/{rails.4.0.mongoid.4.0.0.will_paginate.gemfile → rails.5.0.activerecord.will_paginate.gemfile} +4 -2
  27. data/gemfiles/{sequel.4.31.gemfile → sequel.4.38.gemfile} +3 -2
  28. data/lib/chewy.rb +24 -16
  29. data/lib/chewy/backports/deep_dup.rb +1 -1
  30. data/lib/chewy/backports/duplicable.rb +1 -0
  31. data/lib/chewy/config.rb +13 -7
  32. data/lib/chewy/errors.rb +4 -4
  33. data/lib/chewy/fields/base.rb +19 -14
  34. data/lib/chewy/fields/root.rb +11 -9
  35. data/lib/chewy/index.rb +38 -25
  36. data/lib/chewy/index/actions.rb +17 -17
  37. data/lib/chewy/index/settings.rb +3 -4
  38. data/lib/chewy/journal.rb +107 -0
  39. data/lib/chewy/journal/apply.rb +31 -0
  40. data/lib/chewy/journal/clean.rb +24 -0
  41. data/lib/chewy/journal/entry.rb +83 -0
  42. data/lib/chewy/journal/query.rb +87 -0
  43. data/lib/chewy/log_subscriber.rb +8 -8
  44. data/lib/chewy/minitest.rb +1 -0
  45. data/lib/chewy/minitest/helpers.rb +77 -0
  46. data/lib/chewy/minitest/search_index_receiver.rb +80 -0
  47. data/lib/chewy/query.rb +116 -60
  48. data/lib/chewy/query/compose.rb +5 -6
  49. data/lib/chewy/query/criteria.rb +26 -16
  50. data/lib/chewy/query/filters.rb +9 -9
  51. data/lib/chewy/query/loading.rb +2 -2
  52. data/lib/chewy/query/nodes/and.rb +3 -3
  53. data/lib/chewy/query/nodes/base.rb +1 -1
  54. data/lib/chewy/query/nodes/bool.rb +6 -4
  55. data/lib/chewy/query/nodes/equal.rb +6 -6
  56. data/lib/chewy/query/nodes/exists.rb +2 -2
  57. data/lib/chewy/query/nodes/expr.rb +2 -2
  58. data/lib/chewy/query/nodes/field.rb +35 -31
  59. data/lib/chewy/query/nodes/has_child.rb +1 -0
  60. data/lib/chewy/query/nodes/has_parent.rb +1 -0
  61. data/lib/chewy/query/nodes/has_relation.rb +11 -13
  62. data/lib/chewy/query/nodes/match_all.rb +1 -1
  63. data/lib/chewy/query/nodes/missing.rb +2 -2
  64. data/lib/chewy/query/nodes/not.rb +3 -3
  65. data/lib/chewy/query/nodes/or.rb +3 -3
  66. data/lib/chewy/query/nodes/prefix.rb +4 -3
  67. data/lib/chewy/query/nodes/query.rb +3 -3
  68. data/lib/chewy/query/nodes/range.rb +11 -11
  69. data/lib/chewy/query/nodes/raw.rb +1 -1
  70. data/lib/chewy/query/nodes/regexp.rb +15 -11
  71. data/lib/chewy/query/nodes/script.rb +6 -6
  72. data/lib/chewy/query/pagination/will_paginate.rb +2 -2
  73. data/lib/chewy/railtie.rb +3 -3
  74. data/lib/chewy/rake_helper.rb +51 -30
  75. data/lib/chewy/repository.rb +2 -2
  76. data/lib/chewy/rspec.rb +1 -1
  77. data/lib/chewy/rspec/update_index.rb +46 -47
  78. data/lib/chewy/runtime/version.rb +4 -4
  79. data/lib/chewy/search.rb +7 -5
  80. data/lib/chewy/strategy.rb +10 -8
  81. data/lib/chewy/strategy/atomic.rb +2 -2
  82. data/lib/chewy/strategy/base.rb +4 -4
  83. data/lib/chewy/strategy/bypass.rb +1 -2
  84. data/lib/chewy/strategy/sidekiq.rb +2 -0
  85. data/lib/chewy/strategy/urgent.rb +1 -1
  86. data/lib/chewy/type.rb +51 -45
  87. data/lib/chewy/type/adapter/active_record.rb +23 -12
  88. data/lib/chewy/type/adapter/base.rb +4 -4
  89. data/lib/chewy/type/adapter/mongoid.rb +6 -6
  90. data/lib/chewy/type/adapter/object.rb +15 -12
  91. data/lib/chewy/type/adapter/orm.rb +24 -15
  92. data/lib/chewy/type/adapter/sequel.rb +11 -7
  93. data/lib/chewy/type/crutch.rb +4 -3
  94. data/lib/chewy/type/import.rb +51 -32
  95. data/lib/chewy/type/mapping.rb +17 -17
  96. data/lib/chewy/type/observe.rb +9 -7
  97. data/lib/chewy/type/witchcraft.rb +62 -23
  98. data/lib/chewy/type/wrapper.rb +20 -14
  99. data/lib/chewy/version.rb +1 -1
  100. data/lib/generators/chewy/install_generator.rb +3 -3
  101. data/lib/tasks/chewy.rake +28 -23
  102. data/spec/chewy/config_spec.rb +33 -12
  103. data/spec/chewy/fields/base_spec.rb +143 -154
  104. data/spec/chewy/fields/root_spec.rb +22 -20
  105. data/spec/chewy/fields/time_fields_spec.rb +11 -9
  106. data/spec/chewy/index/actions_spec.rb +27 -4
  107. data/spec/chewy/index/aliases_spec.rb +2 -2
  108. data/spec/chewy/index/settings_spec.rb +72 -50
  109. data/spec/chewy/index_spec.rb +95 -43
  110. data/spec/chewy/journal/apply_spec.rb +120 -0
  111. data/spec/chewy/journal/entry_spec.rb +237 -0
  112. data/spec/chewy/journal_spec.rb +173 -0
  113. data/spec/chewy/minitest/helpers_spec.rb +90 -0
  114. data/spec/chewy/minitest/search_index_receiver_spec.rb +120 -0
  115. data/spec/chewy/query/criteria_spec.rb +504 -237
  116. data/spec/chewy/query/filters_spec.rb +94 -66
  117. data/spec/chewy/query/loading_spec.rb +76 -40
  118. data/spec/chewy/query/nodes/and_spec.rb +3 -7
  119. data/spec/chewy/query/nodes/bool_spec.rb +5 -13
  120. data/spec/chewy/query/nodes/equal_spec.rb +20 -20
  121. data/spec/chewy/query/nodes/exists_spec.rb +7 -7
  122. data/spec/chewy/query/nodes/has_child_spec.rb +42 -23
  123. data/spec/chewy/query/nodes/has_parent_spec.rb +42 -23
  124. data/spec/chewy/query/nodes/match_all_spec.rb +2 -2
  125. data/spec/chewy/query/nodes/missing_spec.rb +6 -5
  126. data/spec/chewy/query/nodes/not_spec.rb +3 -7
  127. data/spec/chewy/query/nodes/or_spec.rb +3 -7
  128. data/spec/chewy/query/nodes/prefix_spec.rb +6 -6
  129. data/spec/chewy/query/nodes/query_spec.rb +3 -3
  130. data/spec/chewy/query/nodes/range_spec.rb +19 -19
  131. data/spec/chewy/query/nodes/raw_spec.rb +2 -2
  132. data/spec/chewy/query/nodes/regexp_spec.rb +31 -19
  133. data/spec/chewy/query/nodes/script_spec.rb +5 -5
  134. data/spec/chewy/query/pagination/kaminari_spec.rb +2 -2
  135. data/spec/chewy/query/pagination/will_paginage_spec.rb +6 -7
  136. data/spec/chewy/query/pagination_spec.rb +2 -3
  137. data/spec/chewy/query_spec.rb +208 -145
  138. data/spec/chewy/repository_spec.rb +8 -8
  139. data/spec/chewy/rspec/update_index_spec.rb +180 -111
  140. data/spec/chewy/search_spec.rb +8 -8
  141. data/spec/chewy/strategy/active_job_spec.rb +2 -2
  142. data/spec/chewy/strategy/atomic_spec.rb +4 -1
  143. data/spec/chewy/strategy/resque_spec.rb +2 -2
  144. data/spec/chewy/strategy/sidekiq_spec.rb +2 -2
  145. data/spec/chewy/type/actions_spec.rb +1 -1
  146. data/spec/chewy/type/adapter/active_record_spec.rb +255 -149
  147. data/spec/chewy/type/adapter/mongoid_spec.rb +169 -108
  148. data/spec/chewy/type/adapter/object_spec.rb +56 -40
  149. data/spec/chewy/type/adapter/sequel_spec.rb +248 -163
  150. data/spec/chewy/type/import_spec.rb +78 -47
  151. data/spec/chewy/type/mapping_spec.rb +6 -6
  152. data/spec/chewy/type/observe_spec.rb +20 -14
  153. data/spec/chewy/type/witchcraft_spec.rb +89 -43
  154. data/spec/chewy/type_spec.rb +4 -3
  155. data/spec/chewy_spec.rb +10 -8
  156. data/spec/spec_helper.rb +3 -0
  157. data/spec/support/active_record.rb +1 -1
  158. data/spec/support/class_helpers.rb +10 -11
  159. data/spec/support/mongoid.rb +2 -2
  160. data/spec/support/sequel.rb +1 -1
  161. metadata +65 -35
  162. data/gemfiles/rails.4.0.activerecord.kaminari.gemfile +0 -14
  163. data/gemfiles/rails.4.0.activerecord.will_paginate.gemfile +0 -14
  164. data/gemfiles/rails.4.0.mongoid.4.0.0.gemfile +0 -15
  165. data/gemfiles/rails.4.0.mongoid.5.1.0.gemfile +0 -15
  166. data/gemfiles/rails.4.0.mongoid.5.1.0.kaminari.gemfile +0 -14
  167. data/gemfiles/rails.4.0.mongoid.5.1.0.will_paginate.gemfile +0 -14
  168. data/gemfiles/rails.4.1.activerecord.gemfile +0 -15
  169. data/gemfiles/rails.4.1.activerecord.kaminari.gemfile +0 -14
  170. data/gemfiles/rails.4.1.activerecord.will_paginate.gemfile +0 -14
  171. data/gemfiles/rails.4.1.mongoid.4.0.0.gemfile +0 -15
  172. data/gemfiles/rails.4.1.mongoid.4.0.0.kaminari.gemfile +0 -14
  173. data/gemfiles/rails.4.1.mongoid.4.0.0.will_paginate.gemfile +0 -14
  174. data/gemfiles/rails.4.1.mongoid.5.1.0.gemfile +0 -15
  175. data/gemfiles/rails.4.1.mongoid.5.1.0.kaminari.gemfile +0 -14
  176. data/gemfiles/rails.4.1.mongoid.5.1.0.will_paginate.gemfile +0 -14
  177. data/gemfiles/rails.5.0.0.beta3.activerecord.gemfile +0 -16
  178. data/gemfiles/rails.5.0.0.beta3.activerecord.kaminari.gemfile +0 -16
  179. data/gemfiles/rails.5.0.0.beta3.activerecord.will_paginate.gemfile +0 -15
@@ -39,7 +39,7 @@ describe Chewy::Type::Adapter::Mongoid, :mongoid do
39
39
 
40
40
  describe '#identify' do
41
41
  subject { described_class.new(City) }
42
- let!(:cities) { 3.times.map { City.create! } }
42
+ let!(:cities) { Array.new(3) { City.create! } }
43
43
 
44
44
  specify { expect(subject.identify(City.all)).to match_array(cities.map(&:id).map(&:to_s)) }
45
45
  specify { expect(subject.identify(cities)).to eq(cities.map(&:id).map(&:to_s)) }
@@ -47,7 +47,7 @@ describe Chewy::Type::Adapter::Mongoid, :mongoid do
47
47
  specify { expect(subject.identify(cities.first(2).map(&:id))).to eq(cities.first(2).map(&:id).map(&:to_s)) }
48
48
 
49
49
  context 'non-bson ids' do
50
- let!(:cities) { 3.times.map { |i| City.create! id: i+1 } }
50
+ let!(:cities) { Array.new(3) { |i| City.create! id: i + 1 } }
51
51
 
52
52
  specify { expect(subject.identify(City.all)).to match_array(cities.map(&:id)) }
53
53
  specify { expect(subject.identify(cities)).to eq(cities.map(&:id)) }
@@ -64,46 +64,62 @@ describe Chewy::Type::Adapter::Mongoid, :mongoid do
64
64
  end
65
65
 
66
66
  context do
67
- let!(:cities) { 3.times.map { |i| City.create! }.sort_by(&:id) }
68
- let!(:deleted) { 4.times.map { |i| City.create!.tap(&:destroy) }.sort_by(&:id) }
67
+ let!(:cities) { Array.new(3) { City.create! }.sort_by(&:id) }
68
+ let!(:deleted) { Array.new(4) { City.create!.tap(&:destroy) }.sort_by(&:id) }
69
69
  subject { described_class.new(City) }
70
70
 
71
- specify { expect(import).to match([{index: match_array(cities)}]) }
72
- specify { expect(import nil).to eq([]) }
73
-
74
- specify { expect(import(City.order(:id.asc))).to eq([{index: cities}]) }
75
- specify { expect(import(City.order(:id.asc), batch_size: 2))
76
- .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) }
77
-
78
- specify { expect(import(cities)).to eq([{index: cities}]) }
79
- specify { expect(import(cities, batch_size: 2))
80
- .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) }
81
- specify { expect(import(cities, deleted))
82
- .to eq([{index: cities}, {delete: deleted}]) }
83
- specify { expect(import(cities, deleted, batch_size: 2)).to eq([
84
- {index: cities.first(2)},
85
- {index: cities.last(1)},
86
- {delete: deleted.first(2)},
87
- {delete: deleted.last(2)}]) }
88
-
89
- specify { expect(import(cities.map(&:id))).to eq([{index: cities}]) }
90
- specify { expect(import(deleted.map(&:id))).to eq([{delete: deleted.map(&:id)}]) }
91
- specify { expect(import(cities.map(&:id), batch_size: 2))
92
- .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) }
93
- specify { expect(import(cities.map(&:id), deleted.map(&:id)))
94
- .to eq([{index: cities}, {delete: deleted.map(&:id)}]) }
95
- specify { expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 2)).to eq([
96
- {index: cities.first(2)},
97
- {index: cities.last(1)},
98
- {delete: deleted.first(2).map(&:id)},
99
- {delete: deleted.last(2).map(&:id)}]) }
100
-
101
- specify { expect(import(cities.first, nil)).to eq([{index: [cities.first]}]) }
102
- specify { expect(import(cities.first.id, nil)).to eq([{index: [cities.first]}]) }
71
+ specify { expect(import).to match([{ index: match_array(cities) }]) }
72
+ specify { expect(import(nil)).to eq([]) }
73
+
74
+ specify { expect(import(City.order(:id.asc))).to eq([{ index: cities }]) }
75
+ specify do
76
+ expect(import(City.order(:id.asc), batch_size: 2))
77
+ .to eq([{ index: cities.first(2) }, { index: cities.last(1) }])
78
+ end
79
+
80
+ specify { expect(import(cities)).to eq([{ index: cities }]) }
81
+ specify do
82
+ expect(import(cities, batch_size: 2))
83
+ .to eq([{ index: cities.first(2) }, { index: cities.last(1) }])
84
+ end
85
+ specify do
86
+ expect(import(cities, deleted))
87
+ .to eq([{ index: cities }, { delete: deleted }])
88
+ end
89
+ specify do
90
+ expect(import(cities, deleted, batch_size: 2)).to eq([
91
+ { index: cities.first(2) },
92
+ { index: cities.last(1) },
93
+ { delete: deleted.first(2) },
94
+ { delete: deleted.last(2) }
95
+ ])
96
+ end
97
+
98
+ specify { expect(import(cities.map(&:id))).to eq([{ index: cities }]) }
99
+ specify { expect(import(deleted.map(&:id))).to eq([{ delete: deleted.map(&:id) }]) }
100
+ specify do
101
+ expect(import(cities.map(&:id), batch_size: 2))
102
+ .to eq([{ index: cities.first(2) }, { index: cities.last(1) }])
103
+ end
104
+ specify do
105
+ expect(import(cities.map(&:id), deleted.map(&:id)))
106
+ .to eq([{ index: cities }, { delete: deleted.map(&:id) }])
107
+ end
108
+ specify do
109
+ expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 2)).to eq([
110
+ { index: cities.first(2) },
111
+ { index: cities.last(1) },
112
+ { delete: deleted.first(2).map(&:id) },
113
+ { delete: deleted.last(2).map(&:id) }
114
+ ])
115
+ end
116
+
117
+ specify { expect(import(cities.first, nil)).to eq([{ index: [cities.first] }]) }
118
+ specify { expect(import(cities.first.id, nil)).to eq([{ index: [cities.first] }]) }
103
119
  end
104
120
 
105
- context 'additional delete conitions' do
106
- let!(:cities) { 4.times.map { |i| City.create! rating: i } }
121
+ context 'additional delete conditions' do
122
+ let!(:cities) { Array.new(4) { |i| City.create! rating: i } }
107
123
  before { cities.last(2).map(&:destroy) }
108
124
  subject { described_class.new(City) }
109
125
 
@@ -114,76 +130,113 @@ describe Chewy::Type::Adapter::Mongoid, :mongoid do
114
130
  end
115
131
  end
116
132
  end
117
- subject { described_class.new(City, delete_if: ->{ delete_already? }) }
118
-
119
- specify { expect(import(City.all)).to eq([
120
- { index: [cities[0]], delete: [cities[1]] }
121
- ]) }
122
- specify { expect(import(cities)).to eq([
123
- { index: [cities[0]], delete: [cities[1]] },
124
- { delete: cities.last(2) }
125
- ]) }
126
- specify { expect(import(cities.map(&:id))).to eq([
127
- { index: [cities[0]], delete: [cities[1]] },
128
- { delete: cities.last(2).map(&:id) }
129
- ]) }
133
+ subject { described_class.new(City, delete_if: -> { delete_already? }) }
134
+
135
+ specify do
136
+ expect(import(City.all)).to eq([
137
+ { index: [cities[0]], delete: [cities[1]] }
138
+ ])
139
+ end
140
+ specify do
141
+ expect(import(cities)).to eq([
142
+ { index: [cities[0]], delete: [cities[1]] },
143
+ { delete: cities.last(2) }
144
+ ])
145
+ end
146
+ specify do
147
+ expect(import(cities.map(&:id))).to eq([
148
+ { index: [cities[0]], delete: [cities[1]] },
149
+ { delete: cities.last(2).map(&:id) }
150
+ ])
151
+ end
130
152
  end
131
153
 
132
154
  context 'default scope' do
133
- let!(:cities) { 4.times.map { |i| City.create!(id: i, rating: i/3) }.sort_by(&:id) }
134
- let!(:deleted) { 3.times.map { |i| City.create!(id: 4 + i).tap(&:destroy) }.sort_by(&:id) }
155
+ let!(:cities) { Array.new(4) { |i| City.create!(id: i, rating: i / 3) }.sort_by(&:id) }
156
+ let!(:deleted) { Array.new(3) { |i| City.create!(id: 4 + i).tap(&:destroy) }.sort_by(&:id) }
135
157
  subject { described_class.new(City.where(rating: 0)) }
136
158
 
137
- specify { expect(import).to eq([{index: cities.first(3)}]) }
159
+ specify { expect(import).to eq([{ index: cities.first(3) }]) }
138
160
 
139
- specify { expect(import(City.where(:rating.lt => 2).order(:id.asc)))
140
- .to eq([{index: cities.first(3)}]) }
141
- specify { expect(import(City.where(:rating.lt => 2).order(:id.asc), batch_size: 2))
142
- .to eq([{index: cities.first(2)}, {index: [cities[2]]}]) }
143
- specify { expect(import(City.where(:rating.lt => 1).order(:id.asc)))
144
- .to eq([{index: cities.first(3)}]) }
161
+ specify do
162
+ expect(import(City.where(:rating.lt => 2).order(:id.asc)))
163
+ .to eq([{ index: cities.first(3) }])
164
+ end
165
+ specify do
166
+ expect(import(City.where(:rating.lt => 2).order(:id.asc), batch_size: 2))
167
+ .to eq([{ index: cities.first(2) }, { index: [cities[2]] }])
168
+ end
169
+ specify do
170
+ expect(import(City.where(:rating.lt => 1).order(:id.asc)))
171
+ .to eq([{ index: cities.first(3) }])
172
+ end
145
173
  specify { expect(import(City.where(:rating.gt => 1).order(:id.asc))).to eq([]) }
146
174
 
147
- specify { expect(import(cities.first(2)))
148
- .to eq([{index: cities.first(2)}]) }
149
- specify { expect(import(cities))
150
- .to eq([{index: cities.first(3)}, {delete: cities.last(1)}]) }
151
- specify { expect(import(cities, batch_size: 2))
152
- .to eq([{index: cities.first(2)}, {index: [cities[2]]}, {delete: cities.last(1)}]) }
153
- specify { expect(import(cities, deleted))
154
- .to eq([{index: cities.first(3)}, {delete: cities.last(1) + deleted}]) }
155
- specify { expect(import(cities, deleted, batch_size: 3)).to eq([
156
- {index: cities.first(3)},
157
- {delete: cities.last(1) + deleted.first(2)},
158
- {delete: deleted.last(1)}]) }
159
-
160
- specify { expect(import(cities.first(2).map(&:id)))
161
- .to eq([{index: cities.first(2)}]) }
162
- specify { expect(import(cities.map(&:id)))
163
- .to eq([{index: cities.first(3)}, {delete: [cities.last.id]}]) }
164
- specify { expect(import(cities.map(&:id), batch_size: 2))
165
- .to eq([{index: cities.first(2)}, {index: [cities[2]]}, {delete: [cities.last.id]}]) }
166
- specify { expect(import(cities.map(&:id), deleted.map(&:id)))
167
- .to eq([{index: cities.first(3)}, {delete: [cities.last.id] + deleted.map(&:id)}]) }
168
- specify { expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 3)).to eq([
169
- {index: cities.first(3)},
170
- {delete: [cities.last.id] + deleted.first(2).map(&:id)},
171
- {delete: deleted.last(1).map(&:id)}]) }
175
+ specify do
176
+ expect(import(cities.first(2)))
177
+ .to eq([{ index: cities.first(2) }])
178
+ end
179
+ specify do
180
+ expect(import(cities))
181
+ .to eq([{ index: cities.first(3) }, { delete: cities.last(1) }])
182
+ end
183
+ specify do
184
+ expect(import(cities, batch_size: 2))
185
+ .to eq([{ index: cities.first(2) }, { index: [cities[2]] }, { delete: cities.last(1) }])
186
+ end
187
+ specify do
188
+ expect(import(cities, deleted))
189
+ .to eq([{ index: cities.first(3) }, { delete: cities.last(1) + deleted }])
190
+ end
191
+ specify do
192
+ expect(import(cities, deleted, batch_size: 3)).to eq([
193
+ { index: cities.first(3) },
194
+ { delete: cities.last(1) + deleted.first(2) },
195
+ { delete: deleted.last(1) }
196
+ ])
197
+ end
198
+
199
+ specify do
200
+ expect(import(cities.first(2).map(&:id)))
201
+ .to eq([{ index: cities.first(2) }])
202
+ end
203
+ specify do
204
+ expect(import(cities.map(&:id)))
205
+ .to eq([{ index: cities.first(3) }, { delete: [cities.last.id] }])
206
+ end
207
+ specify do
208
+ expect(import(cities.map(&:id), batch_size: 2))
209
+ .to eq([{ index: cities.first(2) }, { index: [cities[2]] }, { delete: [cities.last.id] }])
210
+ end
211
+ specify do
212
+ expect(import(cities.map(&:id), deleted.map(&:id)))
213
+ .to eq([{ index: cities.first(3) }, { delete: [cities.last.id] + deleted.map(&:id) }])
214
+ end
215
+ specify do
216
+ expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 3)).to eq([
217
+ { index: cities.first(3) },
218
+ { delete: [cities.last.id] + deleted.first(2).map(&:id) },
219
+ { delete: deleted.last(1).map(&:id) }
220
+ ])
221
+ end
172
222
  end
173
223
 
174
224
  context 'error handling' do
175
- let!(:cities) { 6.times.map { |i| City.create! } }
176
- let!(:deleted) { 4.times.map { |i| City.create!.tap(&:destroy) } }
225
+ let!(:cities) { Array.new(6) { City.create! } }
226
+ let!(:deleted) { Array.new(4) { City.create!.tap(&:destroy) } }
177
227
  let(:ids) { (cities + deleted).map(&:id) }
178
228
  subject { described_class.new(City) }
179
229
 
180
230
  let(:data_comparer) do
181
- ->(id, data) { objects = data[:index] || data[:delete]; !objects.map { |o| o.respond_to?(:id) ? o.id : o }.include?(id) }
231
+ lambda do |id, data|
232
+ objects = data[:index] || data[:delete]
233
+ !objects.map { |o| o.respond_to?(:id) ? o.id : o }.include?(id)
234
+ end
182
235
  end
183
236
 
184
237
  context 'implicit scope' do
185
- specify { expect(subject.import { |data| true }).to eq(true) }
186
- specify { expect(subject.import { |data| false }).to eq(false) }
238
+ specify { expect(subject.import { |_data| true }).to eq(true) }
239
+ specify { expect(subject.import { |_data| false }).to eq(false) }
187
240
  specify { expect(subject.import(batch_size: 2, &data_comparer.curry[cities[0].id])).to eq(false) }
188
241
  specify { expect(subject.import(batch_size: 2, &data_comparer.curry[cities[2].id])).to eq(false) }
189
242
  specify { expect(subject.import(batch_size: 2, &data_comparer.curry[cities[4].id])).to eq(false) }
@@ -194,8 +247,8 @@ describe Chewy::Type::Adapter::Mongoid, :mongoid do
194
247
  context 'explicit scope' do
195
248
  let(:scope) { City.where(:id.in => ids) }
196
249
 
197
- specify { expect(subject.import(scope) { |data| true }).to eq(true) }
198
- specify { expect(subject.import(scope) { |data| false }).to eq(false) }
250
+ specify { expect(subject.import(scope) { |_data| true }).to eq(true) }
251
+ specify { expect(subject.import(scope) { |_data| false }).to eq(false) }
199
252
  specify { expect(subject.import(scope, batch_size: 2, &data_comparer.curry[cities[0].id])).to eq(false) }
200
253
  specify { expect(subject.import(scope, batch_size: 2, &data_comparer.curry[cities[2].id])).to eq(false) }
201
254
  specify { expect(subject.import(scope, batch_size: 2, &data_comparer.curry[cities[4].id])).to eq(false) }
@@ -204,8 +257,8 @@ describe Chewy::Type::Adapter::Mongoid, :mongoid do
204
257
  end
205
258
 
206
259
  context 'objects' do
207
- specify { expect(subject.import(cities + deleted) { |data| true }).to eq(true) }
208
- specify { expect(subject.import(cities + deleted) { |data| false }).to eq(false) }
260
+ specify { expect(subject.import(cities + deleted) { |_data| true }).to eq(true) }
261
+ specify { expect(subject.import(cities + deleted) { |_data| false }).to eq(false) }
209
262
  specify { expect(subject.import(cities + deleted, batch_size: 2, &data_comparer.curry[cities[0].id])).to eq(false) }
210
263
  specify { expect(subject.import(cities + deleted, batch_size: 2, &data_comparer.curry[cities[2].id])).to eq(false) }
211
264
  specify { expect(subject.import(cities + deleted, batch_size: 2, &data_comparer.curry[cities[4].id])).to eq(false) }
@@ -214,8 +267,8 @@ describe Chewy::Type::Adapter::Mongoid, :mongoid do
214
267
  end
215
268
 
216
269
  context 'ids' do
217
- specify { expect(subject.import(ids) { |data| true }).to eq(true) }
218
- specify { expect(subject.import(ids) { |data| false }).to eq(false) }
270
+ specify { expect(subject.import(ids) { |_data| true }).to eq(true) }
271
+ specify { expect(subject.import(ids) { |_data| false }).to eq(false) }
219
272
  specify { expect(subject.import(ids, batch_size: 2, &data_comparer.curry[cities[0].id])).to eq(false) }
220
273
  specify { expect(subject.import(ids, batch_size: 2, &data_comparer.curry[cities[2].id])).to eq(false) }
221
274
  specify { expect(subject.import(ids, batch_size: 2, &data_comparer.curry[cities[4].id])).to eq(false) }
@@ -227,8 +280,8 @@ describe Chewy::Type::Adapter::Mongoid, :mongoid do
227
280
 
228
281
  describe '#load' do
229
282
  context do
230
- let!(:cities) { 3.times.map { |i| City.create!(id: i, rating: i/2) }.sort_by(&:id) }
231
- let!(:deleted) { 2.times.map { |i| City.create!(id: 3 + i).tap(&:destroy) }.sort_by(&:id) }
283
+ let!(:cities) { Array.new(3) { |i| City.create!(id: i, rating: i / 2) }.sort_by(&:id) }
284
+ let!(:deleted) { Array.new(2) { |i| City.create!(id: 3 + i).tap(&:destroy) }.sort_by(&:id) }
232
285
 
233
286
  let(:type) { double(type_name: 'user') }
234
287
 
@@ -238,16 +291,24 @@ describe Chewy::Type::Adapter::Mongoid, :mongoid do
238
291
  specify { expect(subject.load(cities.map { |c| double(id: c.id) }.reverse, _type: type)).to eq(cities.reverse) }
239
292
  specify { expect(subject.load(deleted.map { |c| double(id: c.id) }, _type: type)).to eq([nil, nil]) }
240
293
  specify { expect(subject.load((cities + deleted).map { |c| double(id: c.id) }, _type: type)).to eq([*cities, nil, nil]) }
241
- specify { expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: ->{ where(rating: 0) }))
242
- .to eq(cities.first(2) + [nil]) }
243
- specify { expect(subject.load(cities.map { |c| double(id: c.id) },
244
- _type: type, scope: ->{ where(rating: 0) }, user: {scope: ->{ where(rating: 1)}}))
245
- .to eq([nil, nil] + cities.last(1)) }
246
- specify { expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: City.where(rating: 1)))
247
- .to eq([nil, nil] + cities.last(1)) }
248
- specify { expect(subject.load(cities.map { |c| double(id: c.id) },
249
- _type: type, scope: City.where(rating: 1), user: {scope: ->{ where(rating: 0)}}))
250
- .to eq(cities.first(2) + [nil]) }
294
+ specify do
295
+ expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: -> { where(rating: 0) }))
296
+ .to eq(cities.first(2) + [nil])
297
+ end
298
+ specify do
299
+ expect(subject.load(cities.map { |c| double(id: c.id) },
300
+ _type: type, scope: -> { where(rating: 0) }, user: { scope: -> { where(rating: 1) } }))
301
+ .to eq([nil, nil] + cities.last(1))
302
+ end
303
+ specify do
304
+ expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: City.where(rating: 1)))
305
+ .to eq([nil, nil] + cities.last(1))
306
+ end
307
+ specify do
308
+ expect(subject.load(cities.map { |c| double(id: c.id) },
309
+ _type: type, scope: City.where(rating: 1), user: { scope: -> { where(rating: 0) } }))
310
+ .to eq(cities.first(2) + [nil])
311
+ end
251
312
  end
252
313
  end
253
314
  end
@@ -30,7 +30,7 @@ describe Chewy::Type::Adapter::Object do
30
30
  end
31
31
 
32
32
  describe '#identify' do
33
- let!(:objects) { 3.times.map { double } }
33
+ let!(:objects) { Array.new(3) { double } }
34
34
 
35
35
  specify { expect(subject.identify(objects)).to eq(objects) }
36
36
  specify { expect(subject.identify(objects.first)).to eq([objects.first]) }
@@ -43,65 +43,76 @@ describe Chewy::Type::Adapter::Object do
43
43
  result
44
44
  end
45
45
 
46
- specify { expect(subject.import(3.times.map { |i| double }) { |data| true }).to eq(true) }
47
- specify { expect(subject.import(3.times.map { |i| double }) { |data| false }).to eq(false) }
46
+ specify { expect(subject.import(Array.new(3) { double }) { |_data| true }).to eq(true) }
47
+ specify { expect(subject.import(Array.new(3) { double }) { |_data| false }).to eq(false) }
48
48
 
49
49
  context do
50
- let(:objects) { 3.times.map { |i| double } }
51
- let(:deleted) { 2.times.map { |i| double(destroyed?: true) } }
50
+ let(:objects) { Array.new(3) { double } }
51
+ let(:deleted) { Array.new(2) { double(destroyed?: true) } }
52
52
  subject { described_class.new('product') }
53
53
 
54
54
  specify { expect(import).to eq([]) }
55
- specify { expect(import nil).to eq([]) }
55
+ specify { expect(import(nil)).to eq([]) }
56
56
 
57
- specify { expect(import(objects)).to eq([{index: objects}]) }
58
- specify { expect(import(objects, batch_size: 2))
59
- .to eq([{index: objects.first(2)}, {index: objects.last(1)}]) }
60
- specify { expect(import(objects, deleted)).to eq([{index: objects, delete: deleted}]) }
61
- specify { expect(import(objects, deleted, batch_size: 2)).to eq([
62
- {index: objects.first(2)},
63
- {index: objects.last(1), delete: deleted.first(1)},
64
- {delete: deleted.last(1)}]) }
57
+ specify { expect(import(objects)).to eq([{ index: objects }]) }
58
+ specify do
59
+ expect(import(objects, batch_size: 2))
60
+ .to eq([{ index: objects.first(2) }, { index: objects.last(1) }])
61
+ end
62
+ specify { expect(import(objects, deleted)).to eq([{ index: objects, delete: deleted }]) }
63
+ specify do
64
+ expect(import(objects, deleted, batch_size: 2)).to eq([
65
+ { index: objects.first(2) },
66
+ { index: objects.last(1), delete: deleted.first(1) },
67
+ { delete: deleted.last(1) }
68
+ ])
69
+ end
65
70
 
66
- specify { expect(import(objects.first, nil)).to eq([{index: [objects.first]}]) }
71
+ specify { expect(import(objects.first, nil)).to eq([{ index: [objects.first] }]) }
67
72
 
68
73
  context 'initial data' do
69
- subject { described_class.new ->{ objects } }
74
+ subject { described_class.new -> { objects } }
70
75
 
71
- specify { expect(import).to eq([{index: objects}]) }
72
- specify { expect(import nil).to eq([]) }
76
+ specify { expect(import).to eq([{ index: objects }]) }
77
+ specify { expect(import(nil)).to eq([]) }
73
78
 
74
- specify { expect(import(objects[0..1])).to eq([{index: objects[0..1]}]) }
75
- specify { expect(import(batch_size: 2))
76
- .to eq([{index: objects.first(2)}, {index: objects.last(1)}]) }
79
+ specify { expect(import(objects[0..1])).to eq([{ index: objects[0..1] }]) }
80
+ specify do
81
+ expect(import(batch_size: 2))
82
+ .to eq([{ index: objects.first(2) }, { index: objects.last(1) }])
83
+ end
77
84
  end
78
85
 
79
86
  context do
80
87
  subject { described_class.new('product', delete_if: :delete?) }
81
- let(:deleted) { [
82
- double(delete?: true, destroyed?: true),
83
- double(delete?: true, destroyed?: false),
84
- double(delete?: false, destroyed?: true),
85
- double(delete?: false, destroyed?: false)
86
- ] }
87
-
88
- specify { expect(import(deleted)).to eq([
89
- { delete: deleted[0..2], index: deleted.last(1) }
90
- ]) }
88
+ let(:deleted) do
89
+ [
90
+ double(delete?: true, destroyed?: true),
91
+ double(delete?: true, destroyed?: false),
92
+ double(delete?: false, destroyed?: true),
93
+ double(delete?: false, destroyed?: false)
94
+ ]
95
+ end
96
+
97
+ specify do
98
+ expect(import(deleted)).to eq([
99
+ { delete: deleted[0..2], index: deleted.last(1) }
100
+ ])
101
+ end
91
102
  end
92
103
  end
93
104
 
94
105
  context 'error handling' do
95
- let(:products) { 3.times.map { |i| double.tap { |product| allow(product).to receive_messages(rating: i.next) } } }
96
- let(:deleted) { 2.times.map { |i| double(destroyed?: true, rating: i + 4) } }
106
+ let(:products) { Array.new(3) { |i| double.tap { |product| allow(product).to receive_messages(rating: i.next) } } }
107
+ let(:deleted) { Array.new(2) { |i| double(destroyed?: true, rating: i + 4) } }
97
108
  subject { described_class.new('product') }
98
109
 
99
110
  let(:data_comparer) do
100
111
  ->(n, data) { (data[:index] || data[:delete]).first.rating != n }
101
112
  end
102
113
 
103
- specify { expect(subject.import(products, deleted) { |data| true }).to eq(true) }
104
- specify { expect(subject.import(products, deleted) { |data| false }).to eq(false) }
114
+ specify { expect(subject.import(products, deleted) { |_data| true }).to eq(true) }
115
+ specify { expect(subject.import(products, deleted) { |_data| false }).to eq(false) }
105
116
  specify { expect(subject.import(products, deleted, batch_size: 1, &data_comparer.curry[1])).to eq(false) }
106
117
  specify { expect(subject.import(products, deleted, batch_size: 1, &data_comparer.curry[2])).to eq(false) }
107
118
  specify { expect(subject.import(products, deleted, batch_size: 1, &data_comparer.curry[3])).to eq(false) }
@@ -113,24 +124,29 @@ describe Chewy::Type::Adapter::Object do
113
124
  describe '#load' do
114
125
  context do
115
126
  subject { described_class.new('product') }
116
- let(:objects) { 3.times.map { |i| double } }
127
+ let(:objects) { Array.new(3) { double } }
117
128
 
118
129
  specify { expect(subject.load(objects)).to eq(objects) }
119
130
  end
120
131
 
121
132
  [:wrap, :load_one].each do |load_method|
122
133
  context do
123
- before { allow(Product).to receive(load_method) { |object| allow(object).to receive_messages(wrapped?: true); object } }
134
+ before do
135
+ allow(Product).to receive(load_method) { |object|
136
+ allow(object).to receive_messages(wrapped?: true)
137
+ object
138
+ }
139
+ end
124
140
  subject { described_class.new(Product) }
125
- let(:objects) { 3.times.map { |i| double(wrapped?: false) } }
141
+ let(:objects) { Array.new(3) { double(wrapped?: false) } }
126
142
 
127
143
  specify { expect(subject.load(objects)).to satisfy { |objects| objects.all?(&:wrapped?) } }
128
144
  end
129
145
 
130
146
  context do
131
- before { allow(Product).to receive(load_method) { |object| nil } }
147
+ before { allow(Product).to receive(load_method) { |_object| nil } }
132
148
  subject { described_class.new(Product) }
133
- let(:objects) { 3.times.map { |i| double(wrapped?: false) } }
149
+ let(:objects) { Array.new(3) { double(wrapped?: false) } }
134
150
 
135
151
  specify { expect(subject.load(objects)).to satisfy { |objects| objects.all?(&:nil?) } }
136
152
  end