mongoid_orderable 6.0.1 → 6.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -1
- data/lib/mongoid/orderable/{engine.rb → handlers/base.rb} +42 -81
- data/lib/mongoid/orderable/handlers/document.rb +24 -0
- data/lib/mongoid/orderable/handlers/document_embedded.rb +14 -0
- data/lib/mongoid/orderable/handlers/document_transactional.rb +35 -0
- data/lib/mongoid/orderable/handlers/transaction.rb +71 -0
- data/lib/mongoid/orderable/mixins/callbacks.rb +21 -7
- data/lib/mongoid/orderable/version.rb +1 -1
- data/lib/mongoid_orderable.rb +5 -1
- data/spec/integration/concurrency_spec.rb +232 -0
- data/spec/integration/customized_spec.rb +31 -0
- data/spec/integration/embedded_spec.rb +41 -0
- data/spec/integration/foreign_key_spec.rb +33 -0
- data/spec/integration/inherited_spec.rb +54 -0
- data/spec/integration/multiple_fields_spec.rb +554 -0
- data/spec/integration/multiple_scoped_spec.rb +63 -0
- data/spec/integration/no_indexed_spec.rb +23 -0
- data/spec/integration/scoped_spec.rb +151 -0
- data/spec/integration/simple_spec.rb +184 -0
- data/spec/integration/string_scoped_spec.rb +28 -0
- data/spec/integration/zero_based_spec.rb +161 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/support/models.rb +122 -0
- metadata +33 -5
- data/spec/mongoid/orderable_spec.rb +0 -1486
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe CustomizedOrderable do
|
4
|
+
|
5
|
+
shared_examples_for 'customized_orderable' do
|
6
|
+
|
7
|
+
it 'does not have default position field' do
|
8
|
+
expect(CustomizedOrderable.fields).not_to have_key('position')
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should have custom pos field' do
|
12
|
+
expect(CustomizedOrderable.fields).to have_key('pos')
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should have an alias my_position which points to pos field on Mongoid 3+' do
|
16
|
+
expect(CustomizedOrderable.database_field_name('my_position')).to eq('pos')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'with transactions' do
|
21
|
+
enable_transactions!
|
22
|
+
|
23
|
+
it_behaves_like 'customized_orderable'
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'without transactions' do
|
27
|
+
disable_transactions!
|
28
|
+
|
29
|
+
it_behaves_like 'customized_orderable'
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EmbeddedOrderable do
|
4
|
+
|
5
|
+
shared_examples_for 'embedded_orderable' do
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
eo = EmbedsOrderable.create!
|
9
|
+
2.times { eo.embedded_orderables.create! }
|
10
|
+
eo = EmbedsOrderable.create!
|
11
|
+
3.times { eo.embedded_orderables.create! }
|
12
|
+
end
|
13
|
+
|
14
|
+
def positions
|
15
|
+
EmbedsOrderable.order_by(position: 1).all.map { |eo| eo.embedded_orderables.map(&:position).sort }
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'sets proper position while creation' do
|
19
|
+
expect(positions).to eq([[1, 2], [1, 2, 3]])
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'moves an item returned by a query to position' do
|
23
|
+
embedded_orderable1 = EmbedsOrderable.first.embedded_orderables.where(position: 1).first
|
24
|
+
embedded_orderable2 = EmbedsOrderable.first.embedded_orderables.where(position: 2).first
|
25
|
+
embedded_orderable1.move_to! 2
|
26
|
+
expect(embedded_orderable2.reload.position).to eq(1)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'with transactions' do
|
31
|
+
enable_transactions!
|
32
|
+
|
33
|
+
it_behaves_like 'embedded_orderable'
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'without transactions' do
|
37
|
+
disable_transactions!
|
38
|
+
|
39
|
+
it_behaves_like 'embedded_orderable'
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ForeignKeyDiffersOrderable do
|
4
|
+
|
5
|
+
shared_examples_for 'foreign_key_orderable' do
|
6
|
+
|
7
|
+
it 'uses the foreign key of the relationship as scope' do
|
8
|
+
orderable1, orderable2, orderable3 = nil
|
9
|
+
parent_scope1 = ForeignKeyDiffersOrderable.create
|
10
|
+
parent_scope2 = ForeignKeyDiffersOrderable.create
|
11
|
+
expect do
|
12
|
+
orderable1 = ForeignKeyDiffersOrderable.create!(different_scope: parent_scope1)
|
13
|
+
orderable2 = ForeignKeyDiffersOrderable.create!(different_scope: parent_scope1)
|
14
|
+
orderable3 = ForeignKeyDiffersOrderable.create!(different_scope: parent_scope2)
|
15
|
+
end.to_not raise_error
|
16
|
+
expect(orderable1.position).to eq 1
|
17
|
+
expect(orderable2.position).to eq 2
|
18
|
+
expect(orderable3.position).to eq 1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'with transactions' do
|
23
|
+
enable_transactions!
|
24
|
+
|
25
|
+
it_behaves_like 'foreign_key_orderable'
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'without transactions' do
|
29
|
+
disable_transactions!
|
30
|
+
|
31
|
+
it_behaves_like 'foreign_key_orderable'
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe InheritedOrderable do
|
4
|
+
|
5
|
+
shared_examples_for 'inherited_orderable' do
|
6
|
+
|
7
|
+
it 'should set proper position' do
|
8
|
+
fruit1 = Apple.create
|
9
|
+
fruit2 = Orange.create
|
10
|
+
expect(fruit1.position).to eq(1)
|
11
|
+
expect(fruit2.position).to eq(2)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'movement' do
|
15
|
+
before :each do
|
16
|
+
5.times { Apple.create! }
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'with symbol position' do
|
20
|
+
first_apple = Apple.asc(:_id).first
|
21
|
+
top_pos = first_apple.position
|
22
|
+
bottom_pos = Apple.asc(:_id).last.position
|
23
|
+
expect { first_apple.move_to!(:bottom) }.to change(first_apple, :position).from(top_pos).to bottom_pos
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'with point position' do
|
27
|
+
first_apple = Apple.asc(:_id).first
|
28
|
+
top_pos = first_apple.position
|
29
|
+
bottom_pos = Apple.asc(:_id).last.position
|
30
|
+
expect { first_apple.move_to!(bottom_pos) }.to change(first_apple, :position).from(top_pos).to bottom_pos
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'add orderable configs in inherited class' do
|
35
|
+
it 'does not affect the orderable configs of parent class and sibling class' do
|
36
|
+
expect(InheritedOrderable.orderable_configs).not_to eq Apple.orderable_configs
|
37
|
+
expect(Orange.orderable_configs).not_to eq Apple.orderable_configs
|
38
|
+
expect(InheritedOrderable.orderable_configs).to eq Orange.orderable_configs
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'with transactions' do
|
44
|
+
enable_transactions!
|
45
|
+
|
46
|
+
it_behaves_like 'inherited_orderable'
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'without transactions' do
|
50
|
+
disable_transactions!
|
51
|
+
|
52
|
+
it_behaves_like 'inherited_orderable'
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,554 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MultipleFieldsOrderable do
|
4
|
+
|
5
|
+
shared_examples_for 'multiple_fields_orderable' do
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
5.times { MultipleFieldsOrderable.create! }
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'default orderable' do
|
12
|
+
let(:serial_nos) { MultipleFieldsOrderable.pluck(:serial_no).sort }
|
13
|
+
|
14
|
+
describe 'inserting' do
|
15
|
+
let(:newbie) { MultipleFieldsOrderable.create! }
|
16
|
+
|
17
|
+
before { @position = newbie.position }
|
18
|
+
|
19
|
+
it 'top' do
|
20
|
+
newbie.move_to! :top
|
21
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5, 6])
|
22
|
+
expect(newbie.serial_no).to eq(1)
|
23
|
+
expect(newbie.position).to eq(@position)
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'bottom' do
|
27
|
+
newbie.move_to! :bottom
|
28
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5, 6])
|
29
|
+
expect(newbie.serial_no).to eq(6)
|
30
|
+
expect(newbie.position).to eq(@position)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'middle' do
|
34
|
+
newbie.move_to! 4
|
35
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5, 6])
|
36
|
+
expect(newbie.serial_no).to eq(4)
|
37
|
+
expect(newbie.position).to eq(@position)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'movement' do
|
42
|
+
it 'higher from top' do
|
43
|
+
record = MultipleFieldsOrderable.where(serial_no: 1).first
|
44
|
+
position = record.position
|
45
|
+
record.move_higher!
|
46
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5])
|
47
|
+
expect(record.serial_no).to eq(1)
|
48
|
+
expect(record.position).to eq(position)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'higher from bottom' do
|
52
|
+
record = MultipleFieldsOrderable.where(serial_no: 5).first
|
53
|
+
position = record.position
|
54
|
+
record.move_higher!
|
55
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5])
|
56
|
+
expect(record.serial_no).to eq(4)
|
57
|
+
expect(record.position).to eq(position)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'higher from middle' do
|
61
|
+
record = MultipleFieldsOrderable.where(serial_no: 3).first
|
62
|
+
position = record.position
|
63
|
+
record.move_higher!
|
64
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5])
|
65
|
+
expect(record.serial_no).to eq(2)
|
66
|
+
expect(record.position).to eq(position)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'lower from top' do
|
70
|
+
record = MultipleFieldsOrderable.where(serial_no: 1).first
|
71
|
+
position = record.position
|
72
|
+
record.move_lower!
|
73
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5])
|
74
|
+
expect(record.serial_no).to eq(2)
|
75
|
+
expect(record.position).to eq(position)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'lower from bottom' do
|
79
|
+
record = MultipleFieldsOrderable.where(serial_no: 5).first
|
80
|
+
position = record.position
|
81
|
+
record.move_lower!
|
82
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5])
|
83
|
+
expect(record.serial_no).to eq(5)
|
84
|
+
expect(record.position).to eq(position)
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'lower from middle' do
|
88
|
+
record = MultipleFieldsOrderable.where(serial_no: 3).first
|
89
|
+
position = record.position
|
90
|
+
record.move_lower!
|
91
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5])
|
92
|
+
expect(record.serial_no).to eq(4)
|
93
|
+
expect(record.position).to eq(position)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe 'utility methods' do
|
98
|
+
before do
|
99
|
+
@record1 = MultipleFieldsOrderable.where(serial_no: 1).first
|
100
|
+
@record2 = MultipleFieldsOrderable.where(serial_no: 2).first
|
101
|
+
@record3 = MultipleFieldsOrderable.where(serial_no: 3).first
|
102
|
+
@record4 = MultipleFieldsOrderable.where(serial_no: 4).first
|
103
|
+
@record5 = MultipleFieldsOrderable.where(serial_no: 5).first
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should return the lower/higher item on the list for next_item/previous_item' do
|
107
|
+
expect(@record1.next_item).to eq(@record2)
|
108
|
+
expect(@record3.next_item).to eq(@record4)
|
109
|
+
expect(@record5.next_item).to eq(nil)
|
110
|
+
expect(@record1.prev_item).to eq(nil)
|
111
|
+
expect(@record3.prev_item).to eq(@record2)
|
112
|
+
expect(@record5.prev_item).to eq(@record4)
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should return a collection of items lower/higher on the list for next_items/previous_items' do
|
116
|
+
expect(@record1.next_items.to_a).to eq([@record2, @record3, @record4, @record5])
|
117
|
+
expect(@record3.next_items.to_a).to eq([@record4, @record5])
|
118
|
+
expect(@record5.next_items.to_a).to eq([])
|
119
|
+
expect(@record1.previous_items.to_a).to eq([])
|
120
|
+
expect(@record3.previous_items.to_a).to eq([@record1, @record2])
|
121
|
+
expect(@record5.previous_items.to_a).to eq([@record1, @record2, @record3, @record4])
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context 'serial_no orderable' do
|
127
|
+
let(:serial_nos) { MultipleFieldsOrderable.pluck(:serial_no).sort }
|
128
|
+
|
129
|
+
it 'should have proper serial_no field' do
|
130
|
+
expect(MultipleFieldsOrderable.fields.key?('serial_no')).to be true
|
131
|
+
expect(MultipleFieldsOrderable.fields['serial_no'].options[:type]).to eq(Integer)
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'should have index on serial_no field' do
|
135
|
+
expect(MultipleFieldsOrderable.index_specifications.detect { |spec| spec.key == { serial_no: 1 } }).not_to be_nil
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'should have a orderable base of 1' do
|
139
|
+
expect(MultipleFieldsOrderable.first.orderable_top(:serial_no)).to eq(1)
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'should set proper position while creation' do
|
143
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5])
|
144
|
+
end
|
145
|
+
|
146
|
+
describe 'removement' do
|
147
|
+
it 'top' do
|
148
|
+
MultipleFieldsOrderable.where(serial_no: 1).destroy
|
149
|
+
expect(serial_nos).to eq([1, 2, 3, 4])
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'bottom' do
|
153
|
+
MultipleFieldsOrderable.where(serial_no: 5).destroy
|
154
|
+
expect(serial_nos).to eq([1, 2, 3, 4])
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'middle' do
|
158
|
+
MultipleFieldsOrderable.where(serial_no: 3).destroy
|
159
|
+
expect(serial_nos).to eq([1, 2, 3, 4])
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe 'inserting' do
|
164
|
+
let(:newbie) { MultipleFieldsOrderable.create! }
|
165
|
+
|
166
|
+
before { @position = newbie.position }
|
167
|
+
|
168
|
+
it 'top' do
|
169
|
+
newbie.move_serial_no_to! :top
|
170
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5, 6])
|
171
|
+
expect(newbie.serial_no).to eq(1)
|
172
|
+
expect(newbie.position).to eq(@position)
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'bottom' do
|
176
|
+
newbie.move_serial_no_to! :bottom
|
177
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5, 6])
|
178
|
+
expect(newbie.serial_no).to eq(6)
|
179
|
+
expect(newbie.position).to eq(@position)
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'middle' do
|
183
|
+
newbie.move_serial_no_to! 4
|
184
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5, 6])
|
185
|
+
expect(newbie.serial_no).to eq(4)
|
186
|
+
expect(newbie.position).to eq(@position)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe 'movement' do
|
191
|
+
it 'higher from top' do
|
192
|
+
record = MultipleFieldsOrderable.where(serial_no: 1).first
|
193
|
+
position = record.position
|
194
|
+
record.move_serial_no_higher!
|
195
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5])
|
196
|
+
expect(record.serial_no).to eq(1)
|
197
|
+
expect(record.position).to eq(position)
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'higher from bottom' do
|
201
|
+
record = MultipleFieldsOrderable.where(serial_no: 5).first
|
202
|
+
position = record.position
|
203
|
+
record.move_serial_no_higher!
|
204
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5])
|
205
|
+
expect(record.serial_no).to eq(4)
|
206
|
+
expect(record.position).to eq(position)
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'higher from middle' do
|
210
|
+
record = MultipleFieldsOrderable.where(serial_no: 3).first
|
211
|
+
position = record.position
|
212
|
+
record.move_serial_no_higher!
|
213
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5])
|
214
|
+
expect(record.serial_no).to eq(2)
|
215
|
+
expect(record.position).to eq(position)
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'lower from top' do
|
219
|
+
record = MultipleFieldsOrderable.where(serial_no: 1).first
|
220
|
+
position = record.position
|
221
|
+
record.move_serial_no_lower!
|
222
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5])
|
223
|
+
expect(record.serial_no).to eq(2)
|
224
|
+
expect(record.position).to eq(position)
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'lower from bottom' do
|
228
|
+
record = MultipleFieldsOrderable.where(serial_no: 5).first
|
229
|
+
position = record.position
|
230
|
+
record.move_serial_no_lower!
|
231
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5])
|
232
|
+
expect(record.serial_no).to eq(5)
|
233
|
+
expect(record.position).to eq(position)
|
234
|
+
end
|
235
|
+
|
236
|
+
it 'lower from middle' do
|
237
|
+
record = MultipleFieldsOrderable.where(serial_no: 3).first
|
238
|
+
position = record.position
|
239
|
+
record.move_serial_no_lower!
|
240
|
+
expect(serial_nos).to eq([1, 2, 3, 4, 5])
|
241
|
+
expect(record.serial_no).to eq(4)
|
242
|
+
expect(record.position).to eq(position)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
describe 'utility methods' do
|
247
|
+
before do
|
248
|
+
@record1 = MultipleFieldsOrderable.where(serial_no: 1).first
|
249
|
+
@record2 = MultipleFieldsOrderable.where(serial_no: 2).first
|
250
|
+
@record3 = MultipleFieldsOrderable.where(serial_no: 3).first
|
251
|
+
@record4 = MultipleFieldsOrderable.where(serial_no: 4).first
|
252
|
+
@record5 = MultipleFieldsOrderable.where(serial_no: 5).first
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'should return the lower/higher item on the list for next_item/previous_item' do
|
256
|
+
expect(@record1.next_serial_no_item).to eq(@record2)
|
257
|
+
expect(@record3.next_serial_no_item).to eq(@record4)
|
258
|
+
expect(@record5.next_serial_no_item).to eq(nil)
|
259
|
+
expect(@record1.prev_serial_no_item).to eq(nil)
|
260
|
+
expect(@record3.prev_serial_no_item).to eq(@record2)
|
261
|
+
expect(@record5.prev_serial_no_item).to eq(@record4)
|
262
|
+
end
|
263
|
+
|
264
|
+
it 'should return a collection of items lower/higher on the list for next_items/previous_items' do
|
265
|
+
expect(@record1.next_serial_no_items.to_a).to eq([@record2, @record3, @record4, @record5])
|
266
|
+
expect(@record3.next_serial_no_items.to_a).to eq([@record4, @record5])
|
267
|
+
expect(@record5.next_serial_no_items.to_a).to eq([])
|
268
|
+
expect(@record1.previous_serial_no_items.to_a).to eq([])
|
269
|
+
expect(@record3.previous_serial_no_items.to_a).to eq([@record1, @record2])
|
270
|
+
expect(@record5.previous_serial_no_items.to_a).to eq([@record1, @record2, @record3, @record4])
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
context 'position orderable' do
|
276
|
+
let(:positions) { MultipleFieldsOrderable.pluck(:position).sort }
|
277
|
+
|
278
|
+
it 'should not have default position field' do
|
279
|
+
expect(MultipleFieldsOrderable.fields).not_to have_key('position')
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'should have custom pos field' do
|
283
|
+
expect(MultipleFieldsOrderable.fields).to have_key('pos')
|
284
|
+
expect(MultipleFieldsOrderable.fields['pos'].options[:type]).to eq(Integer)
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'should have index on position field' do
|
288
|
+
expect(MultipleFieldsOrderable.index_specifications.detect { |spec| spec.key == { position: 1 } }).to be_nil
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'should have a orderable base of 0' do
|
292
|
+
expect(MultipleFieldsOrderable.first.orderable_top(:position)).to eq(0)
|
293
|
+
end
|
294
|
+
|
295
|
+
it 'should set proper position while creation' do
|
296
|
+
expect(positions).to eq([0, 1, 2, 3, 4])
|
297
|
+
end
|
298
|
+
|
299
|
+
describe 'removement' do
|
300
|
+
it 'top' do
|
301
|
+
MultipleFieldsOrderable.where(pos: 1).destroy
|
302
|
+
expect(positions).to eq([0, 1, 2, 3])
|
303
|
+
end
|
304
|
+
|
305
|
+
it 'bottom' do
|
306
|
+
MultipleFieldsOrderable.where(pos: 4).destroy
|
307
|
+
expect(positions).to eq([0, 1, 2, 3])
|
308
|
+
end
|
309
|
+
|
310
|
+
it 'middle' do
|
311
|
+
MultipleFieldsOrderable.where(pos: 3).destroy
|
312
|
+
expect(positions).to eq([0, 1, 2, 3])
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
describe 'inserting' do
|
317
|
+
let(:newbie) { MultipleFieldsOrderable.create! }
|
318
|
+
|
319
|
+
before { @serial_no = newbie.serial_no }
|
320
|
+
|
321
|
+
it 'top' do
|
322
|
+
newbie.move_position_to! :top
|
323
|
+
expect(positions).to eq([0, 1, 2, 3, 4, 5])
|
324
|
+
expect(newbie.position).to eq(0)
|
325
|
+
expect(newbie.serial_no).to eq(@serial_no)
|
326
|
+
end
|
327
|
+
|
328
|
+
it 'bottom' do
|
329
|
+
newbie.move_position_to! :bottom
|
330
|
+
expect(positions).to eq([0, 1, 2, 3, 4, 5])
|
331
|
+
expect(newbie.position).to eq(5)
|
332
|
+
expect(newbie.serial_no).to eq(@serial_no)
|
333
|
+
end
|
334
|
+
|
335
|
+
it 'middle' do
|
336
|
+
newbie.move_position_to! 4
|
337
|
+
expect(positions).to eq([0, 1, 2, 3, 4, 5])
|
338
|
+
expect(newbie.position).to eq(4)
|
339
|
+
expect(newbie.serial_no).to eq(@serial_no)
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
describe 'movement' do
|
344
|
+
it 'higher from top' do
|
345
|
+
record = MultipleFieldsOrderable.where(pos: 0).first
|
346
|
+
position = record.serial_no
|
347
|
+
record.move_position_higher!
|
348
|
+
expect(positions).to eq([0, 1, 2, 3, 4])
|
349
|
+
expect(record.position).to eq(0)
|
350
|
+
expect(record.serial_no).to eq(position)
|
351
|
+
end
|
352
|
+
|
353
|
+
it 'higher from bottom' do
|
354
|
+
record = MultipleFieldsOrderable.where(pos: 4).first
|
355
|
+
position = record.serial_no
|
356
|
+
record.move_position_higher!
|
357
|
+
expect(positions).to eq([0, 1, 2, 3, 4])
|
358
|
+
expect(record.position).to eq(3)
|
359
|
+
expect(record.serial_no).to eq(position)
|
360
|
+
end
|
361
|
+
|
362
|
+
it 'higher from middle' do
|
363
|
+
record = MultipleFieldsOrderable.where(pos: 3).first
|
364
|
+
position = record.serial_no
|
365
|
+
record.move_position_higher!
|
366
|
+
expect(positions).to eq([0, 1, 2, 3, 4])
|
367
|
+
expect(record.position).to eq(2)
|
368
|
+
expect(record.serial_no).to eq(position)
|
369
|
+
end
|
370
|
+
|
371
|
+
it 'lower from top' do
|
372
|
+
record = MultipleFieldsOrderable.where(pos: 0).first
|
373
|
+
position = record.serial_no
|
374
|
+
record.move_position_lower!
|
375
|
+
expect(positions).to eq([0, 1, 2, 3, 4])
|
376
|
+
expect(record.position).to eq(1)
|
377
|
+
expect(record.serial_no).to eq(position)
|
378
|
+
end
|
379
|
+
|
380
|
+
it 'lower from bottom' do
|
381
|
+
record = MultipleFieldsOrderable.where(pos: 4).first
|
382
|
+
position = record.serial_no
|
383
|
+
record.move_position_lower!
|
384
|
+
expect(positions).to eq([0, 1, 2, 3, 4])
|
385
|
+
expect(record.position).to eq(4)
|
386
|
+
expect(record.serial_no).to eq(position)
|
387
|
+
end
|
388
|
+
|
389
|
+
it 'lower from middle' do
|
390
|
+
record = MultipleFieldsOrderable.where(pos: 3).first
|
391
|
+
position = record.serial_no
|
392
|
+
record.move_position_lower!
|
393
|
+
expect(positions).to eq([0, 1, 2, 3, 4])
|
394
|
+
expect(record.position).to eq(4)
|
395
|
+
expect(record.serial_no).to eq(position)
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
describe 'utility methods' do
|
400
|
+
before do
|
401
|
+
@record1 = MultipleFieldsOrderable.where(pos: 0).first
|
402
|
+
@record2 = MultipleFieldsOrderable.where(pos: 1).first
|
403
|
+
@record3 = MultipleFieldsOrderable.where(pos: 2).first
|
404
|
+
@record4 = MultipleFieldsOrderable.where(pos: 3).first
|
405
|
+
@record5 = MultipleFieldsOrderable.where(pos: 4).first
|
406
|
+
end
|
407
|
+
|
408
|
+
it 'should return the lower/higher item on the list for next_item/previous_item' do
|
409
|
+
expect(@record1.next_position_item).to eq(@record2)
|
410
|
+
expect(@record3.next_position_item).to eq(@record4)
|
411
|
+
expect(@record5.next_position_item).to eq(nil)
|
412
|
+
expect(@record1.prev_position_item).to eq(nil)
|
413
|
+
expect(@record3.prev_position_item).to eq(@record2)
|
414
|
+
expect(@record5.prev_position_item).to eq(@record4)
|
415
|
+
end
|
416
|
+
|
417
|
+
it 'should return a collection of items lower/higher on the list for next_items/previous_items' do
|
418
|
+
expect(@record1.next_position_items.to_a).to eq([@record2, @record3, @record4, @record5])
|
419
|
+
expect(@record3.next_position_items.to_a).to eq([@record4, @record5])
|
420
|
+
expect(@record5.next_position_items.to_a).to eq([])
|
421
|
+
expect(@record1.previous_position_items.to_a).to eq([])
|
422
|
+
expect(@record3.previous_position_items.to_a).to eq([@record1, @record2])
|
423
|
+
expect(@record5.previous_position_items.to_a).to eq([@record1, @record2, @record3, @record4])
|
424
|
+
end
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
context 'group_count orderable' do
|
429
|
+
before :each do
|
430
|
+
MultipleFieldsOrderable.delete_all
|
431
|
+
2.times { MultipleFieldsOrderable.create! group_id: 1 }
|
432
|
+
3.times { MultipleFieldsOrderable.create! group_id: 2 }
|
433
|
+
end
|
434
|
+
|
435
|
+
let(:all_groups) { MultipleFieldsOrderable.order_by([:group_id, :asc], [:groups, :asc]).map(&:groups) }
|
436
|
+
|
437
|
+
it 'should set proper position while creation' do
|
438
|
+
expect(all_groups).to eq([1, 2, 1, 2, 3])
|
439
|
+
end
|
440
|
+
|
441
|
+
describe 'removement' do
|
442
|
+
it 'top' do
|
443
|
+
MultipleFieldsOrderable.where(groups: 1, group_id: 1).destroy
|
444
|
+
expect(all_groups).to eq([1, 1, 2, 3])
|
445
|
+
end
|
446
|
+
|
447
|
+
it 'bottom' do
|
448
|
+
MultipleFieldsOrderable.where(groups: 3, group_id: 2).destroy
|
449
|
+
expect(all_groups).to eq([1, 2, 1, 2])
|
450
|
+
end
|
451
|
+
|
452
|
+
it 'middle' do
|
453
|
+
MultipleFieldsOrderable.where(groups: 2, group_id: 2).destroy
|
454
|
+
expect(all_groups).to eq([1, 2, 1, 2])
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
describe 'inserting' do
|
459
|
+
it 'top' do
|
460
|
+
newbie = MultipleFieldsOrderable.create! group_id: 1
|
461
|
+
newbie.move_groups_to! :top
|
462
|
+
expect(all_groups).to eq([1, 2, 3, 1, 2, 3])
|
463
|
+
expect(newbie.groups).to eq(1)
|
464
|
+
end
|
465
|
+
|
466
|
+
it 'bottom' do
|
467
|
+
newbie = MultipleFieldsOrderable.create! group_id: 2
|
468
|
+
newbie.move_groups_to! :bottom
|
469
|
+
expect(all_groups).to eq([1, 2, 1, 2, 3, 4])
|
470
|
+
expect(newbie.groups).to eq(4)
|
471
|
+
end
|
472
|
+
|
473
|
+
it 'middle' do
|
474
|
+
newbie = MultipleFieldsOrderable.create! group_id: 2
|
475
|
+
newbie.move_groups_to! 2
|
476
|
+
expect(all_groups).to eq([1, 2, 1, 2, 3, 4])
|
477
|
+
expect(newbie.groups).to eq(2)
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
481
|
+
describe 'scope movement' do
|
482
|
+
let(:record) { MultipleFieldsOrderable.where(group_id: 2, groups: 2).first }
|
483
|
+
|
484
|
+
it 'to a new scope group' do
|
485
|
+
record.update_attributes group_id: 3
|
486
|
+
expect(all_groups).to eq([1, 2, 1, 2, 1])
|
487
|
+
expect(record.groups).to eq(1)
|
488
|
+
end
|
489
|
+
|
490
|
+
context 'when moving to an existing scope group' do
|
491
|
+
it 'without a position' do
|
492
|
+
record.update_attributes group_id: 1
|
493
|
+
expect(all_groups).to eq([1, 2, 3, 1, 2])
|
494
|
+
expect(record.reload.groups).to eq(3)
|
495
|
+
end
|
496
|
+
|
497
|
+
it 'with symbol position' do
|
498
|
+
record.update_attributes group_id: 1
|
499
|
+
record.move_groups_to! :top
|
500
|
+
expect(all_groups).to eq([1, 2, 3, 1, 2])
|
501
|
+
expect(record.reload.groups).to eq(1)
|
502
|
+
end
|
503
|
+
|
504
|
+
it 'with point position' do
|
505
|
+
record.update_attributes group_id: 1
|
506
|
+
record.move_groups_to! 2
|
507
|
+
expect(all_groups).to eq([1, 2, 3, 1, 2])
|
508
|
+
expect(record.reload.groups).to eq(2)
|
509
|
+
end
|
510
|
+
end
|
511
|
+
end
|
512
|
+
|
513
|
+
describe 'utility methods' do
|
514
|
+
before do
|
515
|
+
@record1 = MultipleFieldsOrderable.where(group_id: 2, groups: 1).first
|
516
|
+
@record2 = MultipleFieldsOrderable.where(group_id: 2, groups: 2).first
|
517
|
+
@record3 = MultipleFieldsOrderable.where(group_id: 2, groups: 3).first
|
518
|
+
@record4 = MultipleFieldsOrderable.where(group_id: 1, groups: 1).first
|
519
|
+
@record5 = MultipleFieldsOrderable.where(group_id: 1, groups: 2).first
|
520
|
+
end
|
521
|
+
|
522
|
+
it 'should return the lower/higher item on the list for next_item/previous_item' do
|
523
|
+
expect(@record1.next_groups_item).to eq(@record2)
|
524
|
+
expect(@record4.next_groups_item).to eq(@record5)
|
525
|
+
expect(@record3.next_groups_item).to eq(nil)
|
526
|
+
expect(@record1.prev_groups_item).to eq(nil)
|
527
|
+
expect(@record3.prev_groups_item).to eq(@record2)
|
528
|
+
expect(@record5.prev_groups_item).to eq(@record4)
|
529
|
+
end
|
530
|
+
|
531
|
+
it 'should return a collection of items lower/higher on the list for next_items/previous_items' do
|
532
|
+
expect(@record1.next_groups_items.to_a).to eq([@record2, @record3])
|
533
|
+
expect(@record3.next_groups_items.to_a).to eq([])
|
534
|
+
expect(@record4.next_groups_items.to_a).to eq([@record5])
|
535
|
+
expect(@record1.previous_groups_items.to_a).to eq([])
|
536
|
+
expect(@record3.previous_groups_items.to_a).to eq([@record1, @record2])
|
537
|
+
expect(@record5.previous_groups_items.to_a).to eq([@record4])
|
538
|
+
end
|
539
|
+
end
|
540
|
+
end
|
541
|
+
end
|
542
|
+
|
543
|
+
context 'with transactions' do
|
544
|
+
enable_transactions!
|
545
|
+
|
546
|
+
it_behaves_like 'multiple_fields_orderable'
|
547
|
+
end
|
548
|
+
|
549
|
+
context 'without transactions' do
|
550
|
+
disable_transactions!
|
551
|
+
|
552
|
+
it_behaves_like 'multiple_fields_orderable'
|
553
|
+
end
|
554
|
+
end
|