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
@@ -7,24 +7,24 @@ describe Chewy::Type::Adapter::Sequel, :sequel do
7
7
  end
8
8
 
9
9
  describe '#name' do
10
- it { expect( described_class.new(City).name ).to eq 'City' }
11
- it { expect( described_class.new(City.order(:id)).name ).to eq 'City' }
12
- it { expect( described_class.new(City, name: 'town').name ).to eq 'Town' }
10
+ it { expect(described_class.new(City).name).to eq 'City' }
11
+ it { expect(described_class.new(City.order(:id)).name).to eq 'City' }
12
+ it { expect(described_class.new(City, name: 'town').name).to eq 'Town' }
13
13
 
14
14
  context do
15
15
  before { stub_model('namespace/city') }
16
16
 
17
- it { expect( described_class.new(Namespace::City).name ).to eq 'City' }
18
- it { expect( described_class.new(Namespace::City.order(:id)).name ).to eq 'City' }
17
+ it { expect(described_class.new(Namespace::City).name).to eq 'City' }
18
+ it { expect(described_class.new(Namespace::City.order(:id)).name).to eq 'City' }
19
19
  end
20
20
  end
21
21
 
22
22
  describe '#default_scope' do
23
- it { expect( described_class.new(City).default_scope.sql ).to eql City.where(nil).sql }
24
- it { expect( described_class.new(City.order(:id)).default_scope.sql ).to eql City.where(nil).sql }
25
- it { expect( described_class.new(City.limit(10)).default_scope.sql ).to eql City.where(nil).sql }
26
- it { expect( described_class.new(City.offset(10)).default_scope.sql ).to eql City.where(nil).sql }
27
- it { expect( described_class.new(City.where(rating: 10)).default_scope.sql ).to eql City.where(rating: 10).sql }
23
+ it { expect(described_class.new(City).default_scope.sql).to eql City.where(nil).sql }
24
+ it { expect(described_class.new(City.order(:id)).default_scope.sql).to eql City.where(nil).sql }
25
+ it { expect(described_class.new(City.limit(10)).default_scope.sql).to eql City.where(nil).sql }
26
+ it { expect(described_class.new(City.offset(10)).default_scope.sql).to eql City.where(nil).sql }
27
+ it { expect(described_class.new(City.where(rating: 10)).default_scope.sql).to eql City.where(rating: 10).sql }
28
28
  end
29
29
 
30
30
  describe '#type_name' do
@@ -44,17 +44,17 @@ describe Chewy::Type::Adapter::Sequel, :sequel do
44
44
  subject { described_class.new(City) }
45
45
 
46
46
  context do
47
- let!(:cities) { 3.times.map { City.new.save! } }
47
+ let!(:cities) { Array.new(3) { City.new.save! } }
48
48
 
49
- it { expect(subject.identify(City.where(nil)) ).to match_array cities.map(&:id) }
50
- it { expect(subject.identify(cities) ).to eq cities.map(&:id) }
51
- it { expect(subject.identify(cities.first) ).to eq([cities.first.id]) }
52
- it { expect(subject.identify(cities.first(2).map(&:id)) ).to eq cities.first(2).map(&:id) }
49
+ it { expect(subject.identify(City.where(nil))).to match_array cities.map(&:id) }
50
+ it { expect(subject.identify(cities)).to eq cities.map(&:id) }
51
+ it { expect(subject.identify(cities.first)).to eq([cities.first.id]) }
52
+ it { expect(subject.identify(cities.first(2).map(&:id))).to eq cities.first(2).map(&:id) }
53
53
  end
54
54
 
55
55
  context 'custom primary_key' do
56
56
  before { stub_model(:city).set_dataset :rating_cities }
57
- let!(:cities) { 3.times.map { |i| City.create! { |c| c.rating = i } } }
57
+ let!(:cities) { Array.new(3) { |i| City.create! { |c| c.rating = i } } }
58
58
 
59
59
  specify { expect(subject.identify(City.where(nil))).to match_array([0, 1, 2]) }
60
60
  specify { expect(subject.identify(cities)).to eq([0, 1, 2]) }
@@ -71,46 +71,62 @@ describe Chewy::Type::Adapter::Sequel, :sequel do
71
71
  end
72
72
 
73
73
  context do
74
- let!(:cities) { 3.times.map { City.create! } }
75
- let!(:deleted) { 4.times.map { City.create!.tap(&:destroy) } }
74
+ let!(:cities) { Array.new(3) { City.create! } }
75
+ let!(:deleted) { Array.new(4) { City.create!.tap(&:destroy) } }
76
76
  subject { described_class.new(City) }
77
77
 
78
- specify { expect(import).to eq([{index: cities}]) }
79
- specify { expect(import nil).to eq([]) }
80
-
81
- specify { expect(import(City.order(:id))).to eq([{index: cities}]) }
82
- specify { expect(import(City.order(:id), batch_size: 2))
83
- .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) }
84
-
85
- specify { expect(import(cities)).to eq([{index: cities}]) }
86
- specify { expect(import(cities, batch_size: 2))
87
- .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) }
88
- specify { expect(import(cities, deleted))
89
- .to eq([{index: cities}, {delete: deleted}]) }
90
- specify { 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
- specify { expect(import(cities.map(&:id))).to eq([{index: cities}]) }
97
- specify { expect(import(deleted.map(&:id))).to eq([{delete: deleted.map(&:id)}]) }
98
- specify { expect(import(cities.map(&:id), batch_size: 2))
99
- .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) }
100
- specify { expect(import(cities.map(&:id), deleted.map(&:id)))
101
- .to eq([{index: cities}, {delete: deleted.map(&:id)}]) }
102
- specify { expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 2)).to eq([
103
- {index: cities.first(2)},
104
- {index: cities.last(1)},
105
- {delete: deleted.first(2).map(&:id)},
106
- {delete: deleted.last(2).map(&:id)}]) }
107
-
108
- specify { expect(import(cities.first, nil)).to eq([{index: [cities.first]}]) }
109
- specify { expect(import(cities.first.id, nil)).to eq([{index: [cities.first]}]) }
78
+ specify { expect(import).to eq([{ index: cities }]) }
79
+ specify { expect(import(nil)).to eq([]) }
80
+
81
+ specify { expect(import(City.order(:id))).to eq([{ index: cities }]) }
82
+ specify do
83
+ expect(import(City.order(:id), batch_size: 2))
84
+ .to eq([{ index: cities.first(2) }, { index: cities.last(1) }])
85
+ end
86
+
87
+ specify { expect(import(cities)).to eq([{ index: cities }]) }
88
+ specify do
89
+ expect(import(cities, batch_size: 2))
90
+ .to eq([{ index: cities.first(2) }, { index: cities.last(1) }])
91
+ end
92
+ specify do
93
+ expect(import(cities, deleted))
94
+ .to eq([{ index: cities }, { delete: deleted }])
95
+ end
96
+ specify do
97
+ expect(import(cities, deleted, batch_size: 2)).to eq([
98
+ { index: cities.first(2) },
99
+ { index: cities.last(1) },
100
+ { delete: deleted.first(2) },
101
+ { delete: deleted.last(2) }
102
+ ])
103
+ end
104
+
105
+ specify { expect(import(cities.map(&:id))).to eq([{ index: cities }]) }
106
+ specify { expect(import(deleted.map(&:id))).to eq([{ delete: deleted.map(&:id) }]) }
107
+ specify do
108
+ expect(import(cities.map(&:id), batch_size: 2))
109
+ .to eq([{ index: cities.first(2) }, { index: cities.last(1) }])
110
+ end
111
+ specify do
112
+ expect(import(cities.map(&:id), deleted.map(&:id)))
113
+ .to eq([{ index: cities }, { delete: deleted.map(&:id) }])
114
+ end
115
+ specify do
116
+ expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 2)).to eq([
117
+ { index: cities.first(2) },
118
+ { index: cities.last(1) },
119
+ { delete: deleted.first(2).map(&:id) },
120
+ { delete: deleted.last(2).map(&:id) }
121
+ ])
122
+ end
123
+
124
+ specify { expect(import(cities.first, nil)).to eq([{ index: [cities.first] }]) }
125
+ specify { expect(import(cities.first.id, nil)).to eq([{ index: [cities.first] }]) }
110
126
  end
111
127
 
112
- context 'additional delete conitions' do
113
- let!(:cities) { 4.times.map { |i| City.create! rating: i } }
128
+ context 'additional delete conditions' do
129
+ let!(:cities) { Array.new(4) { |i| City.create! rating: i } }
114
130
  before { cities.last(2).map(&:destroy) }
115
131
  subject { described_class.new(City) }
116
132
 
@@ -121,111 +137,164 @@ describe Chewy::Type::Adapter::Sequel, :sequel do
121
137
  end
122
138
  end
123
139
  end
124
- subject { described_class.new(City, delete_if: ->{ delete_already? }) }
125
-
126
- specify { expect(import(City.where(nil))).to eq([
127
- { index: [cities[0]], delete: [cities[1]] }
128
- ]) }
129
- specify { expect(import(cities)).to eq([
130
- { index: [cities[0]], delete: [cities[1]] },
131
- { delete: cities.last(2) }
132
- ]) }
133
- specify { expect(import(cities.map(&:id))).to eq([
134
- { index: [cities[0]], delete: [cities[1]] },
135
- { delete: cities.last(2).map(&:id) }
136
- ]) }
140
+ subject { described_class.new(City, delete_if: -> { delete_already? }) }
141
+
142
+ specify do
143
+ expect(import(City.where(nil))).to eq([
144
+ { index: [cities[0]], delete: [cities[1]] }
145
+ ])
146
+ end
147
+ specify do
148
+ expect(import(cities)).to eq([
149
+ { index: [cities[0]], delete: [cities[1]] },
150
+ { delete: cities.last(2) }
151
+ ])
152
+ end
153
+ specify do
154
+ expect(import(cities.map(&:id))).to eq([
155
+ { index: [cities[0]], delete: [cities[1]] },
156
+ { delete: cities.last(2).map(&:id) }
157
+ ])
158
+ end
137
159
  end
138
160
 
139
161
  context 'custom primary_key' do
140
162
  before { stub_model(:city).set_dataset :rating_cities }
141
- let!(:cities) { 3.times.map { |i| City.create! { |c| c.rating = i + 7 } } }
142
- let!(:deleted) { 3.times.map { |i| City.create! { |c| c.rating = i + 10 }.tap(&:destroy) } }
163
+ let!(:cities) { Array.new(3) { |i| City.create! { |c| c.rating = i + 7 } } }
164
+ let!(:deleted) { Array.new(3) { |i| City.create! { |c| c.rating = i + 10 }.tap(&:destroy) } }
143
165
  subject { described_class.new(City) }
144
166
 
145
- specify { expect(import).to eq([{index: cities}]) }
146
-
147
- specify { expect(import(City.order(:rating))).to eq([{index: cities}]) }
148
- specify { expect(import(City.order(:rating), batch_size: 2))
149
- .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) }
150
-
151
- specify { expect(import(cities)).to eq([{index: cities}]) }
152
- specify { expect(import(cities, batch_size: 2))
153
- .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) }
154
- specify { expect(import(cities, deleted))
155
- .to eq([{index: cities}, {delete: deleted}]) }
156
- specify { expect(import(cities, deleted, batch_size: 2)).to eq([
157
- {index: cities.first(2)},
158
- {index: cities.last(1)},
159
- {delete: deleted.first(2)},
160
- {delete: deleted.last(1)}]) }
161
-
162
- specify { expect(import(cities.map(&:rating))).to eq([{index: cities}]) }
163
- specify { expect(import(cities.map(&:rating), batch_size: 2))
164
- .to eq([{index: cities.first(2)}, {index: cities.last(1)}]) }
165
- specify { expect(import(cities.map(&:rating), deleted.map(&:rating)))
166
- .to eq([{index: cities}, {delete: deleted.map(&:rating)}]) }
167
- specify { expect(import(cities.map(&:rating), deleted.map(&:rating), batch_size: 2)).to eq([
168
- {index: cities.first(2)},
169
- {index: cities.last(1)},
170
- {delete: deleted.first(2).map(&:rating)},
171
- {delete: deleted.last(1).map(&:rating)}]) }
167
+ specify { expect(import).to eq([{ index: cities }]) }
168
+
169
+ specify { expect(import(City.order(:rating))).to eq([{ index: cities }]) }
170
+ specify do
171
+ expect(import(City.order(:rating), batch_size: 2))
172
+ .to eq([{ index: cities.first(2) }, { index: cities.last(1) }])
173
+ end
174
+
175
+ specify { expect(import(cities)).to eq([{ index: cities }]) }
176
+ specify do
177
+ expect(import(cities, batch_size: 2))
178
+ .to eq([{ index: cities.first(2) }, { index: cities.last(1) }])
179
+ end
180
+ specify do
181
+ expect(import(cities, deleted))
182
+ .to eq([{ index: cities }, { delete: deleted }])
183
+ end
184
+ specify do
185
+ expect(import(cities, deleted, batch_size: 2)).to eq([
186
+ { index: cities.first(2) },
187
+ { index: cities.last(1) },
188
+ { delete: deleted.first(2) },
189
+ { delete: deleted.last(1) }
190
+ ])
191
+ end
192
+
193
+ specify { expect(import(cities.map(&:rating))).to eq([{ index: cities }]) }
194
+ specify do
195
+ expect(import(cities.map(&:rating), batch_size: 2))
196
+ .to eq([{ index: cities.first(2) }, { index: cities.last(1) }])
197
+ end
198
+ specify do
199
+ expect(import(cities.map(&:rating), deleted.map(&:rating)))
200
+ .to eq([{ index: cities }, { delete: deleted.map(&:rating) }])
201
+ end
202
+ specify do
203
+ expect(import(cities.map(&:rating), deleted.map(&:rating), batch_size: 2)).to eq([
204
+ { index: cities.first(2) },
205
+ { index: cities.last(1) },
206
+ { delete: deleted.first(2).map(&:rating) },
207
+ { delete: deleted.last(1).map(&:rating) }
208
+ ])
209
+ end
172
210
  end
173
211
 
174
212
  context 'default scope' do
175
- let!(:cities) { 4.times.map { |i| City.create!(rating: i/3) } }
176
- let!(:deleted) { 3.times.map { |i| City.create!.tap(&:destroy) } }
213
+ let!(:cities) { Array.new(4) { |i| City.create!(rating: i / 3) } }
214
+ let!(:deleted) { Array.new(3) { City.create!.tap(&:destroy) } }
177
215
  subject { described_class.new(City.where(rating: 0)) }
178
216
 
179
- specify { expect(import).to eq([{index: cities.first(3)}]) }
217
+ specify { expect(import).to eq([{ index: cities.first(3) }]) }
180
218
 
181
- specify { expect(import(City.where('rating < 2')))
182
- .to eq([{index: cities.first(3)}]) }
183
- specify { expect(import(City.where('rating < 2'), batch_size: 2))
184
- .to eq([{index: cities.first(2)}, {index: [cities[2]]}]) }
185
- specify { expect(import(City.where('rating < 1')))
186
- .to eq([{index: cities.first(3)}]) }
219
+ specify do
220
+ expect(import(City.where('rating < 2')))
221
+ .to eq([{ index: cities.first(3) }])
222
+ end
223
+ specify do
224
+ expect(import(City.where('rating < 2'), batch_size: 2))
225
+ .to eq([{ index: cities.first(2) }, { index: [cities[2]] }])
226
+ end
227
+ specify do
228
+ expect(import(City.where('rating < 1')))
229
+ .to eq([{ index: cities.first(3) }])
230
+ end
187
231
  specify { expect(import(City.where('rating > 1'))).to eq([]) }
188
232
 
189
- specify { expect(import(cities.first(2)))
190
- .to eq([{index: cities.first(2)}]) }
191
- specify { expect(import(cities))
192
- .to eq([{index: cities.first(3)}, {delete: cities.last(1)}]) }
193
- specify { expect(import(cities, batch_size: 2))
194
- .to eq([{index: cities.first(2)}, {index: [cities[2]]}, {delete: cities.last(1)}]) }
195
- specify { expect(import(cities, deleted))
196
- .to eq([{index: cities.first(3)}, {delete: cities.last(1) + deleted}]) }
197
- specify { expect(import(cities, deleted, batch_size: 3)).to eq([
198
- {index: cities.first(3)},
199
- {delete: cities.last(1) + deleted.first(2)},
200
- {delete: deleted.last(1)}]) }
201
-
202
- specify { expect(import(cities.first(2).map(&:id)))
203
- .to eq([{index: cities.first(2)}]) }
204
- specify { expect(import(cities.map(&:id)))
205
- .to eq([{index: cities.first(3)}, {delete: [cities.last.id]}]) }
206
- specify { expect(import(cities.map(&:id), batch_size: 2))
207
- .to eq([{index: cities.first(2)}, {index: [cities[2]]}, {delete: [cities.last.id]}]) }
208
- specify { expect(import(cities.map(&:id), deleted.map(&:id)))
209
- .to eq([{index: cities.first(3)}, {delete: [cities.last.id] + deleted.map(&:id)}]) }
210
- specify { expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 3)).to eq([
211
- {index: cities.first(3)},
212
- {delete: [cities.last.id] + deleted.first(2).map(&:id)},
213
- {delete: deleted.last(1).map(&:id)}]) }
233
+ specify do
234
+ expect(import(cities.first(2)))
235
+ .to eq([{ index: cities.first(2) }])
236
+ end
237
+ specify do
238
+ expect(import(cities))
239
+ .to eq([{ index: cities.first(3) }, { delete: cities.last(1) }])
240
+ end
241
+ specify do
242
+ expect(import(cities, batch_size: 2))
243
+ .to eq([{ index: cities.first(2) }, { index: [cities[2]] }, { delete: cities.last(1) }])
244
+ end
245
+ specify do
246
+ expect(import(cities, deleted))
247
+ .to eq([{ index: cities.first(3) }, { delete: cities.last(1) + deleted }])
248
+ end
249
+ specify do
250
+ expect(import(cities, deleted, batch_size: 3)).to eq([
251
+ { index: cities.first(3) },
252
+ { delete: cities.last(1) + deleted.first(2) },
253
+ { delete: deleted.last(1) }
254
+ ])
255
+ end
256
+
257
+ specify do
258
+ expect(import(cities.first(2).map(&:id)))
259
+ .to eq([{ index: cities.first(2) }])
260
+ end
261
+ specify do
262
+ expect(import(cities.map(&:id)))
263
+ .to eq([{ index: cities.first(3) }, { delete: [cities.last.id] }])
264
+ end
265
+ specify do
266
+ expect(import(cities.map(&:id), batch_size: 2))
267
+ .to eq([{ index: cities.first(2) }, { index: [cities[2]] }, { delete: [cities.last.id] }])
268
+ end
269
+ specify do
270
+ expect(import(cities.map(&:id), deleted.map(&:id)))
271
+ .to eq([{ index: cities.first(3) }, { delete: [cities.last.id] + deleted.map(&:id) }])
272
+ end
273
+ specify do
274
+ expect(import(cities.map(&:id), deleted.map(&:id), batch_size: 3)).to eq([
275
+ { index: cities.first(3) },
276
+ { delete: [cities.last.id] + deleted.first(2).map(&:id) },
277
+ { delete: deleted.last(1).map(&:id) }
278
+ ])
279
+ end
214
280
  end
215
281
 
216
282
  context 'error handling' do
217
- let!(:cities) { 3.times.map { |i| City.create! } }
218
- let!(:deleted) { 2.times.map { |i| City.create!.tap(&:destroy) } }
283
+ let!(:cities) { Array.new(3) { City.create! } }
284
+ let!(:deleted) { Array.new(2) { City.create!.tap(&:destroy) } }
219
285
  let(:ids) { (cities + deleted).map(&:id) }
220
286
  subject { described_class.new(City) }
221
287
 
222
288
  let(:data_comparer) do
223
- ->(id, data) { objects = data[:index] || data[:delete]; !objects.map { |o| o.respond_to?(:id) ? o.id : o }.include?(id) }
289
+ lambda do |id, data|
290
+ objects = data[:index] || data[:delete]
291
+ !objects.map { |o| o.respond_to?(:id) ? o.id : o }.include?(id)
292
+ end
224
293
  end
225
294
 
226
295
  context 'implicit scope' do
227
- specify { expect(subject.import { |data| true }).to eq(true) }
228
- specify { expect(subject.import { |data| false }).to eq(false) }
296
+ specify { expect(subject.import { |_data| true }).to eq(true) }
297
+ specify { expect(subject.import { |_data| false }).to eq(false) }
229
298
  specify { expect(subject.import(batch_size: 1, &data_comparer.curry[cities[0].id])).to eq(false) }
230
299
  specify { expect(subject.import(batch_size: 1, &data_comparer.curry[cities[1].id])).to eq(false) }
231
300
  specify { expect(subject.import(batch_size: 1, &data_comparer.curry[cities[2].id])).to eq(false) }
@@ -236,8 +305,8 @@ describe Chewy::Type::Adapter::Sequel, :sequel do
236
305
  context 'explicit scope' do
237
306
  let(:scope) { City.where(id: ids) }
238
307
 
239
- specify { expect(subject.import(scope) { |data| true }).to eq(true) }
240
- specify { expect(subject.import(scope) { |data| false }).to eq(false) }
308
+ specify { expect(subject.import(scope) { |_data| true }).to eq(true) }
309
+ specify { expect(subject.import(scope) { |_data| false }).to eq(false) }
241
310
  specify { expect(subject.import(scope, batch_size: 1, &data_comparer.curry[cities[0].id])).to eq(false) }
242
311
  specify { expect(subject.import(scope, batch_size: 1, &data_comparer.curry[cities[1].id])).to eq(false) }
243
312
  specify { expect(subject.import(scope, batch_size: 1, &data_comparer.curry[cities[2].id])).to eq(false) }
@@ -246,8 +315,8 @@ describe Chewy::Type::Adapter::Sequel, :sequel do
246
315
  end
247
316
 
248
317
  context 'objects' do
249
- specify { expect(subject.import(cities + deleted) { |data| true }).to eq(true) }
250
- specify { expect(subject.import(cities + deleted) { |data| false }).to eq(false) }
318
+ specify { expect(subject.import(cities + deleted) { |_data| true }).to eq(true) }
319
+ specify { expect(subject.import(cities + deleted) { |_data| false }).to eq(false) }
251
320
  specify { expect(subject.import(cities + deleted, batch_size: 1, &data_comparer.curry[cities[0].id])).to eq(false) }
252
321
  specify { expect(subject.import(cities + deleted, batch_size: 1, &data_comparer.curry[cities[1].id])).to eq(false) }
253
322
  specify { expect(subject.import(cities + deleted, batch_size: 1, &data_comparer.curry[cities[2].id])).to eq(false) }
@@ -256,8 +325,8 @@ describe Chewy::Type::Adapter::Sequel, :sequel do
256
325
  end
257
326
 
258
327
  context 'ids' do
259
- specify { expect(subject.import(ids) { |data| true }).to eq(true) }
260
- specify { expect(subject.import(ids) { |data| false }).to eq(false) }
328
+ specify { expect(subject.import(ids) { |_data| true }).to eq(true) }
329
+ specify { expect(subject.import(ids) { |_data| false }).to eq(false) }
261
330
  specify { expect(subject.import(ids, batch_size: 1, &data_comparer.curry[cities[0].id])).to eq(false) }
262
331
  specify { expect(subject.import(ids, batch_size: 1, &data_comparer.curry[cities[1].id])).to eq(false) }
263
332
  specify { expect(subject.import(ids, batch_size: 1, &data_comparer.curry[cities[2].id])).to eq(false) }
@@ -269,8 +338,8 @@ describe Chewy::Type::Adapter::Sequel, :sequel do
269
338
 
270
339
  describe '#load' do
271
340
  context do
272
- let!(:cities) { 3.times.map { |i| City.create!(rating: i/2) } }
273
- let!(:deleted) { 2.times.map { |i| City.create!.tap(&:destroy) } }
341
+ let!(:cities) { Array.new(3) { |i| City.create!(rating: i / 2) } }
342
+ let!(:deleted) { Array.new(2) { City.create!.tap(&:destroy) } }
274
343
 
275
344
  let(:type) { double(type_name: 'user') }
276
345
 
@@ -280,22 +349,30 @@ describe Chewy::Type::Adapter::Sequel, :sequel do
280
349
  specify { expect(subject.load(cities.map { |c| double(id: c.id) }.reverse, _type: type)).to eq(cities.reverse) }
281
350
  specify { expect(subject.load(deleted.map { |c| double(id: c.id) }, _type: type)).to eq([nil, nil]) }
282
351
  specify { expect(subject.load((cities + deleted).map { |c| double(id: c.id) }, _type: type)).to eq([*cities, nil, nil]) }
283
- specify { expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: ->{ where(rating: 0) }))
284
- .to eq(cities.first(2) + [nil]) }
285
- specify { expect(subject.load(cities.map { |c| double(id: c.id) },
286
- _type: type, scope: ->{ where(rating: 0) }, user: {scope: ->{ where(rating: 1)}}))
287
- .to eq([nil, nil] + cities.last(1)) }
288
- xspecify { expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: City.where(rating: 1)))
289
- .to eq([nil, nil] + cities.last(1)) }
290
- specify { expect(subject.load(cities.map { |c| double(id: c.id) },
291
- _type: type, scope: City.where(rating: 1), user: {scope: ->{ where(rating: 0)}}))
292
- .to eq(cities.first(2) + [nil]) }
352
+ specify do
353
+ expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: -> { where(rating: 0) }))
354
+ .to eq(cities.first(2) + [nil])
355
+ end
356
+ specify do
357
+ expect(subject.load(cities.map { |c| double(id: c.id) },
358
+ _type: type, scope: -> { where(rating: 0) }, user: { scope: -> { where(rating: 1) } }))
359
+ .to eq([nil, nil] + cities.last(1))
360
+ end
361
+ xspecify do
362
+ expect(subject.load(cities.map { |c| double(id: c.id) }, _type: type, scope: City.where(rating: 1)))
363
+ .to eq([nil, nil] + cities.last(1))
364
+ end
365
+ specify do
366
+ expect(subject.load(cities.map { |c| double(id: c.id) },
367
+ _type: type, scope: City.where(rating: 1), user: { scope: -> { where(rating: 0) } }))
368
+ .to eq(cities.first(2) + [nil])
369
+ end
293
370
  end
294
371
 
295
372
  context 'custom primary_key' do
296
373
  before { stub_model(:city).set_dataset :rating_cities }
297
- let!(:cities) { 3.times.map { |i| City.create!(country_id: i/2) { |c| c.rating = i + 7 } } }
298
- let!(:deleted) { 2.times.map { |i| City.create! { |c| c.rating = i + 10 }.tap(&:destroy) } }
374
+ let!(:cities) { Array.new(3) { |i| City.create!(country_id: i / 2) { |c| c.rating = i + 7 } } }
375
+ let!(:deleted) { Array.new(2) { |i| City.create! { |c| c.rating = i + 10 }.tap(&:destroy) } }
299
376
 
300
377
  let(:type) { double(type_name: 'user') }
301
378
 
@@ -305,16 +382,24 @@ describe Chewy::Type::Adapter::Sequel, :sequel do
305
382
  specify { expect(subject.load(cities.map { |c| double(rating: c.rating) }.reverse, _type: type)).to eq(cities.reverse) }
306
383
  specify { expect(subject.load(deleted.map { |c| double(rating: c.rating) }, _type: type)).to eq([nil, nil]) }
307
384
  specify { expect(subject.load((cities + deleted).map { |c| double(rating: c.rating) }, _type: type)).to eq([*cities, nil, nil]) }
308
- specify { expect(subject.load(cities.map { |c| double(rating: c.rating) }, _type: type, scope: ->{ where(country_id: 0) }))
309
- .to eq(cities.first(2) + [nil]) }
310
- specify { expect(subject.load(cities.map { |c| double(rating: c.rating) },
311
- _type: type, scope: ->{ where(country_id: 0) }, user: {scope: ->{ where(country_id: 1)}}))
312
- .to eq([nil, nil] + cities.last(1)) }
313
- xspecify { expect(subject.load(cities.map { |c| double(rating: c.rating) }, _type: type, scope: City.where(country_id: 1)))
314
- .to eq([nil, nil] + cities.last(1)) }
315
- specify { expect(subject.load(cities.map { |c| double(rating: c.rating) },
316
- _type: type, scope: City.where(country_id: 1), user: {scope: ->{ where(country_id: 0)}}))
317
- .to eq(cities.first(2) + [nil]) }
385
+ specify do
386
+ expect(subject.load(cities.map { |c| double(rating: c.rating) }, _type: type, scope: -> { where(country_id: 0) }))
387
+ .to eq(cities.first(2) + [nil])
388
+ end
389
+ specify do
390
+ expect(subject.load(cities.map { |c| double(rating: c.rating) },
391
+ _type: type, scope: -> { where(country_id: 0) }, user: { scope: -> { where(country_id: 1) } }))
392
+ .to eq([nil, nil] + cities.last(1))
393
+ end
394
+ xspecify do
395
+ expect(subject.load(cities.map { |c| double(rating: c.rating) }, _type: type, scope: City.where(country_id: 1)))
396
+ .to eq([nil, nil] + cities.last(1))
397
+ end
398
+ specify do
399
+ expect(subject.load(cities.map { |c| double(rating: c.rating) },
400
+ _type: type, scope: City.where(country_id: 1), user: { scope: -> { where(country_id: 0) } }))
401
+ .to eq(cities.first(2) + [nil])
402
+ end
318
403
  end
319
404
  end
320
405
  end