mongoid_orderable 6.0.3 → 6.0.5
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 +13 -2
- data/lib/mongoid/orderable/configs/field_config.rb +1 -1
- data/lib/mongoid/orderable/generators/base.rb +1 -1
- data/lib/mongoid/orderable/generators/listable.rb +1 -1
- data/lib/mongoid/orderable/generators/lock_collection.rb +1 -1
- data/lib/mongoid/orderable/generators/movable.rb +1 -1
- data/lib/mongoid/orderable/generators/position.rb +3 -3
- data/lib/mongoid/orderable/generators/scope.rb +1 -1
- data/lib/mongoid/orderable/handlers/base.rb +32 -6
- data/lib/mongoid/orderable/handlers/document.rb +9 -1
- data/lib/mongoid/orderable/handlers/document_transactional.rb +3 -6
- data/lib/mongoid/orderable/handlers/transaction.rb +6 -2
- data/lib/mongoid/orderable/installer.rb +2 -1
- data/lib/mongoid/orderable/mixins/callbacks.rb +3 -1
- data/lib/mongoid/orderable/mixins/cascadeable.rb +15 -0
- data/lib/mongoid/orderable/mixins/movable.rb +7 -3
- data/lib/mongoid/orderable/version.rb +1 -1
- data/lib/mongoid_orderable.rb +2 -2
- metadata +10 -94
- data/spec/integration/concurrency_spec.rb +0 -232
- data/spec/integration/conditional_spec.rb +0 -36
- data/spec/integration/customized_spec.rb +0 -31
- data/spec/integration/embedded_spec.rb +0 -41
- data/spec/integration/foreign_key_spec.rb +0 -33
- data/spec/integration/inherited_spec.rb +0 -54
- data/spec/integration/multiple_fields_spec.rb +0 -554
- data/spec/integration/multiple_scoped_spec.rb +0 -63
- data/spec/integration/no_indexed_spec.rb +0 -23
- data/spec/integration/scoped_spec.rb +0 -151
- data/spec/integration/simple_spec.rb +0 -184
- data/spec/integration/string_scoped_spec.rb +0 -28
- data/spec/integration/zero_based_spec.rb +0 -161
- data/spec/spec_helper.rb +0 -42
- data/spec/support/models.rb +0 -134
@@ -1,151 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ScopedOrderable do
|
4
|
-
|
5
|
-
shared_examples_for 'scoped_orderable' do
|
6
|
-
|
7
|
-
def positions
|
8
|
-
ScopedOrderable.order_by([:group_id, :asc], [:position, :asc]).map(&:position)
|
9
|
-
end
|
10
|
-
|
11
|
-
before :each do
|
12
|
-
2.times { ScopedOrderable.create! group_id: 1 }
|
13
|
-
3.times { ScopedOrderable.create! group_id: 2 }
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'should set proper position while creation' do
|
17
|
-
expect(positions).to eq([1, 2, 1, 2, 3])
|
18
|
-
end
|
19
|
-
|
20
|
-
describe 'removement' do
|
21
|
-
it 'top' do
|
22
|
-
ScopedOrderable.where(position: 1, group_id: 1).destroy
|
23
|
-
expect(positions).to eq([1, 1, 2, 3])
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'bottom' do
|
27
|
-
ScopedOrderable.where(position: 3, group_id: 2).destroy
|
28
|
-
expect(positions).to eq([1, 2, 1, 2])
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'middle' do
|
32
|
-
ScopedOrderable.where(position: 2, group_id: 2).destroy
|
33
|
-
expect(positions).to eq([1, 2, 1, 2])
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
describe 'inserting' do
|
38
|
-
it 'top' do
|
39
|
-
newbie = ScopedOrderable.create! move_to: :top, group_id: 1
|
40
|
-
expect(positions).to eq([1, 2, 3, 1, 2, 3])
|
41
|
-
expect(newbie.position).to eq(1)
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'bottom' do
|
45
|
-
newbie = ScopedOrderable.create! move_to: :bottom, group_id: 2
|
46
|
-
expect(positions).to eq([1, 2, 1, 2, 3, 4])
|
47
|
-
expect(newbie.position).to eq(4)
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'middle' do
|
51
|
-
newbie = ScopedOrderable.create! move_to: 2, group_id: 2
|
52
|
-
expect(positions).to eq([1, 2, 1, 2, 3, 4])
|
53
|
-
expect(newbie.position).to eq(2)
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'middle (with a numeric string)' do
|
57
|
-
newbie = ScopedOrderable.create! move_to: '2', group_id: 2
|
58
|
-
expect(positions).to eq([1, 2, 1, 2, 3, 4])
|
59
|
-
expect(newbie.position).to eq(2)
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'middle (with a non-numeric string)' do
|
63
|
-
expect do
|
64
|
-
ScopedOrderable.create! move_to: 'two', group_id: 2
|
65
|
-
end.to raise_error Mongoid::Orderable::Errors::InvalidTargetPosition
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
describe 'index' do
|
70
|
-
it 'is not on position alone' do
|
71
|
-
expect(ScopedOrderable.index_specifications.detect { |spec| spec.key == { position: 1 } }).to be_nil
|
72
|
-
end
|
73
|
-
|
74
|
-
it 'is on compound fields' do
|
75
|
-
expect(ScopedOrderable.index_specifications.detect { |spec| spec.key == { group_id: 1, position: 1 } }).to_not be_nil
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
describe 'scope movement' do
|
80
|
-
let(:record) { ScopedOrderable.where(group_id: 2, position: 2).first }
|
81
|
-
|
82
|
-
it 'to a new scope group' do
|
83
|
-
record.update_attributes group_id: 3
|
84
|
-
expect(positions).to eq([1, 2, 1, 2, 1])
|
85
|
-
expect(record.position).to eq(1)
|
86
|
-
end
|
87
|
-
|
88
|
-
context 'when moving to an existing scope group' do
|
89
|
-
it 'without a position' do
|
90
|
-
record.update_attributes group_id: 1
|
91
|
-
expect(positions).to eq([1, 2, 3, 1, 2])
|
92
|
-
expect(record.reload.position).to eq(3)
|
93
|
-
end
|
94
|
-
|
95
|
-
it 'with symbol position' do
|
96
|
-
record.update_attributes group_id: 1, move_to: :top
|
97
|
-
expect(positions).to eq([1, 2, 3, 1, 2])
|
98
|
-
expect(record.reload.position).to eq(1)
|
99
|
-
end
|
100
|
-
|
101
|
-
it 'with point position' do
|
102
|
-
record.update_attributes group_id: 1, move_to: 2
|
103
|
-
expect(positions).to eq([1, 2, 3, 1, 2])
|
104
|
-
expect(record.reload.position).to eq(2)
|
105
|
-
end
|
106
|
-
|
107
|
-
it 'with point position (with a numeric string)' do
|
108
|
-
record.update_attributes group_id: 1, move_to: '2'
|
109
|
-
expect(positions).to eq([1, 2, 3, 1, 2])
|
110
|
-
expect(record.reload.position).to eq(2)
|
111
|
-
end
|
112
|
-
|
113
|
-
it 'with point position (with a non-numeric string)' do
|
114
|
-
expect do
|
115
|
-
record.update_attributes group_id: 1, move_to: 'two'
|
116
|
-
end.to raise_error Mongoid::Orderable::Errors::InvalidTargetPosition
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
describe 'utility methods' do
|
122
|
-
it 'should return a collection of items lower/higher on the list for next_items/previous_items' do
|
123
|
-
record1 = ScopedOrderable.where(group_id: 1, position: 1).first
|
124
|
-
record2 = ScopedOrderable.where(group_id: 1, position: 2).first
|
125
|
-
record3 = ScopedOrderable.where(group_id: 2, position: 1).first
|
126
|
-
record4 = ScopedOrderable.where(group_id: 2, position: 2).first
|
127
|
-
record5 = ScopedOrderable.where(group_id: 2, position: 3).first
|
128
|
-
expect(record1.next_items.to_a).to eq([record2])
|
129
|
-
expect(record5.previous_items.to_a).to eq([record3, record4])
|
130
|
-
expect(record3.previous_items.to_a).to eq([])
|
131
|
-
expect(record3.next_items.to_a).to eq([record4, record5])
|
132
|
-
expect(record1.next_item).to eq(record2)
|
133
|
-
expect(record2.previous_item).to eq(record1)
|
134
|
-
expect(record1.previous_item).to eq(nil)
|
135
|
-
expect(record2.next_item).to eq(nil)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
context 'with transactions' do
|
141
|
-
enable_transactions!
|
142
|
-
|
143
|
-
it_behaves_like 'scoped_orderable'
|
144
|
-
end
|
145
|
-
|
146
|
-
context 'without transactions' do
|
147
|
-
disable_transactions!
|
148
|
-
|
149
|
-
it_behaves_like 'scoped_orderable'
|
150
|
-
end
|
151
|
-
end
|
@@ -1,184 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe SimpleOrderable do
|
4
|
-
|
5
|
-
shared_examples_for 'simple_orderable' do
|
6
|
-
|
7
|
-
def positions
|
8
|
-
SimpleOrderable.pluck(:position).sort
|
9
|
-
end
|
10
|
-
|
11
|
-
before :each do
|
12
|
-
5.times { SimpleOrderable.create! }
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'should have proper position field' do
|
16
|
-
expect(SimpleOrderable.fields.key?('position')).to be true
|
17
|
-
expect(SimpleOrderable.fields['position'].options[:type]).to eq(Integer)
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'should have index on position field' do
|
21
|
-
expect(SimpleOrderable.index_specifications.detect { |spec| spec.key == { position: 1 } }).not_to be_nil
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'should have a orderable base of 1' do
|
25
|
-
expect(SimpleOrderable.create!.orderable_top).to eq(1)
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'should set proper position while creation' do
|
29
|
-
expect(positions).to eq([1, 2, 3, 4, 5])
|
30
|
-
end
|
31
|
-
|
32
|
-
describe 'removement' do
|
33
|
-
it 'top' do
|
34
|
-
SimpleOrderable.where(position: 1).destroy
|
35
|
-
expect(positions).to eq([1, 2, 3, 4])
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'bottom' do
|
39
|
-
SimpleOrderable.where(position: 5).destroy
|
40
|
-
expect(positions).to eq([1, 2, 3, 4])
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'middle' do
|
44
|
-
SimpleOrderable.where(position: 3).destroy
|
45
|
-
expect(positions).to eq([1, 2, 3, 4])
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe 'inserting' do
|
50
|
-
it 'top' do
|
51
|
-
newbie = SimpleOrderable.create! move_to: :top
|
52
|
-
expect(positions).to eq([1, 2, 3, 4, 5, 6])
|
53
|
-
expect(newbie.position).to eq(1)
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'bottom' do
|
57
|
-
newbie = SimpleOrderable.create! move_to: :bottom
|
58
|
-
expect(positions).to eq([1, 2, 3, 4, 5, 6])
|
59
|
-
expect(newbie.position).to eq(6)
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'middle' do
|
63
|
-
newbie = SimpleOrderable.create! move_to: 4
|
64
|
-
expect(positions).to eq([1, 2, 3, 4, 5, 6])
|
65
|
-
expect(newbie.position).to eq(4)
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'middle (with a numeric string)' do
|
69
|
-
newbie = SimpleOrderable.create! move_to: '4'
|
70
|
-
expect(positions).to eq([1, 2, 3, 4, 5, 6])
|
71
|
-
expect(newbie.position).to eq(4)
|
72
|
-
end
|
73
|
-
|
74
|
-
it 'middle (with a non-numeric string)' do
|
75
|
-
expect do
|
76
|
-
SimpleOrderable.create! move_to: 'four'
|
77
|
-
end.to raise_error Mongoid::Orderable::Errors::InvalidTargetPosition
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'simultaneous create and update' do
|
81
|
-
newbie = SimpleOrderable.new
|
82
|
-
newbie.send(:orderable_before_update) { }
|
83
|
-
expect(newbie.position).to eq(6)
|
84
|
-
another = SimpleOrderable.create!
|
85
|
-
expect(another.position).to eq(6)
|
86
|
-
newbie.save!
|
87
|
-
expect(positions).to eq([1, 2, 3, 4, 5, 6, 7])
|
88
|
-
expect(newbie.position).to eq(7)
|
89
|
-
expect(another.position).to eq(6)
|
90
|
-
end
|
91
|
-
|
92
|
-
it 'parallel updates' do
|
93
|
-
newbie = SimpleOrderable.new
|
94
|
-
newbie.send(:orderable_before_update) { }
|
95
|
-
another = SimpleOrderable.create!
|
96
|
-
newbie.save!
|
97
|
-
expect(positions).to eq([1, 2, 3, 4, 5, 6, 7])
|
98
|
-
expect(newbie.position).to eq(7)
|
99
|
-
expect(another.position).to eq(6)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
describe 'movement' do
|
104
|
-
it 'higher from top' do
|
105
|
-
record = SimpleOrderable.where(position: 1).first
|
106
|
-
record.update_attributes move_to: :higher
|
107
|
-
expect(positions).to eq([1, 2, 3, 4, 5])
|
108
|
-
expect(record.reload.position).to eq(1)
|
109
|
-
end
|
110
|
-
|
111
|
-
it 'higher from bottom' do
|
112
|
-
record = SimpleOrderable.where(position: 5).first
|
113
|
-
record.update_attributes move_to: :higher
|
114
|
-
expect(positions).to eq([1, 2, 3, 4, 5])
|
115
|
-
expect(record.reload.position).to eq(4)
|
116
|
-
end
|
117
|
-
|
118
|
-
it 'higher from middle' do
|
119
|
-
record = SimpleOrderable.where(position: 3).first
|
120
|
-
record.update_attributes move_to: :higher
|
121
|
-
expect(positions).to eq([1, 2, 3, 4, 5])
|
122
|
-
expect(record.reload.position).to eq(2)
|
123
|
-
end
|
124
|
-
|
125
|
-
it 'lower from top' do
|
126
|
-
record = SimpleOrderable.where(position: 1).first
|
127
|
-
record.update_attributes move_to: :lower
|
128
|
-
expect(positions).to eq([1, 2, 3, 4, 5])
|
129
|
-
expect(record.reload.position).to eq(2)
|
130
|
-
end
|
131
|
-
|
132
|
-
it 'lower from bottom' do
|
133
|
-
record = SimpleOrderable.where(position: 5).first
|
134
|
-
record.update_attributes move_to: :lower
|
135
|
-
expect(positions).to eq([1, 2, 3, 4, 5])
|
136
|
-
expect(record.reload.position).to eq(5)
|
137
|
-
end
|
138
|
-
|
139
|
-
it 'lower from middle' do
|
140
|
-
record = SimpleOrderable.where(position: 3).first
|
141
|
-
record.update_attributes move_to: :lower
|
142
|
-
expect(positions).to eq([1, 2, 3, 4, 5])
|
143
|
-
expect(record.reload.position).to eq(4)
|
144
|
-
end
|
145
|
-
|
146
|
-
it 'does nothing if position not change' do
|
147
|
-
record = SimpleOrderable.where(position: 3).first
|
148
|
-
record.save
|
149
|
-
expect(positions).to eq([1, 2, 3, 4, 5])
|
150
|
-
expect(record.reload.position).to eq(3)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
describe 'utility methods' do
|
155
|
-
it 'should return a collection of items lower/higher on the list for next_items/previous_items' do
|
156
|
-
record1 = SimpleOrderable.where(position: 1).first
|
157
|
-
record2 = SimpleOrderable.where(position: 2).first
|
158
|
-
record3 = SimpleOrderable.where(position: 3).first
|
159
|
-
record4 = SimpleOrderable.where(position: 4).first
|
160
|
-
record5 = SimpleOrderable.where(position: 5).first
|
161
|
-
expect(record1.next_items.to_a).to eq([record2, record3, record4, record5])
|
162
|
-
expect(record5.previous_items.to_a).to eq([record1, record2, record3, record4])
|
163
|
-
expect(record3.previous_items.to_a).to eq([record1, record2])
|
164
|
-
expect(record3.next_items.to_a).to eq([record4, record5])
|
165
|
-
expect(record1.next_item).to eq(record2)
|
166
|
-
expect(record2.previous_item).to eq(record1)
|
167
|
-
expect(record1.previous_item).to eq(nil)
|
168
|
-
expect(record5.next_item).to eq(nil)
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
context 'with transactions' do
|
174
|
-
enable_transactions!
|
175
|
-
|
176
|
-
it_behaves_like 'simple_orderable'
|
177
|
-
end
|
178
|
-
|
179
|
-
context 'without transactions' do
|
180
|
-
disable_transactions!
|
181
|
-
|
182
|
-
it_behaves_like 'simple_orderable'
|
183
|
-
end
|
184
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe StringScopedOrderable do
|
4
|
-
|
5
|
-
shared_examples_for 'string_scoped_orderable' do
|
6
|
-
|
7
|
-
it 'uses the foreign key of the relationship as scope' do
|
8
|
-
orderable1 = StringScopedOrderable.create!(some_scope: 1)
|
9
|
-
orderable2 = StringScopedOrderable.create!(some_scope: 1)
|
10
|
-
orderable3 = StringScopedOrderable.create!(some_scope: 2)
|
11
|
-
expect(orderable1.position).to eq 1
|
12
|
-
expect(orderable2.position).to eq 2
|
13
|
-
expect(orderable3.position).to eq 1
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
context 'with transactions' do
|
18
|
-
enable_transactions!
|
19
|
-
|
20
|
-
it_behaves_like 'string_scoped_orderable'
|
21
|
-
end
|
22
|
-
|
23
|
-
context 'without transactions' do
|
24
|
-
disable_transactions!
|
25
|
-
|
26
|
-
it_behaves_like 'string_scoped_orderable'
|
27
|
-
end
|
28
|
-
end
|
@@ -1,161 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ZeroBasedOrderable do
|
4
|
-
|
5
|
-
shared_examples_for 'zero_based_orderable' do
|
6
|
-
|
7
|
-
before :each do
|
8
|
-
5.times { ZeroBasedOrderable.create! }
|
9
|
-
end
|
10
|
-
|
11
|
-
def positions
|
12
|
-
ZeroBasedOrderable.pluck(:position).sort
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'should have a orderable base of 0' do
|
16
|
-
expect(ZeroBasedOrderable.create!.orderable_top).to eq(0)
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'should set proper position while creation' do
|
20
|
-
expect(positions).to eq([0, 1, 2, 3, 4])
|
21
|
-
end
|
22
|
-
|
23
|
-
describe 'reset position' do
|
24
|
-
before { ZeroBasedOrderable.update_all(position: nil) }
|
25
|
-
it 'should properly reset position' do
|
26
|
-
ZeroBasedOrderable.all.map(&:save)
|
27
|
-
expect(positions).to eq([0, 1, 2, 3, 4])
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
describe 'removement' do
|
32
|
-
it 'top' do
|
33
|
-
ZeroBasedOrderable.where(position: 0).destroy
|
34
|
-
expect(positions).to eq([0, 1, 2, 3])
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'bottom' do
|
38
|
-
ZeroBasedOrderable.where(position: 4).destroy
|
39
|
-
expect(positions).to eq([0, 1, 2, 3])
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'middle' do
|
43
|
-
ZeroBasedOrderable.where(position: 2).destroy
|
44
|
-
expect(positions).to eq([0, 1, 2, 3])
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
describe 'inserting' do
|
49
|
-
it 'top' do
|
50
|
-
newbie = ZeroBasedOrderable.create! move_to: :top
|
51
|
-
expect(positions).to eq([0, 1, 2, 3, 4, 5])
|
52
|
-
expect(newbie.position).to eq(0)
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'bottom' do
|
56
|
-
newbie = ZeroBasedOrderable.create! move_to: :bottom
|
57
|
-
expect(positions).to eq([0, 1, 2, 3, 4, 5])
|
58
|
-
expect(newbie.position).to eq(5)
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'middle' do
|
62
|
-
newbie = ZeroBasedOrderable.create! move_to: 3
|
63
|
-
expect(positions).to eq([0, 1, 2, 3, 4, 5])
|
64
|
-
expect(newbie.position).to eq(3)
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'middle (with a numeric string)' do
|
68
|
-
newbie = ZeroBasedOrderable.create! move_to: '3'
|
69
|
-
expect(positions).to eq([0, 1, 2, 3, 4, 5])
|
70
|
-
expect(newbie.position).to eq(3)
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'middle (with a non-numeric string)' do
|
74
|
-
expect do
|
75
|
-
ZeroBasedOrderable.create! move_to: 'three'
|
76
|
-
end.to raise_error Mongoid::Orderable::Errors::InvalidTargetPosition
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
describe 'movement' do
|
81
|
-
it 'higher from top' do
|
82
|
-
record = ZeroBasedOrderable.where(position: 0).first
|
83
|
-
record.update_attributes move_to: :higher
|
84
|
-
expect(positions).to eq([0, 1, 2, 3, 4])
|
85
|
-
expect(record.reload.position).to eq(0)
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'higher from bottom' do
|
89
|
-
record = ZeroBasedOrderable.where(position: 4).first
|
90
|
-
record.update_attributes move_to: :higher
|
91
|
-
expect(positions).to eq([0, 1, 2, 3, 4])
|
92
|
-
expect(record.reload.position).to eq(3)
|
93
|
-
end
|
94
|
-
|
95
|
-
it 'higher from middle' do
|
96
|
-
record = ZeroBasedOrderable.where(position: 3).first
|
97
|
-
record.update_attributes move_to: :higher
|
98
|
-
expect(positions).to eq([0, 1, 2, 3, 4])
|
99
|
-
expect(record.reload.position).to eq(2)
|
100
|
-
end
|
101
|
-
|
102
|
-
it 'lower from top' do
|
103
|
-
record = ZeroBasedOrderable.where(position: 0).first
|
104
|
-
record.update_attributes move_to: :lower
|
105
|
-
expect(positions).to eq([0, 1, 2, 3, 4])
|
106
|
-
expect(record.reload.position).to eq(1)
|
107
|
-
end
|
108
|
-
|
109
|
-
it 'lower from bottom' do
|
110
|
-
record = ZeroBasedOrderable.where(position: 4).first
|
111
|
-
record.update_attributes move_to: :lower
|
112
|
-
expect(positions).to eq([0, 1, 2, 3, 4])
|
113
|
-
expect(record.reload.position).to eq(4)
|
114
|
-
end
|
115
|
-
|
116
|
-
it 'lower from middle' do
|
117
|
-
record = ZeroBasedOrderable.where(position: 2).first
|
118
|
-
record.update_attributes move_to: :lower
|
119
|
-
expect(positions).to eq([0, 1, 2, 3, 4])
|
120
|
-
expect(record.reload.position).to eq(3)
|
121
|
-
end
|
122
|
-
|
123
|
-
it 'does nothing if position not change' do
|
124
|
-
record = ZeroBasedOrderable.where(position: 3).first
|
125
|
-
record.save
|
126
|
-
expect(positions).to eq([0, 1, 2, 3, 4])
|
127
|
-
expect(record.reload.position).to eq(3)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
describe 'utility methods' do
|
132
|
-
it 'should return a collection of items lower/higher on the list for next_items/previous_items' do
|
133
|
-
record1 = ZeroBasedOrderable.where(position: 0).first
|
134
|
-
record2 = ZeroBasedOrderable.where(position: 1).first
|
135
|
-
record3 = ZeroBasedOrderable.where(position: 2).first
|
136
|
-
record4 = ZeroBasedOrderable.where(position: 3).first
|
137
|
-
record5 = ZeroBasedOrderable.where(position: 4).first
|
138
|
-
expect(record1.next_items.to_a).to eq([record2, record3, record4, record5])
|
139
|
-
expect(record5.previous_items.to_a).to eq([record1, record2, record3, record4])
|
140
|
-
expect(record3.previous_items.to_a).to eq([record1, record2])
|
141
|
-
expect(record3.next_items.to_a).to eq([record4, record5])
|
142
|
-
expect(record1.next_item).to eq(record2)
|
143
|
-
expect(record2.previous_item).to eq(record1)
|
144
|
-
expect(record1.previous_item).to eq(nil)
|
145
|
-
expect(record5.next_item).to eq(nil)
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
context 'with transactions' do
|
151
|
-
enable_transactions!
|
152
|
-
|
153
|
-
it_behaves_like 'zero_based_orderable'
|
154
|
-
end
|
155
|
-
|
156
|
-
context 'without transactions' do
|
157
|
-
disable_transactions!
|
158
|
-
|
159
|
-
it_behaves_like 'zero_based_orderable'
|
160
|
-
end
|
161
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
require 'bundler'
|
2
|
-
Bundler.require
|
3
|
-
require 'rspec'
|
4
|
-
require 'rspec/retry'
|
5
|
-
|
6
|
-
Mongoid.configure do |config|
|
7
|
-
config.connect_to 'mongoid_orderable_test'
|
8
|
-
end
|
9
|
-
|
10
|
-
Mongoid.logger.level = Logger::INFO
|
11
|
-
Mongo::Logger.logger.level = Logger::INFO
|
12
|
-
Mongoid::Config.belongs_to_required_by_default = false
|
13
|
-
|
14
|
-
RSpec.configure do |config|
|
15
|
-
config.order = 'random'
|
16
|
-
|
17
|
-
config.before(:each) do
|
18
|
-
Mongoid.purge!
|
19
|
-
Mongoid.models.each do |model|
|
20
|
-
model.create_indexes if model.name =~ /Mongoid::Orderable::Models/
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
require_relative 'support/models'
|
26
|
-
|
27
|
-
def set_transactions(enabled)
|
28
|
-
Mongoid.models.each do |model|
|
29
|
-
next unless model.respond_to?(:orderable_configs)
|
30
|
-
model.orderable_configs.values.each do |config|
|
31
|
-
config[:use_transactions] = enabled
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def enable_transactions!
|
37
|
-
before { set_transactions(true) }
|
38
|
-
end
|
39
|
-
|
40
|
-
def disable_transactions!
|
41
|
-
before { set_transactions(false) }
|
42
|
-
end
|
data/spec/support/models.rb
DELETED
@@ -1,134 +0,0 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
Mongoid::Orderable.configure do |c|
|
4
|
-
c.use_transactions = true
|
5
|
-
c.transaction_max_retries = 100
|
6
|
-
c.lock_collection = :foo_bar_locks
|
7
|
-
end
|
8
|
-
|
9
|
-
class SimpleOrderable
|
10
|
-
include Mongoid::Document
|
11
|
-
include Mongoid::Orderable
|
12
|
-
|
13
|
-
orderable
|
14
|
-
end
|
15
|
-
|
16
|
-
class ConditionalOrderable
|
17
|
-
include Mongoid::Document
|
18
|
-
include Mongoid::Orderable
|
19
|
-
|
20
|
-
field :cond_a, type: Boolean
|
21
|
-
field :cond_b, type: Integer
|
22
|
-
|
23
|
-
orderable field: :pos_a, if: :cond_a, unless: ->(obj) { obj.cond_b&.<(2) }
|
24
|
-
orderable field: :pos_b, if: -> { cond_b&.<=(4) }
|
25
|
-
orderable field: :pos_c, unless: false
|
26
|
-
end
|
27
|
-
|
28
|
-
class ScopedGroup
|
29
|
-
include Mongoid::Document
|
30
|
-
|
31
|
-
has_many :scoped_orderables
|
32
|
-
has_many :multiple_fields_orderables
|
33
|
-
end
|
34
|
-
|
35
|
-
class ScopedOrderable
|
36
|
-
include Mongoid::Document
|
37
|
-
include Mongoid::Orderable
|
38
|
-
|
39
|
-
belongs_to :group, class_name: 'ScopedGroup', optional: true
|
40
|
-
|
41
|
-
orderable scope: :group
|
42
|
-
end
|
43
|
-
|
44
|
-
class StringScopedOrderable
|
45
|
-
include Mongoid::Document
|
46
|
-
include Mongoid::Orderable
|
47
|
-
|
48
|
-
field :some_scope, type: Integer
|
49
|
-
|
50
|
-
orderable scope: 'some_scope'
|
51
|
-
end
|
52
|
-
|
53
|
-
class EmbedsOrderable
|
54
|
-
include Mongoid::Document
|
55
|
-
|
56
|
-
embeds_many :embedded_orderables
|
57
|
-
end
|
58
|
-
|
59
|
-
class EmbeddedOrderable
|
60
|
-
include Mongoid::Document
|
61
|
-
include Mongoid::Orderable
|
62
|
-
|
63
|
-
embedded_in :embeds_orderable
|
64
|
-
|
65
|
-
orderable
|
66
|
-
end
|
67
|
-
|
68
|
-
class CustomizedOrderable
|
69
|
-
include Mongoid::Document
|
70
|
-
include Mongoid::Orderable
|
71
|
-
|
72
|
-
orderable field: :pos, as: :my_position
|
73
|
-
end
|
74
|
-
|
75
|
-
class NoIndexOrderable
|
76
|
-
include Mongoid::Document
|
77
|
-
include Mongoid::Orderable
|
78
|
-
|
79
|
-
orderable index: false
|
80
|
-
end
|
81
|
-
|
82
|
-
class ZeroBasedOrderable
|
83
|
-
include Mongoid::Document
|
84
|
-
include Mongoid::Orderable
|
85
|
-
|
86
|
-
orderable base: 0
|
87
|
-
end
|
88
|
-
|
89
|
-
class InheritedOrderable
|
90
|
-
include Mongoid::Document
|
91
|
-
include Mongoid::Orderable
|
92
|
-
|
93
|
-
orderable inherited: true
|
94
|
-
end
|
95
|
-
|
96
|
-
class Apple < InheritedOrderable
|
97
|
-
orderable field: :serial
|
98
|
-
end
|
99
|
-
|
100
|
-
class Orange < InheritedOrderable
|
101
|
-
end
|
102
|
-
|
103
|
-
class ForeignKeyDiffersOrderable
|
104
|
-
include Mongoid::Document
|
105
|
-
include Mongoid::Orderable
|
106
|
-
|
107
|
-
belongs_to :different_scope, class_name: 'ForeignKeyDiffersOrderable',
|
108
|
-
foreign_key: 'different_orderable_id',
|
109
|
-
optional: true
|
110
|
-
|
111
|
-
orderable scope: :different_scope
|
112
|
-
end
|
113
|
-
|
114
|
-
class MultipleFieldsOrderable
|
115
|
-
include Mongoid::Document
|
116
|
-
include Mongoid::Orderable
|
117
|
-
|
118
|
-
belongs_to :group, class_name: 'ScopedGroup', optional: true
|
119
|
-
|
120
|
-
orderable field: :pos, base: 0, index: false, as: :position
|
121
|
-
orderable field: :serial_no, default: true
|
122
|
-
orderable field: :groups, scope: :group
|
123
|
-
end
|
124
|
-
|
125
|
-
class MultipleScopedOrderable
|
126
|
-
include Mongoid::Document
|
127
|
-
include Mongoid::Orderable
|
128
|
-
|
129
|
-
belongs_to :apple, optional: true
|
130
|
-
belongs_to :orange, optional: true
|
131
|
-
|
132
|
-
orderable field: :posa, scope: :apple_id
|
133
|
-
orderable field: :poso, scope: :orange_id
|
134
|
-
end
|