acts_as_list 0.1.2 → 0.1.3

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.
@@ -0,0 +1,7 @@
1
+ module ActiveRecord
2
+ module Acts
3
+ module List
4
+ VERSION = "0.1.3"
5
+ end
6
+ end
7
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'active_record'
12
+ require "#{File.dirname(__FILE__)}/../init"
13
+
14
+
15
+
data/test/test_list.rb ADDED
@@ -0,0 +1,659 @@
1
+ # NOTE: following now done in helper.rb (better Readability)
2
+ #require 'test/unit'
3
+ #require 'rubygems'
4
+ #gem 'activerecord', '>= 1.15.4.7794'
5
+ #require 'active_record'
6
+ #require "#{File.dirname(__FILE__)}/../init"
7
+ require 'helper.rb'
8
+
9
+
10
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
11
+
12
+ def setup_db
13
+ ActiveRecord::Schema.define(:version => 1) do
14
+ create_table :mixins do |t|
15
+ t.column :pos, :integer
16
+ t.column :parent_id, :integer
17
+ t.column :parent_type, :string
18
+ t.column :created_at, :datetime
19
+ t.column :updated_at, :datetime
20
+ end
21
+ end
22
+ end
23
+
24
+ # Returns true if ActiveRecord is rails3 version
25
+ def rails_3
26
+ defined?(ActiveRecord::VERSION) && ActiveRecord::VERSION::MAJOR >= 3
27
+ end
28
+
29
+ def teardown_db
30
+ ActiveRecord::Base.connection.tables.each do |table|
31
+ ActiveRecord::Base.connection.drop_table(table)
32
+ end
33
+ end
34
+
35
+ class Mixin < ActiveRecord::Base
36
+ end
37
+
38
+ class ListMixin < Mixin
39
+ acts_as_list :column => "pos", :scope => :parent
40
+
41
+ def self.table_name() "mixins" end
42
+ end
43
+
44
+ class ListMixinSub1 < ListMixin
45
+ end
46
+
47
+ class ListMixinSub2 < ListMixin
48
+ end
49
+
50
+ class ListWithStringScopeMixin < ActiveRecord::Base
51
+ acts_as_list :column => "pos", :scope => 'parent_id = #{parent_id}'
52
+
53
+ def self.table_name() "mixins" end
54
+ end
55
+
56
+ class ArrayScopeListMixin < Mixin
57
+ acts_as_list :column => "pos", :scope => [:parent_id, :parent_type]
58
+
59
+ def self.table_name() "mixins" end
60
+ end
61
+
62
+ class ZeroBasedMixin < ActiveRecord::Base
63
+ acts_as_list :column => "pos", :top_of_list => 0, :scope => [:parent_id]
64
+
65
+ def self.table_name() "mixins" end
66
+ end
67
+
68
+
69
+ class ZeroBasedTest < Test::Unit::TestCase
70
+ def setup
71
+ setup_db
72
+ (1..4).each { |counter| ZeroBasedMixin.create! :pos => counter, :parent_id => 5 }
73
+ end
74
+
75
+ def teardown
76
+ teardown_db
77
+ end
78
+
79
+ def test_insert
80
+ new = ZeroBasedMixin.create(:parent_id => 20)
81
+ assert_equal 0, new.pos
82
+ assert new.first?
83
+ assert new.last?
84
+
85
+ new = ZeroBasedMixin.create(:parent_id => 20)
86
+ assert_equal 1, new.pos
87
+ assert !new.first?
88
+ assert new.last?
89
+
90
+ new = ZeroBasedMixin.create(:parent_id => 20)
91
+ assert_equal 2, new.pos
92
+ assert !new.first?
93
+ assert new.last?
94
+
95
+ new = ZeroBasedMixin.create(:parent_id => 0)
96
+ assert_equal 0, new.pos
97
+ assert new.first?
98
+ assert new.last?
99
+ end
100
+
101
+
102
+ def test_reordering
103
+ assert_equal [1, 2, 3, 4], ZeroBasedMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
104
+
105
+ ListMixin.find(2).move_lower
106
+ assert_equal [1, 3, 2, 4], ZeroBasedMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
107
+
108
+ ListMixin.find(2).move_higher
109
+ assert_equal [1, 2, 3, 4], ZeroBasedMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
110
+
111
+ ListMixin.find(1).move_to_bottom
112
+ assert_equal [2, 3, 4, 1], ZeroBasedMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
113
+
114
+ ListMixin.find(1).move_to_top
115
+ assert_equal [1, 2, 3, 4], ZeroBasedMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
116
+
117
+ ListMixin.find(2).move_to_bottom
118
+ assert_equal [1, 3, 4, 2], ZeroBasedMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
119
+
120
+ ListMixin.find(4).move_to_top
121
+ assert_equal [4, 1, 3, 2], ZeroBasedMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
122
+ end
123
+
124
+ def test_insert_at
125
+ new = ZeroBasedMixin.create(:parent_id => 20)
126
+ assert_equal 0, new.pos
127
+
128
+ new = ZeroBasedMixin.create(:parent_id => 20)
129
+ assert_equal 1, new.pos
130
+
131
+ new = ZeroBasedMixin.create(:parent_id => 20)
132
+ assert_equal 2, new.pos
133
+
134
+ new4 = ZeroBasedMixin.create(:parent_id => 20)
135
+ assert_equal 3, new4.pos
136
+
137
+ new4.insert_at(2)
138
+ assert_equal 2, new4.pos
139
+
140
+ new.reload
141
+ assert_equal 3, new.pos
142
+
143
+ new.insert_at(2)
144
+ assert_equal 2, new.pos
145
+
146
+ new4.reload
147
+ assert_equal 3, new4.pos
148
+
149
+ new5 = ListMixin.create(:parent_id => 20)
150
+ assert_equal 4, new5.pos
151
+
152
+ new5.insert_at(1)
153
+ assert_equal 1, new5.pos
154
+
155
+ new4.reload
156
+ assert_equal 4, new4.pos
157
+ end
158
+
159
+ end
160
+
161
+
162
+ class ListTest < Test::Unit::TestCase
163
+
164
+ def setup
165
+ setup_db
166
+ (1..4).each { |counter| ListMixin.create! :pos => counter, :parent_id => 5 }
167
+ end
168
+
169
+ def teardown
170
+ teardown_db
171
+ end
172
+
173
+ def test_reordering
174
+ assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
175
+
176
+ ListMixin.find(2).move_lower
177
+ assert_equal [1, 3, 2, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
178
+
179
+ ListMixin.find(2).move_higher
180
+ assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
181
+
182
+ ListMixin.find(1).move_to_bottom
183
+ assert_equal [2, 3, 4, 1], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
184
+
185
+ ListMixin.find(1).move_to_top
186
+ assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
187
+
188
+ ListMixin.find(2).move_to_bottom
189
+ assert_equal [1, 3, 4, 2], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
190
+
191
+ ListMixin.find(4).move_to_top
192
+ assert_equal [4, 1, 3, 2], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
193
+ end
194
+
195
+ def test_move_to_bottom_with_next_to_last_item
196
+ assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
197
+ ListMixin.find(3).move_to_bottom
198
+ assert_equal [1, 2, 4, 3], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
199
+ end
200
+
201
+ def test_next_prev
202
+ assert_equal ListMixin.find(2), ListMixin.find(1).lower_item
203
+ assert_nil ListMixin.find(1).higher_item
204
+ assert_equal ListMixin.find(3), ListMixin.find(4).higher_item
205
+ assert_nil ListMixin.find(4).lower_item
206
+ end
207
+
208
+ def test_injection
209
+ item = ListMixin.new(:parent_id => 1)
210
+ assert_equal '"mixins"."parent_id" = 1', item.scope_condition
211
+ assert_equal "pos", item.position_column
212
+ end
213
+
214
+ def test_insert
215
+ new = ListMixin.create(:parent_id => 20)
216
+ assert_equal 1, new.pos
217
+ assert new.first?
218
+ assert new.last?
219
+
220
+ new = ListMixin.create(:parent_id => 20)
221
+ assert_equal 2, new.pos
222
+ assert !new.first?
223
+ assert new.last?
224
+
225
+ new = ListMixin.create(:parent_id => 20)
226
+ assert_equal 3, new.pos
227
+ assert !new.first?
228
+ assert new.last?
229
+
230
+ new = ListMixin.create(:parent_id => 0)
231
+ assert_equal 1, new.pos
232
+ assert new.first?
233
+ assert new.last?
234
+ end
235
+
236
+ def test_insert_at
237
+ new = ListMixin.create(:parent_id => 20)
238
+ assert_equal 1, new.pos
239
+
240
+ new = ListMixin.create(:parent_id => 20)
241
+ assert_equal 2, new.pos
242
+
243
+ new = ListMixin.create(:parent_id => 20)
244
+ assert_equal 3, new.pos
245
+
246
+ new4 = ListMixin.create(:parent_id => 20)
247
+ assert_equal 4, new4.pos
248
+
249
+ new4.insert_at(3)
250
+ assert_equal 3, new4.pos
251
+
252
+ new.reload
253
+ assert_equal 4, new.pos
254
+
255
+ new.insert_at(2)
256
+ assert_equal 2, new.pos
257
+
258
+ new4.reload
259
+ assert_equal 4, new4.pos
260
+
261
+ new5 = ListMixin.create(:parent_id => 20)
262
+ assert_equal 5, new5.pos
263
+
264
+ new5.insert_at(1)
265
+ assert_equal 1, new5.pos
266
+
267
+ new4.reload
268
+ assert_equal 5, new4.pos
269
+ end
270
+
271
+ def test_delete_middle
272
+ assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
273
+
274
+ ListMixin.find(2).destroy
275
+
276
+ assert_equal [1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
277
+
278
+ assert_equal 1, ListMixin.find(1).pos
279
+ assert_equal 2, ListMixin.find(3).pos
280
+ assert_equal 3, ListMixin.find(4).pos
281
+
282
+ ListMixin.find(1).destroy
283
+
284
+ assert_equal [3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
285
+
286
+ assert_equal 1, ListMixin.find(3).pos
287
+ assert_equal 2, ListMixin.find(4).pos
288
+ end
289
+
290
+ def test_with_string_based_scope
291
+ new = ListWithStringScopeMixin.create(:parent_id => 500)
292
+ assert_equal 1, new.pos
293
+ assert new.first?
294
+ assert new.last?
295
+ end
296
+
297
+ def test_nil_scope
298
+ new1, new2, new3 = ListMixin.create, ListMixin.create, ListMixin.create
299
+ new2.move_higher
300
+ assert_equal [new2, new1, new3], ListMixin.find(:all, :conditions => 'parent_id IS NULL', :order => 'pos')
301
+ end
302
+
303
+ def test_remove_from_list_should_then_fail_in_list?
304
+ assert_equal true, ListMixin.find(1).in_list?
305
+ ListMixin.find(1).remove_from_list
306
+ assert_equal false, ListMixin.find(1).in_list?
307
+ end
308
+
309
+ def test_remove_from_list_should_set_position_to_nil
310
+ assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
311
+
312
+ ListMixin.find(2).remove_from_list
313
+
314
+ assert_equal [2, 1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
315
+
316
+ assert_equal 1, ListMixin.find(1).pos
317
+ assert_equal nil, ListMixin.find(2).pos
318
+ assert_equal 2, ListMixin.find(3).pos
319
+ assert_equal 3, ListMixin.find(4).pos
320
+ end
321
+
322
+ def test_remove_before_destroy_does_not_shift_lower_items_twice
323
+ assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
324
+
325
+ ListMixin.find(2).remove_from_list
326
+ ListMixin.find(2).destroy
327
+
328
+ assert_equal [1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
329
+
330
+ assert_equal 1, ListMixin.find(1).pos
331
+ assert_equal 2, ListMixin.find(3).pos
332
+ assert_equal 3, ListMixin.find(4).pos
333
+ end
334
+
335
+ def test_before_destroy_callbacks_do_not_update_position_to_nil_before_deleting_the_record
336
+ assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
337
+
338
+ # We need to trigger all the before_destroy callbacks without actually
339
+ # destroying the record so we can see the affect the callbacks have on
340
+ # the record.
341
+ # NOTE: Hotfix for rails3 ActiveRecord
342
+ list = ListMixin.find(2)
343
+ if list.respond_to?(:run_callbacks)
344
+ # Refactored to work according to Rails3 ActiveRSupport Callbacks <http://api.rubyonrails.org/classes/ActiveSupport/Callbacks.html>
345
+ list.run_callbacks :destroy, :before if rails_3
346
+ list.run_callbacks(:before_destroy) if !rails_3
347
+ else
348
+ list.send(:callback, :before_destroy)
349
+ end
350
+
351
+ assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
352
+
353
+ assert_equal 1, ListMixin.find(1).pos
354
+ assert_equal 2, ListMixin.find(2).pos
355
+ assert_equal 2, ListMixin.find(3).pos
356
+ assert_equal 3, ListMixin.find(4).pos
357
+ end
358
+
359
+ def test_before_create_callback_adds_to_bottom
360
+ assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
361
+
362
+ new = ListMixin.create(:parent_id => 5)
363
+ assert_equal 5, new.pos
364
+ assert !new.first?
365
+ assert new.last?
366
+
367
+ assert_equal [1, 2, 3, 4, 5], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
368
+ end
369
+
370
+ def test_before_create_callback_adds_to_given_position
371
+ assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
372
+
373
+ new = ListMixin.create(:pos => 1, :parent_id => 5)
374
+ assert_equal 1, new.pos
375
+ assert new.first?
376
+ assert !new.last?
377
+
378
+ assert_equal [5, 1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
379
+
380
+ new = ListMixin.create(:pos => 3, :parent_id => 5)
381
+ assert_equal 3, new.pos
382
+ assert !new.first?
383
+ assert !new.last?
384
+
385
+ assert_equal [5, 1, 6, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos').map(&:id)
386
+ end
387
+
388
+ end
389
+
390
+ class ListSubTest < Test::Unit::TestCase
391
+
392
+ def setup
393
+ setup_db
394
+ (1..4).each { |i| ((i % 2 == 1) ? ListMixinSub1 : ListMixinSub2).create! :pos => i, :parent_id => 5000 }
395
+ end
396
+
397
+ def teardown
398
+ teardown_db
399
+ end
400
+
401
+ def test_reordering
402
+ assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
403
+
404
+ ListMixin.find(2).move_lower
405
+ assert_equal [1, 3, 2, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
406
+
407
+ ListMixin.find(2).move_higher
408
+ assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
409
+
410
+ ListMixin.find(1).move_to_bottom
411
+ assert_equal [2, 3, 4, 1], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
412
+
413
+ ListMixin.find(1).move_to_top
414
+ assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
415
+
416
+ ListMixin.find(2).move_to_bottom
417
+ assert_equal [1, 3, 4, 2], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
418
+
419
+ ListMixin.find(4).move_to_top
420
+ assert_equal [4, 1, 3, 2], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
421
+ end
422
+
423
+ def test_move_to_bottom_with_next_to_last_item
424
+ assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
425
+ ListMixin.find(3).move_to_bottom
426
+ assert_equal [1, 2, 4, 3], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
427
+ end
428
+
429
+ def test_next_prev
430
+ assert_equal ListMixin.find(2), ListMixin.find(1).lower_item
431
+ assert_nil ListMixin.find(1).higher_item
432
+ assert_equal ListMixin.find(3), ListMixin.find(4).higher_item
433
+ assert_nil ListMixin.find(4).lower_item
434
+ end
435
+
436
+ def test_injection
437
+ item = ListMixin.new("parent_id"=>1)
438
+ assert_equal '"mixins"."parent_id" = 1', item.scope_condition
439
+ assert_equal "pos", item.position_column
440
+ end
441
+
442
+ def test_insert_at
443
+ new = ListMixin.create("parent_id" => 20)
444
+ assert_equal 1, new.pos
445
+
446
+ new = ListMixinSub1.create("parent_id" => 20)
447
+ assert_equal 2, new.pos
448
+
449
+ new = ListMixinSub2.create("parent_id" => 20)
450
+ assert_equal 3, new.pos
451
+
452
+ new4 = ListMixin.create("parent_id" => 20)
453
+ assert_equal 4, new4.pos
454
+
455
+ new4.insert_at(3)
456
+ assert_equal 3, new4.pos
457
+
458
+ new.reload
459
+ assert_equal 4, new.pos
460
+
461
+ new.insert_at(2)
462
+ assert_equal 2, new.pos
463
+
464
+ new4.reload
465
+ assert_equal 4, new4.pos
466
+
467
+ new5 = ListMixinSub1.create("parent_id" => 20)
468
+ assert_equal 5, new5.pos
469
+
470
+ new5.insert_at(1)
471
+ assert_equal 1, new5.pos
472
+
473
+ new4.reload
474
+ assert_equal 5, new4.pos
475
+ end
476
+
477
+ def test_delete_middle
478
+ assert_equal [1, 2, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
479
+
480
+ ListMixin.find(2).destroy
481
+
482
+ assert_equal [1, 3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
483
+
484
+ assert_equal 1, ListMixin.find(1).pos
485
+ assert_equal 2, ListMixin.find(3).pos
486
+ assert_equal 3, ListMixin.find(4).pos
487
+
488
+ ListMixin.find(1).destroy
489
+
490
+ assert_equal [3, 4], ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos').map(&:id)
491
+
492
+ assert_equal 1, ListMixin.find(3).pos
493
+ assert_equal 2, ListMixin.find(4).pos
494
+ end
495
+
496
+ end
497
+
498
+ class ArrayScopeListTest < Test::Unit::TestCase
499
+
500
+ def setup
501
+ setup_db
502
+ (1..4).each { |counter| ArrayScopeListMixin.create! :pos => counter, :parent_id => 5, :parent_type => 'ParentClass' }
503
+ end
504
+
505
+ def teardown
506
+ teardown_db
507
+ end
508
+
509
+ def test_reordering
510
+ assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
511
+
512
+ ArrayScopeListMixin.find(2).move_lower
513
+ assert_equal [1, 3, 2, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
514
+
515
+ ArrayScopeListMixin.find(2).move_higher
516
+ assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
517
+
518
+ ArrayScopeListMixin.find(1).move_to_bottom
519
+ assert_equal [2, 3, 4, 1], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
520
+
521
+ ArrayScopeListMixin.find(1).move_to_top
522
+ assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
523
+
524
+ ArrayScopeListMixin.find(2).move_to_bottom
525
+ assert_equal [1, 3, 4, 2], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
526
+
527
+ ArrayScopeListMixin.find(4).move_to_top
528
+ assert_equal [4, 1, 3, 2], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
529
+ end
530
+
531
+ def test_move_to_bottom_with_next_to_last_item
532
+ assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
533
+ ArrayScopeListMixin.find(3).move_to_bottom
534
+ assert_equal [1, 2, 4, 3], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
535
+ end
536
+
537
+ def test_next_prev
538
+ assert_equal ArrayScopeListMixin.find(2), ArrayScopeListMixin.find(1).lower_item
539
+ assert_nil ArrayScopeListMixin.find(1).higher_item
540
+ assert_equal ArrayScopeListMixin.find(3), ArrayScopeListMixin.find(4).higher_item
541
+ assert_nil ArrayScopeListMixin.find(4).lower_item
542
+ end
543
+
544
+ def test_injection
545
+ item = ArrayScopeListMixin.new(:parent_id => 1, :parent_type => 'ParentClass')
546
+ assert_equal '"mixins"."parent_id" = 1 AND "mixins"."parent_type" = \'ParentClass\'', item.scope_condition
547
+ assert_equal "pos", item.position_column
548
+ end
549
+
550
+ def test_insert
551
+ new = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass')
552
+ assert_equal 1, new.pos
553
+ assert new.first?
554
+ assert new.last?
555
+
556
+ new = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass')
557
+ assert_equal 2, new.pos
558
+ assert !new.first?
559
+ assert new.last?
560
+
561
+ new = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass')
562
+ assert_equal 3, new.pos
563
+ assert !new.first?
564
+ assert new.last?
565
+
566
+ new = ArrayScopeListMixin.create(:parent_id => 0, :parent_type => 'ParentClass')
567
+ assert_equal 1, new.pos
568
+ assert new.first?
569
+ assert new.last?
570
+ end
571
+
572
+ def test_insert_at
573
+ new = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass')
574
+ assert_equal 1, new.pos
575
+
576
+ new = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass')
577
+ assert_equal 2, new.pos
578
+
579
+ new = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass')
580
+ assert_equal 3, new.pos
581
+
582
+ new4 = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass')
583
+ assert_equal 4, new4.pos
584
+
585
+ new4.insert_at(3)
586
+ assert_equal 3, new4.pos
587
+
588
+ new.reload
589
+ assert_equal 4, new.pos
590
+
591
+ new.insert_at(2)
592
+ assert_equal 2, new.pos
593
+
594
+ new4.reload
595
+ assert_equal 4, new4.pos
596
+
597
+ new5 = ArrayScopeListMixin.create(:parent_id => 20, :parent_type => 'ParentClass')
598
+ assert_equal 5, new5.pos
599
+
600
+ new5.insert_at(1)
601
+ assert_equal 1, new5.pos
602
+
603
+ new4.reload
604
+ assert_equal 5, new4.pos
605
+ end
606
+
607
+ def test_delete_middle
608
+ assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
609
+
610
+ ArrayScopeListMixin.find(2).destroy
611
+
612
+ assert_equal [1, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
613
+
614
+ assert_equal 1, ArrayScopeListMixin.find(1).pos
615
+ assert_equal 2, ArrayScopeListMixin.find(3).pos
616
+ assert_equal 3, ArrayScopeListMixin.find(4).pos
617
+
618
+ ArrayScopeListMixin.find(1).destroy
619
+
620
+ assert_equal [3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
621
+
622
+ assert_equal 1, ArrayScopeListMixin.find(3).pos
623
+ assert_equal 2, ArrayScopeListMixin.find(4).pos
624
+ end
625
+
626
+ def test_remove_from_list_should_then_fail_in_list?
627
+ assert_equal true, ArrayScopeListMixin.find(1).in_list?
628
+ ArrayScopeListMixin.find(1).remove_from_list
629
+ assert_equal false, ArrayScopeListMixin.find(1).in_list?
630
+ end
631
+
632
+ def test_remove_from_list_should_set_position_to_nil
633
+ assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
634
+
635
+ ArrayScopeListMixin.find(2).remove_from_list
636
+
637
+ assert_equal [2, 1, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
638
+
639
+ assert_equal 1, ArrayScopeListMixin.find(1).pos
640
+ assert_equal nil, ArrayScopeListMixin.find(2).pos
641
+ assert_equal 2, ArrayScopeListMixin.find(3).pos
642
+ assert_equal 3, ArrayScopeListMixin.find(4).pos
643
+ end
644
+
645
+ def test_remove_before_destroy_does_not_shift_lower_items_twice
646
+ assert_equal [1, 2, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
647
+
648
+ ArrayScopeListMixin.find(2).remove_from_list
649
+ ArrayScopeListMixin.find(2).destroy
650
+
651
+ assert_equal [1, 3, 4], ArrayScopeListMixin.find(:all, :conditions => "parent_id = 5 AND parent_type = 'ParentClass'", :order => 'pos').map(&:id)
652
+
653
+ assert_equal 1, ArrayScopeListMixin.find(1).pos
654
+ assert_equal 2, ArrayScopeListMixin.find(3).pos
655
+ assert_equal 3, ArrayScopeListMixin.find(4).pos
656
+ end
657
+
658
+ end
659
+