acts_as_list 0.7.4 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,50 @@
1
+ module ActiveRecord
2
+ module Acts
3
+ module List
4
+ module NoUpdate
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+ # Lets you selectively disable all act_as_list database updates
9
+ # for the duration of a block.
10
+ #
11
+ # ==== Examples
12
+ # ActiveRecord::Acts::List.acts_as_list_no_update do
13
+ # TodoList....
14
+ # end
15
+ #
16
+ # TodoList.acts_as_list_no_update do
17
+ # TodoList....
18
+ # end
19
+ #
20
+ def acts_as_list_no_update(&block)
21
+ NoUpdate.apply_to(self, &block)
22
+ end
23
+ end
24
+
25
+ class << self
26
+ def apply_to(klass)
27
+ klasses.push(klass)
28
+ yield
29
+ ensure
30
+ klasses.pop
31
+ end
32
+
33
+ def applied_to?(klass)
34
+ klasses.any? { |k| k >= klass }
35
+ end
36
+
37
+ private
38
+
39
+ def klasses
40
+ Thread.current[:act_as_list_no_update] ||= []
41
+ end
42
+ end
43
+
44
+ def act_as_list_no_update?
45
+ NoUpdate.applied_to?(self.class)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,49 @@
1
+ module ActiveRecord::Acts::List::ScopeMethodDefiner #:nodoc:
2
+ extend ActiveSupport::Inflector
3
+
4
+ def self.call(caller_class, scope)
5
+ scope = idify(scope) if scope.is_a?(Symbol)
6
+
7
+ caller_class.class_eval do
8
+ define_method :scope_name do
9
+ scope
10
+ end
11
+
12
+ if scope.is_a?(Symbol)
13
+ define_method :scope_condition do
14
+ { scope => send(:"#{scope}") }
15
+ end
16
+
17
+ define_method :scope_changed? do
18
+ changed.include?(scope_name.to_s)
19
+ end
20
+ elsif scope.is_a?(Array)
21
+ define_method :scope_condition do
22
+ scope.inject({}) do |hash, column|
23
+ hash.merge!({ column.to_sym => read_attribute(column.to_sym) })
24
+ end
25
+ end
26
+
27
+ define_method :scope_changed? do
28
+ (scope_condition.keys & changed.map(&:to_sym)).any?
29
+ end
30
+ else
31
+ define_method :scope_condition do
32
+ eval "%{#{scope}}"
33
+ end
34
+
35
+ define_method :scope_changed? do
36
+ false
37
+ end
38
+ end
39
+
40
+ self.scope :in_list, lambda { where("#{quoted_position_column_with_table_name} IS NOT NULL") }
41
+ end
42
+ end
43
+
44
+ def self.idify(name)
45
+ return name if name.to_s =~ /_id$/
46
+
47
+ foreign_key(name).to_sym
48
+ end
49
+ end
@@ -0,0 +1,21 @@
1
+ module ActiveRecord::Acts::List::SequentialUpdatesMethodDefiner #:nodoc:
2
+ def self.call(caller_class, column, sequential_updates_option)
3
+ caller_class.class_eval do
4
+ define_method :sequential_updates? do
5
+ if !defined?(@sequential_updates)
6
+ if sequential_updates_option.nil?
7
+ table_exists = caller_class.connection.table_exists?(caller_class.table_name)
8
+ index_exists = caller_class.connection.index_exists?(caller_class.table_name, column, unique: true)
9
+ @sequential_updates = table_exists && index_exists
10
+ else
11
+ @sequential_updates = sequential_updates_option
12
+ end
13
+ else
14
+ @sequential_updates
15
+ end
16
+ end
17
+
18
+ private :sequential_updates?
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ module ActiveRecord::Acts::List::TopOfListMethodDefiner #:nodoc:
2
+ def self.call(caller_class, top_of_list)
3
+ caller_class.class_eval do
4
+ define_singleton_method :acts_as_list_top do
5
+ top_of_list.to_i
6
+ end
7
+
8
+ define_method :acts_as_list_top do
9
+ top_of_list.to_i
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,7 +1,7 @@
1
1
  module ActiveRecord
2
2
  module Acts
3
3
  module List
4
- VERSION = '0.7.4'
4
+ VERSION = '0.9.0'
5
5
  end
6
6
  end
7
7
  end
data/lib/acts_as_list.rb CHANGED
@@ -1,15 +1,9 @@
1
1
  require 'acts_as_list/active_record/acts/list'
2
-
3
- module ActsAsList
4
- if defined?(Rails::Railtie)
5
- class Railtie < Rails::Railtie
6
- initializer 'acts_as_list.insert_into_active_record' do
7
- ActiveSupport.on_load :active_record do
8
- ActiveRecord::Base.send(:include, ActiveRecord::Acts::List)
9
- end
10
- end
11
- end
12
- else
13
- ActiveRecord::Base.send(:include, ActiveRecord::Acts::List) if defined?(ActiveRecord)
14
- end
15
- end
2
+ require "acts_as_list/active_record/acts/column_method_definer"
3
+ require "acts_as_list/active_record/acts/scope_method_definer"
4
+ require "acts_as_list/active_record/acts/top_of_list_method_definer"
5
+ require "acts_as_list/active_record/acts/add_new_at_method_definer"
6
+ require "acts_as_list/active_record/acts/aux_method_definer"
7
+ require "acts_as_list/active_record/acts/callback_definer"
8
+ require 'acts_as_list/active_record/acts/no_update'
9
+ require "acts_as_list/active_record/acts/sequential_updates_method_definer"
data/test/database.yml ADDED
@@ -0,0 +1,16 @@
1
+ sqlite:
2
+ adapter: sqlite3
3
+ database: "file:memdb1?mode=memory&cache=shared"
4
+
5
+ mysql:
6
+ adapter: mysql2
7
+ username: root
8
+ password:
9
+ database: acts_as_list
10
+
11
+ postgresql:
12
+ adapter: postgresql
13
+ username: postgres
14
+ password:
15
+ database: acts_as_list
16
+ min_messages: ERROR
data/test/helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # $DEBUG = true
2
+
1
3
  require "rubygems"
2
4
  require "bundler/setup"
3
5
  begin
@@ -12,10 +14,20 @@ require "minitest/autorun"
12
14
  require "#{File.dirname(__FILE__)}/../init"
13
15
 
14
16
  if defined?(ActiveRecord::VERSION) &&
15
- ActiveRecord::VERSION::MAJOR > 4 ||
16
- (ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR >= 2)
17
+ ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR >= 2
17
18
 
19
+ # Was removed in Rails 5 and is effectively true.
18
20
  ActiveRecord::Base.raise_in_transactional_callbacks = true
19
21
  end
20
22
 
21
23
  require "shared"
24
+
25
+ # ActiveRecord::Base.logger = Logger.new(STDOUT)
26
+
27
+ def assert_equal_or_nil(a, b)
28
+ if a.nil?
29
+ assert_nil b
30
+ else
31
+ assert_equal a, b
32
+ end
33
+ end
data/test/shared.rb CHANGED
@@ -6,4 +6,5 @@ module Shared
6
6
  autoload :ArrayScopeList, 'shared_array_scope_list'
7
7
  autoload :TopAddition, 'shared_top_addition'
8
8
  autoload :NoAddition, 'shared_no_addition'
9
+ autoload :Quoting, 'shared_quoting'
9
10
  end
@@ -25,7 +25,7 @@ module Shared
25
25
 
26
26
  ArrayScopeListMixin.where(id: 4).first.move_to_top
27
27
  assert_equal [4, 1, 3, 2], ArrayScopeListMixin.where(parent_id: 5, parent_type: 'ParentClass').order('pos').map(&:id)
28
-
28
+
29
29
  ArrayScopeListMixin.where(id: 4).first.insert_at(4)
30
30
  assert_equal [1, 3, 2, 4], ArrayScopeListMixin.where(parent_id: 5, parent_type: 'ParentClass').order('pos').map(&:id)
31
31
  assert_equal [1, 2, 3, 4], ArrayScopeListMixin.where(parent_id: 5, parent_type: 'ParentClass').order('pos').map(&:pos)
@@ -60,6 +60,11 @@ module Shared
60
60
  assert !new.first?
61
61
  assert new.last?
62
62
 
63
+ new = ArrayScopeListMixin.acts_as_list_no_update { ArrayScopeListMixin.create(parent_id: 20, parent_type: 'ParentClass') }
64
+ assert_equal_or_nil $default_position,new.pos
65
+ assert_equal $default_position.is_a?(Fixnum), new.first?
66
+ assert !new.last?
67
+
63
68
  new = ArrayScopeListMixin.create(parent_id: 20, parent_type: 'ParentClass')
64
69
  assert_equal 3, new.pos
65
70
  assert !new.first?
@@ -81,6 +86,9 @@ module Shared
81
86
  new = ArrayScopeListMixin.create(parent_id: 20, parent_type: 'ParentClass')
82
87
  assert_equal 3, new.pos
83
88
 
89
+ new_noup = ArrayScopeListMixin.acts_as_list_no_update { ArrayScopeListMixin.create(parent_id: 20, parent_type: 'ParentClass') }
90
+ assert_equal_or_nil $default_position,new_noup.pos
91
+
84
92
  new4 = ArrayScopeListMixin.create(parent_id: 20, parent_type: 'ParentClass')
85
93
  assert_equal 4, new4.pos
86
94
 
@@ -104,6 +112,9 @@ module Shared
104
112
 
105
113
  new4.reload
106
114
  assert_equal 5, new4.pos
115
+
116
+ new_noup.reload
117
+ assert_equal_or_nil $default_position, new_noup.pos
107
118
  end
108
119
 
109
120
  def test_delete_middle
@@ -123,6 +134,12 @@ module Shared
123
134
 
124
135
  assert_equal 1, ArrayScopeListMixin.where(id: 3).first.pos
125
136
  assert_equal 2, ArrayScopeListMixin.where(id: 4).first.pos
137
+
138
+ ArrayScopeListMixin.acts_as_list_no_update { ArrayScopeListMixin.where(id: 3).first.destroy }
139
+
140
+ assert_equal [4], ArrayScopeListMixin.where(parent_id: 5, parent_type: 'ParentClass').order('pos').map(&:id)
141
+
142
+ assert_equal 2, ArrayScopeListMixin.where(id: 4).first.pos
126
143
  end
127
144
 
128
145
  def test_remove_from_list_should_then_fail_in_list?
@@ -136,10 +153,8 @@ module Shared
136
153
 
137
154
  ArrayScopeListMixin.where(id: 2).first.remove_from_list
138
155
 
139
- assert_equal [2, 1, 3, 4], ArrayScopeListMixin.where(parent_id: 5, parent_type: 'ParentClass').order('pos').map(&:id)
140
-
141
156
  assert_equal 1, ArrayScopeListMixin.where(id: 1).first.pos
142
- assert_equal nil, ArrayScopeListMixin.where(id: 2).first.pos
157
+ assert_nil ArrayScopeListMixin.where(id: 2).first.pos
143
158
  assert_equal 2, ArrayScopeListMixin.where(id: 3).first.pos
144
159
  assert_equal 3, ArrayScopeListMixin.where(id: 4).first.pos
145
160
  end
data/test/shared_list.rb CHANGED
@@ -60,6 +60,11 @@ module Shared
60
60
  assert !new.first?
61
61
  assert new.last?
62
62
 
63
+ new = ListMixin.acts_as_list_no_update { ListMixin.create(parent_id: 20) }
64
+ assert_equal_or_nil $default_position, new.pos
65
+ assert_equal $default_position.is_a?(Fixnum), new.first?
66
+ assert !new.last?
67
+
63
68
  new = ListMixin.create(parent_id: 20)
64
69
  assert_equal 3, new.pos
65
70
  assert !new.first?
@@ -81,6 +86,9 @@ module Shared
81
86
  new = ListMixin.create(parent_id: 20)
82
87
  assert_equal 3, new.pos
83
88
 
89
+ new_noup = ListMixin.acts_as_list_no_update { ListMixin.create(parent_id: 20) }
90
+ assert_equal_or_nil $default_position, new_noup.pos
91
+
84
92
  new4 = ListMixin.create(parent_id: 20)
85
93
  assert_equal 4, new4.pos
86
94
 
@@ -104,13 +112,21 @@ module Shared
104
112
 
105
113
  new4.reload
106
114
  assert_equal 5, new4.pos
115
+
116
+ new_noup.reload
117
+ assert_equal_or_nil $default_position, new_noup.pos
118
+
119
+ last1 = ListMixin.where('pos IS NOT NULL').order('pos').last
120
+ last2 = ListMixin.where('pos IS NOT NULL').order('pos').last
121
+ last1.insert_at(1)
122
+ last2.insert_at(1)
123
+ pos_list = ListMixin.where(parent_id: 20).order("pos ASC#{' NULLS FIRST' if ENV['DB'] == 'postgresql'}").map(&:pos)
124
+ assert_equal [$default_position, 1, 2, 3, 4, 5], pos_list
107
125
  end
108
126
 
109
127
  def test_delete_middle
110
128
  assert_equal [1, 2, 3, 4], ListMixin.where(parent_id: 5).order('pos').map(&:id)
111
129
 
112
-
113
-
114
130
  ListMixin.where(id: 2).first.destroy
115
131
 
116
132
  assert_equal [1, 3, 4], ListMixin.where(parent_id: 5).order('pos').map(&:id)
@@ -125,6 +141,12 @@ module Shared
125
141
 
126
142
  assert_equal 1, ListMixin.where(id: 3).first.pos
127
143
  assert_equal 2, ListMixin.where(id: 4).first.pos
144
+
145
+ ListMixin.acts_as_list_no_update { ListMixin.where(id: 3).first.destroy }
146
+
147
+ assert_equal [4], ListMixin.where(parent_id: 5).order('pos').map(&:id)
148
+
149
+ assert_equal 2, ListMixin.where(id: 4).first.pos
128
150
  end
129
151
 
130
152
  def test_with_string_based_scope
@@ -142,7 +164,7 @@ module Shared
142
164
 
143
165
  def test_update_position_when_scope_changes
144
166
  assert_equal [1, 2, 3, 4], ListMixin.where(parent_id: 5).order('pos').map(&:id)
145
- parent = ListMixin.create(parent_id: 6)
167
+ ListMixin.create(parent_id: 6)
146
168
 
147
169
  ListMixin.where(id: 2).first.move_within_scope(6)
148
170
 
@@ -169,10 +191,8 @@ module Shared
169
191
 
170
192
  ListMixin.where(id: 2).first.remove_from_list
171
193
 
172
- assert_equal [2, 1, 3, 4], ListMixin.where(parent_id: 5).order('pos').map(&:id)
173
-
174
194
  assert_equal 1, ListMixin.where(id: 1).first.pos
175
- assert_equal nil, ListMixin.where(id: 2).first.pos
195
+ assert_nil ListMixin.where(id: 2).first.pos
176
196
  assert_equal 2, ListMixin.where(id: 3).first.pos
177
197
  assert_equal 3, ListMixin.where(id: 4).first.pos
178
198
  end
@@ -237,14 +257,30 @@ module Shared
237
257
 
238
258
  assert_equal [5, 1, 2, 3, 4], ListMixin.where(parent_id: 5).order('pos').map(&:id)
239
259
 
260
+ new6 = ListMixin.new(parent_id: 5)
261
+ new6.pos = 3
262
+ new6.save!
263
+ assert_equal 3, new6.pos
264
+ assert !new6.first?
265
+ assert !new6.last?
266
+
267
+ assert_equal [5, 1, 6, 2, 3, 4], ListMixin.where(parent_id: 5).order('pos').map(&:id)
268
+
240
269
  new = ListMixin.new(parent_id: 5)
241
270
  new.pos = 3
242
- new.save!
271
+ ListMixin.acts_as_list_no_update { new.save! }
243
272
  assert_equal 3, new.pos
273
+ assert_equal 3, new6.pos
244
274
  assert !new.first?
245
275
  assert !new.last?
246
276
 
247
- assert_equal [5, 1, 6, 2, 3, 4], ListMixin.where(parent_id: 5).order('pos').map(&:id)
277
+ assert_equal [5, 1, 6, 7, 2, 3, 4], ListMixin.where(parent_id: 5).order('pos, id').map(&:id)
278
+ end
279
+
280
+ def test_non_persisted_records_dont_get_lock_called
281
+ new = ListMixin.new(parent_id: 5)
282
+
283
+ new.destroy
248
284
  end
249
285
  end
250
286
  end
@@ -43,6 +43,36 @@ module Shared
43
43
  assert_nil ListMixin.where(id: 4).first.lower_item
44
44
  end
45
45
 
46
+ def test_next_prev_not_regular_sequence
47
+ ListMixin.all.each do |item|
48
+ item.update_attributes(pos: item.pos * 5)
49
+ end
50
+
51
+ assert_equal [1, 2, 3, 4], ListMixin.where(parent_id: 5000).order('pos').map(&:id)
52
+ assert_equal [5, 10, 15, 20], ListMixin.where(parent_id: 5000).order('id').map(&:pos)
53
+
54
+ ListMixin.where(id: 2).first.move_lower
55
+ assert_equal [1, 3, 2, 4], ListMixin.where(parent_id: 5000).order('pos').map(&:id)
56
+ assert_equal [5, 15, 10, 20], ListMixin.where(parent_id: 5000).order('id').map(&:pos)
57
+
58
+
59
+ ListMixin.where(id: 2).first.move_higher
60
+ assert_equal [1, 2, 3, 4], ListMixin.where(parent_id: 5000).order('pos').map(&:id)
61
+ assert_equal [5, 10, 15, 20], ListMixin.where(parent_id: 5000).order('id').map(&:pos)
62
+
63
+ ListMixin.where(id: 1).first.move_to_bottom
64
+ assert_equal [2, 3, 4, 1], ListMixin.where(parent_id: 5000).order('pos').map(&:id)
65
+
66
+ ListMixin.where(id: 1).first.move_to_top
67
+ assert_equal [1, 2, 3, 4], ListMixin.where(parent_id: 5000).order('pos').map(&:id)
68
+
69
+ ListMixin.where(id: 2).first.move_to_bottom
70
+ assert_equal [1, 3, 4, 2], ListMixin.where(parent_id: 5000).order('pos').map(&:id)
71
+
72
+ ListMixin.where(id: 4).first.move_to_top
73
+ assert_equal [4, 1, 3, 2], ListMixin.where(parent_id: 5000).order('pos').map(&:id)
74
+ end
75
+
46
76
  def test_next_prev_groups
47
77
  li1 = ListMixin.where(id: 1).first
48
78
  li2 = ListMixin.where(id: 2).first
@@ -53,12 +83,29 @@ module Shared
53
83
  assert_equal [li2, li3], li1.lower_items(2)
54
84
  assert_equal [], li4.lower_items
55
85
 
56
- assert_equal [li1, li2], li3.higher_items
86
+ assert_equal [li2, li1], li3.higher_items
57
87
  assert_equal [li1], li2.higher_items
58
- assert_equal [li2, li3], li4.higher_items(2)
88
+ assert_equal [li3, li2], li4.higher_items(2)
59
89
  assert_equal [], li1.higher_items
60
90
  end
61
91
 
92
+ def test_next_prev_groups_with_same_position
93
+ li1 = ListMixin.where(id: 1).first
94
+ li2 = ListMixin.where(id: 2).first
95
+ li3 = ListMixin.where(id: 3).first
96
+ li4 = ListMixin.where(id: 4).first
97
+
98
+ li3.update_column(:pos, 2) # Make the same position as li2
99
+
100
+ assert_equal [1, 2, 2, 4], ListMixin.order(:pos).pluck(:pos)
101
+
102
+ assert_equal [li3, li4], li2.lower_items
103
+ assert_equal [li2, li4], li3.lower_items
104
+
105
+ assert_equal [li3, li1], li2.higher_items
106
+ assert_equal [li2, li1], li3.higher_items
107
+ end
108
+
62
109
  def test_injection
63
110
  item = ListMixin.new("parent_id"=>1)
64
111
  assert_equal({ parent_id: 1 }, item.scope_condition)
@@ -75,6 +122,9 @@ module Shared
75
122
  new = ListMixinSub1.create("parent_id" => 20)
76
123
  assert_equal 3, new.pos
77
124
 
125
+ new_noup = ListMixinSub1.acts_as_list_no_update { ListMixinSub1.create("parent_id" => 20) }
126
+ assert_equal_or_nil $default_position, new_noup.pos
127
+
78
128
  new4 = ListMixin.create("parent_id" => 20)
79
129
  assert_equal 4, new4.pos
80
130
 
@@ -98,6 +148,9 @@ module Shared
98
148
 
99
149
  new4.reload
100
150
  assert_equal 5, new4.pos
151
+
152
+ new_noup.reload
153
+ assert_equal_or_nil $default_position, new_noup.pos
101
154
  end
102
155
 
103
156
  def test_delete_middle
@@ -117,6 +170,12 @@ module Shared
117
170
 
118
171
  assert_equal 1, ListMixin.where(id: 3).first.pos
119
172
  assert_equal 2, ListMixin.where(id: 4).first.pos
173
+
174
+ ListMixin.acts_as_list_no_update { ListMixin.where(id: 3).first.destroy }
175
+
176
+ assert_equal [4], ListMixin.where(parent_id: 5000).order('pos').map(&:id)
177
+
178
+ assert_equal 2, ListMixin.where(id: 4).first.pos
120
179
  end
121
180
 
122
181
  def test_acts_as_list_class
@@ -6,11 +6,11 @@ module Shared
6
6
 
7
7
  def test_insert
8
8
  new = NoAdditionMixin.create(parent_id: 20)
9
- assert_equal nil, new.pos
9
+ assert_nil new.pos
10
10
  assert !new.in_list?
11
11
 
12
12
  new = NoAdditionMixin.create(parent_id: 20)
13
- assert_equal nil, new.pos
13
+ assert_nil new.pos
14
14
  end
15
15
 
16
16
  def test_update_does_not_add_to_list
@@ -21,5 +21,16 @@ module Shared
21
21
  assert !new.in_list?
22
22
  end
23
23
 
24
+ def test_update_scope_does_not_add_to_list
25
+ new = NoAdditionMixin.create
26
+
27
+ new.update_attribute(:parent_id, 20)
28
+ new.reload
29
+ assert !new.in_list?
30
+
31
+ new.update_attribute(:parent_id, 5)
32
+ new.reload
33
+ assert !new.in_list?
34
+ end
24
35
  end
25
36
  end
@@ -0,0 +1,21 @@
1
+ module Shared
2
+ module Quoting
3
+
4
+ def setup
5
+ 3.times { |counter| QuotedList.create! order: counter }
6
+ end
7
+
8
+ def test_create
9
+ assert_equal QuotedList.in_list.size, 3
10
+ end
11
+
12
+ # This test execute raw queries involving table name
13
+ def test_moving
14
+ item = QuotedList.first
15
+ item.higher_items
16
+ item.lower_items
17
+ item.send :bottom_item # Part of private api
18
+ end
19
+
20
+ end
21
+ end
@@ -4,23 +4,26 @@ module Shared
4
4
  (1..4).each { |counter| TopAdditionMixin.create! pos: counter, parent_id: 5 }
5
5
  end
6
6
 
7
- def test_reordering
8
- assert_equal [4, 3, 2, 1], TopAdditionMixin.where(parent_id: 5).order('pos').map(&:id)
7
+ def test_setup_state
8
+ # If we explicitly define a position (as above) then that position is what gets applied
9
+ assert_equal [1, 2, 3, 4], TopAdditionMixin.where(parent_id: 5).order('pos').map(&:id)
10
+ end
9
11
 
12
+ def test_reordering
10
13
  TopAdditionMixin.where(id: 2).first.move_lower
11
- assert_equal [4, 3, 1, 2], TopAdditionMixin.where(parent_id: 5).order('pos').map(&:id)
14
+ assert_equal [1, 3, 2, 4], TopAdditionMixin.where(parent_id: 5).order('pos').map(&:id)
12
15
 
13
16
  TopAdditionMixin.where(id: 2).first.move_higher
14
- assert_equal [4, 3, 2, 1], TopAdditionMixin.where(parent_id: 5).order('pos').map(&:id)
17
+ assert_equal [1, 2, 3, 4], TopAdditionMixin.where(parent_id: 5).order('pos').map(&:id)
15
18
 
16
19
  TopAdditionMixin.where(id: 1).first.move_to_bottom
17
- assert_equal [4, 3, 2, 1], TopAdditionMixin.where(parent_id: 5).order('pos').map(&:id)
20
+ assert_equal [2, 3, 4, 1], TopAdditionMixin.where(parent_id: 5).order('pos').map(&:id)
18
21
 
19
22
  TopAdditionMixin.where(id: 1).first.move_to_top
20
- assert_equal [1, 4, 3, 2], TopAdditionMixin.where(parent_id: 5).order('pos').map(&:id)
23
+ assert_equal [1, 2, 3, 4], TopAdditionMixin.where(parent_id: 5).order('pos').map(&:id)
21
24
 
22
25
  TopAdditionMixin.where(id: 2).first.move_to_bottom
23
- assert_equal [1, 4, 3, 2], TopAdditionMixin.where(parent_id: 5).order('pos').map(&:id)
26
+ assert_equal [1, 3, 4, 2], TopAdditionMixin.where(parent_id: 5).order('pos').map(&:id)
24
27
 
25
28
  TopAdditionMixin.where(id: 4).first.move_to_top
26
29
  assert_equal [4, 1, 3, 2], TopAdditionMixin.where(parent_id: 5).order('pos').map(&:id)
@@ -43,9 +46,14 @@ module Shared
43
46
  assert new.first?
44
47
  assert !new.last?
45
48
 
49
+ new = TopAdditionMixin.acts_as_list_no_update { TopAdditionMixin.create(parent_id: 20) }
50
+ assert_equal_or_nil $default_position, new.pos
51
+ assert_equal $default_position.is_a?(Fixnum), new.first?
52
+ assert !new.last?
53
+
46
54
  new = TopAdditionMixin.create(parent_id: 20)
47
55
  assert_equal 1, new.pos
48
- assert new.first?
56
+ assert_equal $default_position.nil?, new.first?
49
57
  assert !new.last?
50
58
 
51
59
  new = TopAdditionMixin.create(parent_id: 0)
@@ -64,6 +72,9 @@ module Shared
64
72
  new = TopAdditionMixin.create(parent_id: 20)
65
73
  assert_equal 1, new.pos
66
74
 
75
+ new = TopAdditionMixin.acts_as_list_no_update { TopAdditionMixin.create(parent_id: 20) }
76
+ assert_equal_or_nil $default_position, new.pos
77
+
67
78
  new4 = TopAdditionMixin.create(parent_id: 20)
68
79
  assert_equal 1, new4.pos
69
80
 
@@ -71,16 +82,26 @@ module Shared
71
82
  assert_equal 3, new4.pos
72
83
  end
73
84
 
74
- def test_delete_middle
75
- assert_equal [4, 3, 2, 1], TopAdditionMixin.where(parent_id: 5).order('pos').map(&:id)
85
+ def test_supplied_position
86
+ new = TopAdditionMixin.create(parent_id: 20, pos: 3)
87
+ assert_equal 3, new.pos
88
+ end
76
89
 
90
+ def test_delete_middle
77
91
  TopAdditionMixin.where(id: 2).first.destroy
78
92
 
79
- assert_equal [4, 3, 1], TopAdditionMixin.where(parent_id: 5).order('pos').map(&:id)
93
+ assert_equal [1, 3, 4], TopAdditionMixin.where(parent_id: 5).order('pos').map(&:id)
80
94
 
81
- assert_equal 3, TopAdditionMixin.where(id: 1).first.pos
95
+ assert_equal 1, TopAdditionMixin.where(id: 1).first.pos
82
96
  assert_equal 2, TopAdditionMixin.where(id: 3).first.pos
83
- assert_equal 1, TopAdditionMixin.where(id: 4).first.pos
97
+ assert_equal 3, TopAdditionMixin.where(id: 4).first.pos
98
+
99
+ TopAdditionMixin.acts_as_list_no_update { TopAdditionMixin.where(id: 3).first.destroy }
100
+
101
+ assert_equal [1, 4], TopAdditionMixin.where(parent_id: 5).order('pos').map(&:id)
102
+
103
+ assert_equal 1, TopAdditionMixin.where(id: 1).first.pos
104
+ assert_equal 3, TopAdditionMixin.where(id: 4).first.pos
84
105
  end
85
106
 
86
107
  end
@@ -15,6 +15,11 @@ module Shared
15
15
  assert !new.first?
16
16
  assert new.last?
17
17
 
18
+ new = ZeroBasedMixin.acts_as_list_no_update { ZeroBasedMixin.create(parent_id: 20) }
19
+ assert_equal_or_nil $default_position, new.pos
20
+ assert !new.first?
21
+ assert !new.last?
22
+
18
23
  new = ZeroBasedMixin.create(parent_id: 20)
19
24
  assert_equal 2, new.pos
20
25
  assert !new.first?
@@ -63,6 +68,9 @@ module Shared
63
68
  new = ZeroBasedMixin.create(parent_id: 20)
64
69
  assert_equal 2, new.pos
65
70
 
71
+ new_noup = ZeroBasedMixin.acts_as_list_no_update { ZeroBasedMixin.create(parent_id: 20) }
72
+ assert_equal_or_nil $default_position, new_noup.pos
73
+
66
74
  new4 = ZeroBasedMixin.create(parent_id: 20)
67
75
  assert_equal 3, new4.pos
68
76
 
@@ -86,6 +94,9 @@ module Shared
86
94
 
87
95
  new4.reload
88
96
  assert_equal 4, new4.pos
97
+
98
+ new_noup.reload
99
+ assert_equal_or_nil $default_position, new_noup.pos
89
100
  end
90
101
  end
91
102
  end