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