acts_as_list 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/continuous_integration.yml +62 -0
- data/.gitignore +3 -2
- data/CHANGELOG.md +9 -0
- data/Gemfile +6 -21
- data/README.md +7 -2
- data/Rakefile +0 -8
- data/acts_as_list.gemspec +9 -4
- data/lib/acts_as_list/active_record/acts/list.rb +10 -5
- data/lib/acts_as_list/active_record/acts/scope_method_definer.rb +1 -2
- data/lib/acts_as_list/version.rb +1 -1
- data/test/helper.rb +17 -5
- data/test/shared_list.rb +131 -108
- data/test/support/ci_database.yml +20 -0
- data/test/{database.yml → support/database.yml} +1 -1
- data/test/test_list.rb +136 -5
- metadata +102 -25
- data/.github/workflows/ci.yml +0 -123
- data/.travis.yml +0 -55
- data/Appraisals +0 -44
- data/gemfiles/rails_4_2.gemfile +0 -32
- data/gemfiles/rails_5_0.gemfile +0 -31
- data/gemfiles/rails_5_1.gemfile +0 -31
- data/gemfiles/rails_5_2.gemfile +0 -31
- data/gemfiles/rails_6_0.gemfile +0 -31
- data/gemfiles/rails_6_1.gemfile +0 -31
- data/gemfiles/rails_7_0.gemfile +0 -31
data/test/shared_list.rb
CHANGED
@@ -2,103 +2,108 @@
|
|
2
2
|
|
3
3
|
module Shared
|
4
4
|
module List
|
5
|
-
def setup
|
5
|
+
def setup(mixin = ListMixin, mixinError = ListMixinError, id = :id)
|
6
|
+
@mixin = mixin
|
7
|
+
@id = id
|
8
|
+
@mixinError = mixinError
|
6
9
|
(1..4).each do |counter|
|
7
|
-
node =
|
10
|
+
node = @mixin.new parent_id: 5
|
11
|
+
node.first_id = counter if @id == :first_id
|
12
|
+
node.second_id = counter if @id == :first_id
|
8
13
|
node.pos = counter
|
9
14
|
node.save!
|
10
15
|
end
|
11
16
|
end
|
12
17
|
|
13
18
|
def test_current_position
|
14
|
-
first_item =
|
19
|
+
first_item = @mixin.where(parent_id: 5).first
|
15
20
|
assert_equal 1, first_item.current_position
|
16
21
|
first_item.remove_from_list
|
17
22
|
assert_nil first_item.current_position
|
18
23
|
end
|
19
24
|
|
20
25
|
def test_reordering
|
21
|
-
assert_equal [1, 2, 3, 4],
|
26
|
+
assert_equal [1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
22
27
|
|
23
|
-
|
24
|
-
assert_equal [1, 3, 2, 4],
|
28
|
+
@mixin.where(@id => 2).first.move_lower
|
29
|
+
assert_equal [1, 3, 2, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
25
30
|
|
26
|
-
|
27
|
-
assert_equal [1, 2, 3, 4],
|
31
|
+
@mixin.where(@id => 2).first.move_higher
|
32
|
+
assert_equal [1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
28
33
|
|
29
|
-
|
30
|
-
assert_equal [2, 3, 4, 1],
|
34
|
+
@mixin.where(@id => 1).first.move_to_bottom
|
35
|
+
assert_equal [2, 3, 4, 1], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
31
36
|
|
32
|
-
|
33
|
-
assert_equal [1, 2, 3, 4],
|
37
|
+
@mixin.where(@id => 1).first.move_to_top
|
38
|
+
assert_equal [1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
34
39
|
|
35
|
-
|
36
|
-
assert_equal [1, 3, 4, 2],
|
40
|
+
@mixin.where(@id => 2).first.move_to_bottom
|
41
|
+
assert_equal [1, 3, 4, 2], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
37
42
|
|
38
|
-
|
39
|
-
assert_equal [4, 1, 3, 2],
|
43
|
+
@mixin.where(@id => 4).first.move_to_top
|
44
|
+
assert_equal [4, 1, 3, 2], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
40
45
|
end
|
41
46
|
|
42
47
|
def test_move_to_bottom_with_next_to_last_item
|
43
|
-
assert_equal [1, 2, 3, 4],
|
44
|
-
|
45
|
-
assert_equal [1, 2, 4, 3],
|
48
|
+
assert_equal [1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
49
|
+
@mixin.where(@id => 3).first.move_to_bottom
|
50
|
+
assert_equal [1, 2, 4, 3], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
46
51
|
end
|
47
52
|
|
48
53
|
def test_next_prev
|
49
|
-
assert_equal
|
50
|
-
assert_nil
|
51
|
-
assert_equal
|
52
|
-
assert_nil
|
54
|
+
assert_equal @mixin.where(@id => 2).first, @mixin.where(@id => 1).first.lower_item
|
55
|
+
assert_nil @mixin.where(@id => 1).first.higher_item
|
56
|
+
assert_equal @mixin.where(@id => 3).first, @mixin.where(@id => 4).first.higher_item
|
57
|
+
assert_nil @mixin.where(@id => 4).first.lower_item
|
53
58
|
end
|
54
59
|
|
55
60
|
def test_injection
|
56
|
-
item =
|
61
|
+
item = @mixin.new(parent_id: 1)
|
57
62
|
assert_equal({ parent_id: 1 }, item.scope_condition)
|
58
63
|
assert_equal "pos", item.position_column
|
59
64
|
end
|
60
65
|
|
61
66
|
def test_insert
|
62
|
-
new =
|
67
|
+
new = create_record(id: 5, parent_id: 20)
|
63
68
|
assert_equal 1, new.pos
|
64
69
|
assert new.first?
|
65
70
|
assert new.last?
|
66
71
|
|
67
|
-
new =
|
72
|
+
new = create_record(id: 6, parent_id: 20)
|
68
73
|
assert_equal 2, new.pos
|
69
74
|
assert !new.first?
|
70
75
|
assert new.last?
|
71
76
|
|
72
|
-
new =
|
77
|
+
new = @mixin.acts_as_list_no_update { create_record(id: 7, parent_id: 20) }
|
73
78
|
assert_equal_or_nil $default_position, new.pos
|
74
79
|
assert_equal $default_position.is_a?(Integer), new.first?
|
75
80
|
assert !new.last?
|
76
81
|
|
77
|
-
new =
|
82
|
+
new = create_record(id: 8, parent_id: 20)
|
78
83
|
assert_equal 3, new.pos
|
79
84
|
assert !new.first?
|
80
85
|
assert new.last?
|
81
86
|
|
82
|
-
new =
|
87
|
+
new = create_record(id: 9, parent_id: 0)
|
83
88
|
assert_equal 1, new.pos
|
84
89
|
assert new.first?
|
85
90
|
assert new.last?
|
86
91
|
end
|
87
92
|
|
88
93
|
def test_insert_at
|
89
|
-
new =
|
94
|
+
new = create_record(id: 5, parent_id: 20)
|
90
95
|
assert_equal 1, new.pos
|
91
96
|
|
92
|
-
new =
|
97
|
+
new = create_record(id: 6, parent_id: 20)
|
93
98
|
assert_equal 2, new.pos
|
94
99
|
|
95
|
-
new =
|
100
|
+
new = create_record(id: 7, parent_id: 20)
|
96
101
|
assert_equal 3, new.pos
|
97
102
|
|
98
|
-
new_noup =
|
103
|
+
new_noup = @mixin.acts_as_list_no_update { create_record(id: 8, parent_id: 20) }
|
99
104
|
assert_equal_or_nil $default_position, new_noup.pos
|
100
105
|
|
101
|
-
new4 =
|
106
|
+
new4 = create_record(id: 9, parent_id: 20)
|
102
107
|
assert_equal 4, new4.pos
|
103
108
|
|
104
109
|
new4.insert_at(3)
|
@@ -113,7 +118,7 @@ module Shared
|
|
113
118
|
new4.reload
|
114
119
|
assert_equal 4, new4.pos
|
115
120
|
|
116
|
-
new5 =
|
121
|
+
new5 = create_record(id: 10, parent_id: 20)
|
117
122
|
assert_equal 5, new5.pos
|
118
123
|
|
119
124
|
new5.insert_at(1)
|
@@ -125,49 +130,50 @@ module Shared
|
|
125
130
|
new_noup.reload
|
126
131
|
assert_equal_or_nil $default_position, new_noup.pos
|
127
132
|
|
128
|
-
last1 =
|
129
|
-
last2 =
|
133
|
+
last1 = @mixin.where('pos IS NOT NULL').order('pos').last
|
134
|
+
last2 = @mixin.where('pos IS NOT NULL').order('pos').last
|
130
135
|
last1.insert_at(1)
|
131
136
|
last2.insert_at(1)
|
132
|
-
pos_list =
|
137
|
+
pos_list = @mixin.where(parent_id: 20).order("pos ASC#{' NULLS FIRST' if ENV['DB'] == 'postgresql'}").map(&:pos)
|
133
138
|
assert_equal [$default_position, 1, 2, 3, 4, 5], pos_list
|
134
139
|
end
|
135
140
|
|
136
141
|
def test_insert_at_after_dup
|
137
|
-
new1 =
|
138
|
-
new2 =
|
139
|
-
new3 =
|
142
|
+
new1 = create_record(id: 5, parent_id: 20)
|
143
|
+
new2 = create_record(id: 6, parent_id: 20)
|
144
|
+
new3 = create_record(id: 7, parent_id: 20)
|
140
145
|
|
141
146
|
duped = new1.dup
|
142
|
-
duped.
|
147
|
+
duped.first_id = 8 if @id == :first_id
|
148
|
+
duped.second_id = 8 if @id == :first_id
|
149
|
+
duped.insert_at(1)
|
143
150
|
[new1, new2, new3, duped].map(&:reload)
|
144
151
|
|
145
152
|
assert_equal [1, 2, 3, 4], [duped.pos, new1.pos, new2.pos, new3.pos]
|
146
153
|
end
|
147
154
|
|
148
155
|
def test_delete_middle
|
149
|
-
assert_equal [1, 2, 3, 4],
|
156
|
+
assert_equal [1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
150
157
|
|
151
|
-
|
158
|
+
@mixin.where(@id => 2).first.destroy
|
159
|
+
assert_equal [1, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
152
160
|
|
153
|
-
assert_equal
|
161
|
+
assert_equal 1, @mixin.where(@id => 1).first.pos
|
162
|
+
assert_equal 2, @mixin.where(@id => 3).first.pos
|
163
|
+
assert_equal 3, @mixin.where(@id => 4).first.pos
|
154
164
|
|
155
|
-
|
156
|
-
assert_equal 2, ListMixin.where(id: 3).first.pos
|
157
|
-
assert_equal 3, ListMixin.where(id: 4).first.pos
|
165
|
+
@mixin.where(@id => 1).first.destroy
|
158
166
|
|
159
|
-
|
167
|
+
assert_equal [3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
160
168
|
|
161
|
-
assert_equal
|
169
|
+
assert_equal 1, @mixin.where(@id => 3).first.pos
|
170
|
+
assert_equal 2, @mixin.where(@id => 4).first.pos
|
162
171
|
|
163
|
-
|
164
|
-
assert_equal 2, ListMixin.where(id: 4).first.pos
|
172
|
+
@mixin.acts_as_list_no_update { @mixin.where(@id => 3).first.destroy }
|
165
173
|
|
166
|
-
|
174
|
+
assert_equal [4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
167
175
|
|
168
|
-
assert_equal
|
169
|
-
|
170
|
-
assert_equal 2, ListMixin.where(id: 4).first.pos
|
176
|
+
assert_equal 2, @mixin.where(@id => 4).first.pos
|
171
177
|
end
|
172
178
|
|
173
179
|
def test_with_string_based_scope
|
@@ -178,137 +184,142 @@ module Shared
|
|
178
184
|
end
|
179
185
|
|
180
186
|
def test_nil_scope
|
181
|
-
new1, new2, new3 =
|
187
|
+
new1, new2, new3 = create_record(id: 5), create_record(id: 6), create_record(id: 7)
|
182
188
|
new2.move_higher
|
183
|
-
assert_equal [new2, new1, new3].map(
|
189
|
+
assert_equal [new2, new1, new3].map(&@id), @mixin.where(parent_id: nil).order('pos').map(&@id)
|
184
190
|
end
|
185
191
|
|
186
192
|
def test_update_position_when_scope_changes
|
187
|
-
assert_equal [1, 2, 3, 4],
|
188
|
-
|
193
|
+
assert_equal [1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
194
|
+
create_record(id: 5, parent_id: 6)
|
189
195
|
|
190
|
-
|
196
|
+
@mixin.where(@id => 2).first.move_within_scope(6)
|
191
197
|
|
192
|
-
assert_equal 2,
|
198
|
+
assert_equal 2, @mixin.where(@id => 2).first.pos
|
193
199
|
|
194
|
-
assert_equal [1, 3, 4],
|
200
|
+
assert_equal [1, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
195
201
|
|
196
|
-
assert_equal 1,
|
197
|
-
assert_equal 2,
|
198
|
-
assert_equal 3,
|
202
|
+
assert_equal 1, @mixin.where(@id => 1).first.pos
|
203
|
+
assert_equal 2, @mixin.where(@id => 3).first.pos
|
204
|
+
assert_equal 3, @mixin.where(@id => 4).first.pos
|
199
205
|
|
200
|
-
|
201
|
-
assert_equal [1, 3, 4, 2],
|
206
|
+
@mixin.where(@id => 2).first.move_within_scope(5)
|
207
|
+
assert_equal [1, 3, 4, 2], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
202
208
|
end
|
203
209
|
|
204
210
|
def test_remove_from_list_should_then_fail_in_list?
|
205
|
-
assert_equal true,
|
206
|
-
|
207
|
-
assert_equal false,
|
211
|
+
assert_equal true, @mixin.where(@id => 1).first.in_list?
|
212
|
+
@mixin.where(@id => 1).first.remove_from_list
|
213
|
+
assert_equal false, @mixin.where(@id => 1).first.in_list?
|
208
214
|
end
|
209
215
|
|
210
216
|
def test_remove_from_list_should_set_position_to_nil
|
211
|
-
assert_equal [1, 2, 3, 4],
|
217
|
+
assert_equal [1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
212
218
|
|
213
|
-
|
219
|
+
@mixin.where(@id => 2).first.remove_from_list
|
214
220
|
|
215
|
-
assert_equal 1,
|
216
|
-
assert_nil
|
217
|
-
assert_equal 2,
|
218
|
-
assert_equal 3,
|
221
|
+
assert_equal 1, @mixin.where(@id => 1).first.pos
|
222
|
+
assert_nil @mixin.where(@id => 2).first.pos
|
223
|
+
assert_equal 2, @mixin.where(@id => 3).first.pos
|
224
|
+
assert_equal 3, @mixin.where(@id => 4).first.pos
|
219
225
|
end
|
220
226
|
|
221
227
|
def test_remove_before_destroy_does_not_shift_lower_items_twice
|
222
|
-
assert_equal [1, 2, 3, 4],
|
228
|
+
assert_equal [1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
223
229
|
|
224
|
-
|
225
|
-
|
230
|
+
@mixin.where(@id => 2).first.remove_from_list
|
231
|
+
@mixin.where(@id => 2).first.destroy
|
226
232
|
|
227
|
-
assert_equal [1, 3, 4],
|
233
|
+
assert_equal [1, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
228
234
|
|
229
|
-
assert_equal 1,
|
230
|
-
assert_equal 2,
|
231
|
-
assert_equal 3,
|
235
|
+
assert_equal 1, @mixin.where(@id => 1).first.pos
|
236
|
+
assert_equal 2, @mixin.where(@id => 3).first.pos
|
237
|
+
assert_equal 3, @mixin.where(@id => 4).first.pos
|
232
238
|
end
|
233
239
|
|
234
240
|
def test_before_destroy_callbacks_do_not_update_position_to_nil_before_deleting_the_record
|
235
|
-
assert_equal [1, 2, 3, 4],
|
241
|
+
assert_equal [1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
236
242
|
|
237
243
|
# We need to trigger all the before_destroy callbacks without actually
|
238
|
-
# destroying the record so we can see the
|
244
|
+
# destroying the record so we can see the effect the callbacks have on
|
239
245
|
# the record.
|
240
|
-
list =
|
246
|
+
list = @mixin.where(@id => 2).first
|
241
247
|
if list.respond_to?(:run_callbacks)
|
242
248
|
list.run_callbacks(:destroy)
|
243
249
|
else
|
244
250
|
list.send(:callback, :before_destroy)
|
245
251
|
end
|
246
252
|
|
247
|
-
assert_equal [1, 2, 3, 4],
|
253
|
+
assert_equal [1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
248
254
|
|
249
|
-
assert_equal 1,
|
250
|
-
assert_equal 2,
|
251
|
-
assert_equal 2,
|
252
|
-
assert_equal 3,
|
255
|
+
assert_equal 1, @mixin.where(@id => 1).first.pos
|
256
|
+
assert_equal 2, @mixin.where(@id => 2).first.pos
|
257
|
+
assert_equal 2, @mixin.where(@id => 3).first.pos
|
258
|
+
assert_equal 3, @mixin.where(@id => 4).first.pos
|
253
259
|
end
|
254
260
|
|
255
261
|
def test_before_create_callback_adds_to_bottom
|
256
|
-
assert_equal [1, 2, 3, 4],
|
262
|
+
assert_equal [1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
257
263
|
|
258
|
-
new =
|
264
|
+
new = create_record(id: 5, parent_id: 5)
|
259
265
|
assert_equal 5, new.pos
|
260
266
|
assert !new.first?
|
261
267
|
assert new.last?
|
262
268
|
|
263
|
-
assert_equal [1, 2, 3, 4, 5],
|
269
|
+
assert_equal [1, 2, 3, 4, 5], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
264
270
|
end
|
265
271
|
|
266
272
|
def test_before_create_callback_adds_to_given_position
|
267
|
-
assert_equal [1, 2, 3, 4],
|
268
|
-
|
269
|
-
new =
|
273
|
+
assert_equal [1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
274
|
+
new = @mixin.new(@id => 5, parent_id: 5)
|
275
|
+
new.second_id = 5 if @id == :first_id
|
270
276
|
new.pos = 1
|
271
277
|
new.save!
|
272
278
|
assert_equal 1, new.pos
|
273
279
|
assert new.first?
|
274
280
|
assert !new.last?
|
275
281
|
|
276
|
-
assert_equal [5, 1, 2, 3, 4],
|
282
|
+
assert_equal [5, 1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
277
283
|
|
278
|
-
new6 =
|
284
|
+
new6 = @mixin.new(@id => 6, parent_id: 5)
|
285
|
+
new6.second_id = 6 if @id == :first_id
|
279
286
|
new6.pos = 3
|
280
287
|
new6.save!
|
281
288
|
assert_equal 3, new6.pos
|
282
289
|
assert !new6.first?
|
283
290
|
assert !new6.last?
|
284
291
|
|
285
|
-
assert_equal [5, 1, 6, 2, 3, 4],
|
292
|
+
assert_equal [5, 1, 6, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
|
286
293
|
|
287
|
-
new =
|
294
|
+
new = @mixin.new(@id => 7, parent_id: 5)
|
295
|
+
new.second_id = 7 if @id == :first_id
|
288
296
|
new.pos = 3
|
289
|
-
|
297
|
+
@mixin.acts_as_list_no_update { new.save! }
|
290
298
|
assert_equal 3, new.pos
|
291
299
|
assert_equal 3, new6.pos
|
292
300
|
assert !new.first?
|
293
301
|
assert !new.last?
|
294
302
|
|
295
|
-
assert_equal [5, 1, 6, 7, 2, 3, 4],
|
303
|
+
assert_equal [5, 1, 6, 7, 2, 3, 4], @mixin.where(parent_id: 5).order("pos, #{@id}").map(&@id)
|
296
304
|
end
|
297
305
|
|
298
306
|
def test_non_persisted_records_dont_get_lock_called
|
299
|
-
new =
|
307
|
+
new = @mixin.new(@id => 5, parent_id: 5)
|
308
|
+
new.second_id = 6 if @id == :first_id
|
300
309
|
new.destroy
|
301
310
|
end
|
302
311
|
|
303
312
|
def test_invalid_records_dont_get_inserted
|
304
|
-
new =
|
313
|
+
new = @mixinError.new(@id => 5, parent_id: 5, state: nil)
|
314
|
+
new.second_id = 6 if @id == :first_id
|
305
315
|
assert !new.valid?
|
306
316
|
new.insert_at(1)
|
307
317
|
assert !new.persisted?
|
308
318
|
end
|
309
319
|
|
310
320
|
def test_invalid_records_raise_error_with_insert_at!
|
311
|
-
new =
|
321
|
+
new = @mixinError.new(@id => 5, parent_id: 5, state: nil)
|
322
|
+
new.second_id = 5 if @id == :first_id
|
312
323
|
assert !new.valid?
|
313
324
|
assert_raises ActiveRecord::RecordInvalid do
|
314
325
|
new.insert_at!(1)
|
@@ -317,8 +328,20 @@ module Shared
|
|
317
328
|
|
318
329
|
def test_find_or_create_doesnt_raise_deprecation_warning
|
319
330
|
assert_no_deprecation_warning_raised_by('ActiveRecord deprecation warning raised when using `find_or_create_by` when we didn\'t expect it') do
|
320
|
-
|
331
|
+
@mixin.where(parent_id: 5).find_or_create_by(pos: 5) do |new|
|
332
|
+
new.first_id = 5 if @id == :first_id
|
333
|
+
new.second_id = 5 if @id == :first_id
|
334
|
+
end
|
321
335
|
end
|
322
336
|
end
|
337
|
+
|
338
|
+
private
|
339
|
+
|
340
|
+
def create_record(opts)
|
341
|
+
attrs = { parent_id: opts[:parent_id] }
|
342
|
+
attrs[:first_id] = opts[:id] if @id == :first_id
|
343
|
+
attrs[:second_id] = opts[:id] if @id == :first_id
|
344
|
+
@mixin.create(attrs)
|
345
|
+
end
|
323
346
|
end
|
324
347
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
sqlite:
|
2
|
+
adapter: sqlite3
|
3
|
+
database: file::memory:?cache=shared
|
4
|
+
|
5
|
+
mysql:
|
6
|
+
adapter: mysql2
|
7
|
+
database: runner
|
8
|
+
pool: 5
|
9
|
+
timeout: 5000
|
10
|
+
username: root
|
11
|
+
password: root
|
12
|
+
|
13
|
+
postgresql:
|
14
|
+
adapter: postgresql
|
15
|
+
database: runner
|
16
|
+
pool: 5
|
17
|
+
timeout: 5000
|
18
|
+
username: runner
|
19
|
+
password:
|
20
|
+
min_messages: ERROR
|
data/test/test_list.rb
CHANGED
@@ -7,11 +7,13 @@ def setup_db(position_options = {})
|
|
7
7
|
$default_position = position_options[:default]
|
8
8
|
|
9
9
|
# sqlite cannot drop/rename/alter columns and add constraints after table creation
|
10
|
-
sqlite = ENV.fetch("DB"
|
10
|
+
sqlite = ENV.fetch("DB") == "sqlite"
|
11
|
+
unique = position_options.delete(:unique)
|
12
|
+
positive = position_options.delete(:positive)
|
11
13
|
|
12
14
|
# AR caches columns options like defaults etc. Clear them!
|
13
15
|
ActiveRecord::Base.connection.create_table :mixins do |t|
|
14
|
-
t.column :pos, :integer, **position_options unless
|
16
|
+
t.column :pos, :integer, **position_options unless positive && sqlite
|
15
17
|
t.column :active, :boolean, default: true
|
16
18
|
t.column :parent_id, :integer
|
17
19
|
t.column :parent_type, :string
|
@@ -20,11 +22,11 @@ def setup_db(position_options = {})
|
|
20
22
|
t.column :state, :integer
|
21
23
|
end
|
22
24
|
|
23
|
-
if
|
25
|
+
if unique && !(sqlite && positive)
|
24
26
|
ActiveRecord::Base.connection.add_index :mixins, :pos, unique: true
|
25
27
|
end
|
26
28
|
|
27
|
-
if
|
29
|
+
if positive
|
28
30
|
if sqlite
|
29
31
|
# SQLite cannot add constraint after table creation, also cannot add unique inside ADD COLUMN
|
30
32
|
ActiveRecord::Base.connection.execute('ALTER TABLE mixins ADD COLUMN pos integer8 NOT NULL CHECK (pos > 0) DEFAULT 1')
|
@@ -48,9 +50,21 @@ def setup_db(position_options = {})
|
|
48
50
|
|
49
51
|
ActiveRecord::Base.connection.add_index 'altid-table', :pos, unique: true
|
50
52
|
|
53
|
+
# This table is used to test table names with a composite primary_key
|
54
|
+
ActiveRecord::Base.connection.create_table 'composite-primary-key-table', primary_key: [:first_id, :second_id] do |t|
|
55
|
+
t.integer :first_id, null: false
|
56
|
+
t.integer :second_id, null: false
|
57
|
+
t.column :parent_id, :integer
|
58
|
+
t.column :parent_type, :string
|
59
|
+
t.column :pos, :integer
|
60
|
+
t.column :created_at, :datetime
|
61
|
+
t.column :updated_at, :datetime
|
62
|
+
t.column :state, :integer
|
63
|
+
end
|
64
|
+
|
51
65
|
mixins = [ Mixin, ListMixin, ListMixinSub1, ListMixinSub2, ListWithStringScopeMixin,
|
52
66
|
ArrayScopeListMixin, ZeroBasedMixin, DefaultScopedMixin, EnumArrayScopeListMixin,
|
53
|
-
DefaultScopedWhereMixin, TopAdditionMixin, NoAdditionMixin, QuotedList, TouchDisabledMixin ]
|
67
|
+
DefaultScopedWhereMixin, TopAdditionMixin, NoAdditionMixin, QuotedList, TouchDisabledMixin, CompositePrimaryKeyList, CompositePrimaryKeyListScoped ]
|
54
68
|
|
55
69
|
ActiveRecord::Base.connection.schema_cache.clear!
|
56
70
|
mixins.each do |klass|
|
@@ -194,6 +208,21 @@ class QuotedList < ActiveRecord::Base
|
|
194
208
|
acts_as_list column: :order
|
195
209
|
end
|
196
210
|
|
211
|
+
class CompositePrimaryKeyList < ActiveRecord::Base
|
212
|
+
self.table_name = "composite-primary-key-table"
|
213
|
+
self.primary_key = [:first_id, :second_id]
|
214
|
+
|
215
|
+
acts_as_list column: "pos"
|
216
|
+
end
|
217
|
+
|
218
|
+
class CompositePrimaryKeyListScoped < CompositePrimaryKeyList
|
219
|
+
acts_as_list column: "pos", scope: :parent_id
|
220
|
+
end
|
221
|
+
|
222
|
+
class CompositePrimaryKeyListScopedError < CompositePrimaryKeyListScoped
|
223
|
+
validates :state, presence: true
|
224
|
+
end
|
225
|
+
|
197
226
|
class ActsAsListTestCase < Minitest::Test
|
198
227
|
# No default test required as this class is abstract.
|
199
228
|
# Need for test/unit.
|
@@ -1120,3 +1149,105 @@ class SequentialUpdatesMixinNotNullUniquePositiveConstraintsTest < ActsAsListTes
|
|
1120
1149
|
end
|
1121
1150
|
end
|
1122
1151
|
end
|
1152
|
+
|
1153
|
+
if ActiveRecord::VERSION::MAJOR == 7 && ActiveRecord::VERSION::MINOR >= 1 || ActiveRecord::VERSION::MAJOR > 7
|
1154
|
+
class CompositePrimaryKeyListTest < ActsAsListTestCase
|
1155
|
+
def setup
|
1156
|
+
setup_db
|
1157
|
+
(1..4).each { |counter| CompositePrimaryKeyList.create!({first_id: counter, second_id: counter, pos: counter}) }
|
1158
|
+
end
|
1159
|
+
|
1160
|
+
def test_insert_at
|
1161
|
+
new = CompositePrimaryKeyList.create({first_id: 5, second_id: 5})
|
1162
|
+
assert_equal 5, new.pos
|
1163
|
+
|
1164
|
+
new.insert_at(1)
|
1165
|
+
assert_equal 1, new.pos
|
1166
|
+
|
1167
|
+
new.insert_at(5)
|
1168
|
+
assert_equal 5, new.pos
|
1169
|
+
|
1170
|
+
new.insert_at(3)
|
1171
|
+
assert_equal 3, new.pos
|
1172
|
+
end
|
1173
|
+
|
1174
|
+
def test_move_lower
|
1175
|
+
item = CompositePrimaryKeyList.order(:pos).first
|
1176
|
+
item.move_lower
|
1177
|
+
assert_equal 2, item.pos
|
1178
|
+
end
|
1179
|
+
|
1180
|
+
def test_move_higher
|
1181
|
+
item = CompositePrimaryKeyList.order(:pos).second
|
1182
|
+
item.move_higher
|
1183
|
+
assert_equal 1, item.pos
|
1184
|
+
end
|
1185
|
+
|
1186
|
+
def test_move_to_bottom
|
1187
|
+
item = CompositePrimaryKeyList.order(:pos).first
|
1188
|
+
item.move_to_bottom
|
1189
|
+
assert_equal 4, item.pos
|
1190
|
+
end
|
1191
|
+
|
1192
|
+
def test_move_to_top
|
1193
|
+
new_item = CompositePrimaryKeyList.create!({first_id: 5, second_id: 5})
|
1194
|
+
assert_equal 5, new_item.pos
|
1195
|
+
|
1196
|
+
new_item.move_to_top
|
1197
|
+
assert_equal 1, new_item.pos
|
1198
|
+
end
|
1199
|
+
|
1200
|
+
def test_remove_from_list
|
1201
|
+
assert_equal true, CompositePrimaryKeyList.find([1, 1]).in_list?
|
1202
|
+
CompositePrimaryKeyList.find([1,1]).remove_from_list
|
1203
|
+
assert_equal false, CompositePrimaryKeyList.find([1, 1]).in_list?
|
1204
|
+
end
|
1205
|
+
|
1206
|
+
def test_increment_position
|
1207
|
+
item = CompositePrimaryKeyList.order(:pos).first
|
1208
|
+
item.increment_position
|
1209
|
+
assert_equal 2, item.pos
|
1210
|
+
end
|
1211
|
+
|
1212
|
+
def test_decrement_position
|
1213
|
+
item = CompositePrimaryKeyList.order(:pos).second
|
1214
|
+
item.decrement_position
|
1215
|
+
assert_equal 1, item.pos
|
1216
|
+
end
|
1217
|
+
|
1218
|
+
def test_set_list_position
|
1219
|
+
item = CompositePrimaryKeyList.order(:pos).first
|
1220
|
+
item.set_list_position(4)
|
1221
|
+
assert_equal 4, item.pos
|
1222
|
+
end
|
1223
|
+
|
1224
|
+
def test_create_at_top
|
1225
|
+
new = CompositePrimaryKeyList.create({first_id: 5, second_id: 5, pos: 1})
|
1226
|
+
assert_equal 1, new.pos
|
1227
|
+
end
|
1228
|
+
|
1229
|
+
def test_destroy
|
1230
|
+
new_item = CompositePrimaryKeyList.create({first_id: 5, second_id: 5})
|
1231
|
+
assert_equal 5, new_item.pos
|
1232
|
+
assert_equal true, new_item.last?
|
1233
|
+
|
1234
|
+
new_item.insert_at(1)
|
1235
|
+
assert_equal 1, new_item.pos
|
1236
|
+
assert_equal true, new_item.first?
|
1237
|
+
|
1238
|
+
new_item.destroy
|
1239
|
+
assert_equal [1,2,3,4], CompositePrimaryKeyList.all.map(&:pos).sort
|
1240
|
+
end
|
1241
|
+
end
|
1242
|
+
|
1243
|
+
class CompositePrimaryKeyListScopedTest < ActsAsListTestCase
|
1244
|
+
include Shared::List
|
1245
|
+
|
1246
|
+
def setup
|
1247
|
+
setup_db
|
1248
|
+
|
1249
|
+
super(CompositePrimaryKeyListScoped, CompositePrimaryKeyListScopedError, :first_id)
|
1250
|
+
end
|
1251
|
+
end
|
1252
|
+
end
|
1253
|
+
|