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.
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 = ListMixin.new parent_id: 5
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 = ListMixin.where(parent_id: 5).first
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], ListMixin.where(parent_id: 5).order('pos').map(&:id)
26
+ assert_equal [1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
22
27
 
23
- ListMixin.where(id: 2).first.move_lower
24
- assert_equal [1, 3, 2, 4], ListMixin.where(parent_id: 5).order('pos').map(&:id)
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
- ListMixin.where(id: 2).first.move_higher
27
- assert_equal [1, 2, 3, 4], ListMixin.where(parent_id: 5).order('pos').map(&:id)
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
- ListMixin.where(id: 1).first.move_to_bottom
30
- assert_equal [2, 3, 4, 1], ListMixin.where(parent_id: 5).order('pos').map(&:id)
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
- ListMixin.where(id: 1).first.move_to_top
33
- assert_equal [1, 2, 3, 4], ListMixin.where(parent_id: 5).order('pos').map(&:id)
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
- ListMixin.where(id: 2).first.move_to_bottom
36
- assert_equal [1, 3, 4, 2], ListMixin.where(parent_id: 5).order('pos').map(&:id)
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
- ListMixin.where(id: 4).first.move_to_top
39
- assert_equal [4, 1, 3, 2], ListMixin.where(parent_id: 5).order('pos').map(&:id)
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], ListMixin.where(parent_id: 5).order('pos').map(&:id)
44
- ListMixin.where(id: 3).first.move_to_bottom
45
- assert_equal [1, 2, 4, 3], ListMixin.where(parent_id: 5).order('pos').map(&:id)
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 ListMixin.where(id: 2).first, ListMixin.where(id: 1).first.lower_item
50
- assert_nil ListMixin.where(id: 1).first.higher_item
51
- assert_equal ListMixin.where(id: 3).first, ListMixin.where(id: 4).first.higher_item
52
- assert_nil ListMixin.where(id: 4).first.lower_item
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 = ListMixin.new(parent_id: 1)
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 = ListMixin.create(parent_id: 20)
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 = ListMixin.create(parent_id: 20)
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 = ListMixin.acts_as_list_no_update { ListMixin.create(parent_id: 20) }
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 = ListMixin.create(parent_id: 20)
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 = ListMixin.create(parent_id: 0)
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 = ListMixin.create(parent_id: 20)
94
+ new = create_record(id: 5, parent_id: 20)
90
95
  assert_equal 1, new.pos
91
96
 
92
- new = ListMixin.create(parent_id: 20)
97
+ new = create_record(id: 6, parent_id: 20)
93
98
  assert_equal 2, new.pos
94
99
 
95
- new = ListMixin.create(parent_id: 20)
100
+ new = create_record(id: 7, parent_id: 20)
96
101
  assert_equal 3, new.pos
97
102
 
98
- new_noup = ListMixin.acts_as_list_no_update { ListMixin.create(parent_id: 20) }
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 = ListMixin.create(parent_id: 20)
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 = ListMixin.create(parent_id: 20)
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 = ListMixin.where('pos IS NOT NULL').order('pos').last
129
- last2 = ListMixin.where('pos IS NOT NULL').order('pos').last
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 = ListMixin.where(parent_id: 20).order("pos ASC#{' NULLS FIRST' if ENV['DB'] == 'postgresql'}").map(&:pos)
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 = ListMixin.create(parent_id: 20)
138
- new2 = ListMixin.create(parent_id: 20)
139
- new3 = ListMixin.create(parent_id: 20)
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.save
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], ListMixin.where(parent_id: 5).order('pos').map(&:id)
156
+ assert_equal [1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
150
157
 
151
- ListMixin.where(id: 2).first.destroy
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 [1, 3, 4], ListMixin.where(parent_id: 5).order('pos').map(&:id)
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
- assert_equal 1, ListMixin.where(id: 1).first.pos
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
- ListMixin.where(id: 1).first.destroy
167
+ assert_equal [3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
160
168
 
161
- assert_equal [3, 4], ListMixin.where(parent_id: 5).order('pos').map(&:id)
169
+ assert_equal 1, @mixin.where(@id => 3).first.pos
170
+ assert_equal 2, @mixin.where(@id => 4).first.pos
162
171
 
163
- assert_equal 1, ListMixin.where(id: 3).first.pos
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
- ListMixin.acts_as_list_no_update { ListMixin.where(id: 3).first.destroy }
174
+ assert_equal [4], @mixin.where(parent_id: 5).order('pos').map(&@id)
167
175
 
168
- assert_equal [4], ListMixin.where(parent_id: 5).order('pos').map(&:id)
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 = ListMixin.create, ListMixin.create, ListMixin.create
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(&:id), ListMixin.where(parent_id: nil).order('pos').map(&:id)
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], ListMixin.where(parent_id: 5).order('pos').map(&:id)
188
- ListMixin.create(parent_id: 6)
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
- ListMixin.where(id: 2).first.move_within_scope(6)
196
+ @mixin.where(@id => 2).first.move_within_scope(6)
191
197
 
192
- assert_equal 2, ListMixin.where(id: 2).first.pos
198
+ assert_equal 2, @mixin.where(@id => 2).first.pos
193
199
 
194
- assert_equal [1, 3, 4], ListMixin.where(parent_id: 5).order('pos').map(&:id)
200
+ assert_equal [1, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
195
201
 
196
- assert_equal 1, ListMixin.where(id: 1).first.pos
197
- assert_equal 2, ListMixin.where(id: 3).first.pos
198
- assert_equal 3, ListMixin.where(id: 4).first.pos
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
- ListMixin.where(id: 2).first.move_within_scope(5)
201
- assert_equal [1, 3, 4, 2], ListMixin.where(parent_id: 5).order('pos').map(&:id)
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, ListMixin.where(id: 1).first.in_list?
206
- ListMixin.where(id: 1).first.remove_from_list
207
- assert_equal false, ListMixin.where(id: 1).first.in_list?
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], ListMixin.where(parent_id: 5).order('pos').map(&:id)
217
+ assert_equal [1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
212
218
 
213
- ListMixin.where(id: 2).first.remove_from_list
219
+ @mixin.where(@id => 2).first.remove_from_list
214
220
 
215
- assert_equal 1, ListMixin.where(id: 1).first.pos
216
- assert_nil ListMixin.where(id: 2).first.pos
217
- assert_equal 2, ListMixin.where(id: 3).first.pos
218
- assert_equal 3, ListMixin.where(id: 4).first.pos
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], ListMixin.where(parent_id: 5).order('pos').map(&:id)
228
+ assert_equal [1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
223
229
 
224
- ListMixin.where(id: 2).first.remove_from_list
225
- ListMixin.where(id: 2).first.destroy
230
+ @mixin.where(@id => 2).first.remove_from_list
231
+ @mixin.where(@id => 2).first.destroy
226
232
 
227
- assert_equal [1, 3, 4], ListMixin.where(parent_id: 5).order('pos').map(&:id)
233
+ assert_equal [1, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
228
234
 
229
- assert_equal 1, ListMixin.where(id: 1).first.pos
230
- assert_equal 2, ListMixin.where(id: 3).first.pos
231
- assert_equal 3, ListMixin.where(id: 4).first.pos
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], ListMixin.where(parent_id: 5).order('pos').map(&:id)
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 affect the callbacks have on
244
+ # destroying the record so we can see the effect the callbacks have on
239
245
  # the record.
240
- list = ListMixin.where(id: 2).first
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], ListMixin.where(parent_id: 5).order('pos').map(&:id)
253
+ assert_equal [1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
248
254
 
249
- assert_equal 1, ListMixin.where(id: 1).first.pos
250
- assert_equal 2, ListMixin.where(id: 2).first.pos
251
- assert_equal 2, ListMixin.where(id: 3).first.pos
252
- assert_equal 3, ListMixin.where(id: 4).first.pos
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], ListMixin.where(parent_id: 5).order('pos').map(&:id)
262
+ assert_equal [1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
257
263
 
258
- new = ListMixin.create(parent_id: 5)
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], ListMixin.where(parent_id: 5).order('pos').map(&:id)
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], ListMixin.where(parent_id: 5).order('pos').map(&:id)
268
-
269
- new = ListMixin.new(parent_id: 5)
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], ListMixin.where(parent_id: 5).order('pos').map(&:id)
282
+ assert_equal [5, 1, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
277
283
 
278
- new6 = ListMixin.new(parent_id: 5)
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], ListMixin.where(parent_id: 5).order('pos').map(&:id)
292
+ assert_equal [5, 1, 6, 2, 3, 4], @mixin.where(parent_id: 5).order('pos').map(&@id)
286
293
 
287
- new = ListMixin.new(parent_id: 5)
294
+ new = @mixin.new(@id => 7, parent_id: 5)
295
+ new.second_id = 7 if @id == :first_id
288
296
  new.pos = 3
289
- ListMixin.acts_as_list_no_update { new.save! }
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], ListMixin.where(parent_id: 5).order('pos, id').map(&:id)
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 = ListMixin.new(parent_id: 5)
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 = ListMixinError.new(parent_id: 5, state: nil)
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 = ListMixinError.new(parent_id: 5, state: nil)
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
- ListMixin.where(parent_id: 5).find_or_create_by(pos: 5)
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
@@ -1,6 +1,6 @@
1
1
  sqlite:
2
2
  adapter: sqlite3
3
- database: "file:memdb1?mode=memory&cache=shared"
3
+ database: file::memory:?cache=shared
4
4
 
5
5
  mysql:
6
6
  adapter: mysql2
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", "sqlite") == "sqlite"
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 position_options[:positive] && sqlite
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 position_options[:unique] && !(sqlite && position_options[:positive])
25
+ if unique && !(sqlite && positive)
24
26
  ActiveRecord::Base.connection.add_index :mixins, :pos, unique: true
25
27
  end
26
28
 
27
- if position_options[:positive]
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
+