aguids-positionable 0.2.1

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.
Files changed (74) hide show
  1. data/.document +5 -0
  2. data/.gitignore +11 -0
  3. data/LICENSE +20 -0
  4. data/README.markdown +200 -0
  5. data/Rakefile +56 -0
  6. data/VERSION +1 -0
  7. data/app/controllers/positionable_controller.rb +32 -0
  8. data/app/helpers/positionable_helper.rb +70 -0
  9. data/config/routes.rb +3 -0
  10. data/init.rb +1 -0
  11. data/lib/positionable.rb +362 -0
  12. data/positionable.gemspec +154 -0
  13. data/test/rails_root/Rakefile +10 -0
  14. data/test/rails_root/app/controllers/application_controller.rb +10 -0
  15. data/test/rails_root/app/helpers/application_helper.rb +3 -0
  16. data/test/rails_root/app/models/conditional_item.rb +3 -0
  17. data/test/rails_root/app/models/different_position_column_item.rb +3 -0
  18. data/test/rails_root/app/models/hell_on_earth_item.rb +5 -0
  19. data/test/rails_root/app/models/multiple_list_item.rb +5 -0
  20. data/test/rails_root/app/models/multiple_scoped_item.rb +3 -0
  21. data/test/rails_root/app/models/scoped_item.rb +3 -0
  22. data/test/rails_root/app/models/simple_item.rb +4 -0
  23. data/test/rails_root/config/boot.rb +110 -0
  24. data/test/rails_root/config/database.yml +22 -0
  25. data/test/rails_root/config/environment.rb +14 -0
  26. data/test/rails_root/config/environments/development.rb +17 -0
  27. data/test/rails_root/config/environments/production.rb +28 -0
  28. data/test/rails_root/config/environments/test.rb +28 -0
  29. data/test/rails_root/config/initializers/backtrace_silencers.rb +7 -0
  30. data/test/rails_root/config/initializers/inflections.rb +10 -0
  31. data/test/rails_root/config/initializers/mime_types.rb +5 -0
  32. data/test/rails_root/config/initializers/new_rails_defaults.rb +19 -0
  33. data/test/rails_root/config/initializers/session_store.rb +15 -0
  34. data/test/rails_root/config/locales/en.yml +5 -0
  35. data/test/rails_root/config/routes.rb +45 -0
  36. data/test/rails_root/db/development.sqlite3 +0 -0
  37. data/test/rails_root/db/migrate/20090702170207_create_simple_items.rb +13 -0
  38. data/test/rails_root/db/migrate/20090703071830_create_scoped_items.rb +14 -0
  39. data/test/rails_root/db/migrate/20090706180046_create_different_position_column_items.rb +13 -0
  40. data/test/rails_root/db/migrate/20090706200318_create_conditional_items.rb +14 -0
  41. data/test/rails_root/db/migrate/20090708045618_create_multiple_scoped_items.rb +15 -0
  42. data/test/rails_root/db/migrate/20090708174947_create_multiple_list_items.rb +15 -0
  43. data/test/rails_root/db/migrate/20090708183550_create_hell_on_earth_items.rb +19 -0
  44. data/test/rails_root/db/schema.rb +68 -0
  45. data/test/rails_root/script/about +4 -0
  46. data/test/rails_root/script/console +3 -0
  47. data/test/rails_root/script/dbconsole +3 -0
  48. data/test/rails_root/script/destroy +3 -0
  49. data/test/rails_root/script/generate +3 -0
  50. data/test/rails_root/script/performance/benchmarker +3 -0
  51. data/test/rails_root/script/performance/profiler +3 -0
  52. data/test/rails_root/script/plugin +3 -0
  53. data/test/rails_root/script/runner +3 -0
  54. data/test/rails_root/script/server +3 -0
  55. data/test/rails_root/test/conditional_tests.rb +28 -0
  56. data/test/rails_root/test/functional/positionable_controller_test.rb +50 -0
  57. data/test/rails_root/test/performance/browsing_test.rb +9 -0
  58. data/test/rails_root/test/scoped_tests.rb +53 -0
  59. data/test/rails_root/test/simple_gap_tests.rb +17 -0
  60. data/test/rails_root/test/simple_gapless_tests.rb +52 -0
  61. data/test/rails_root/test/simple_tests.rb +185 -0
  62. data/test/rails_root/test/test_helper.rb +37 -0
  63. data/test/rails_root/test/unit/conditional_item_test.rb +36 -0
  64. data/test/rails_root/test/unit/different_position_column_item_test.rb +21 -0
  65. data/test/rails_root/test/unit/eval_support_test.rb +62 -0
  66. data/test/rails_root/test/unit/hell_on_earth_item_test.rb +71 -0
  67. data/test/rails_root/test/unit/helpers/positionable_helper_test.rb +69 -0
  68. data/test/rails_root/test/unit/multiple_list_item_test.rb +60 -0
  69. data/test/rails_root/test/unit/multiple_scoped_item_test.rb +34 -0
  70. data/test/rails_root/test/unit/scoped_item_test.rb +22 -0
  71. data/test/rails_root/test/unit/scoped_item_with_gaps_test.rb +25 -0
  72. data/test/rails_root/test/unit/simple_item_test.rb +21 -0
  73. data/test/rails_root/test/unit/simple_item_with_gaps_test.rb +24 -0
  74. metadata +172 -0
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+ require 'performance_test_help'
3
+
4
+ # Profiling results for each test method are written to tmp/performance.
5
+ class BrowsingTest < ActionController::PerformanceTest
6
+ def test_homepage
7
+ get '/'
8
+ end
9
+ end
@@ -0,0 +1,53 @@
1
+ module ScopedTests
2
+
3
+ def test_scoped_insert
4
+ item = create(170)
5
+ assert item.in_list?
6
+ assert item.first?
7
+ assert item.last?
8
+ assert_equal 1, item.list_position
9
+ end
10
+
11
+ # Unescoped Tests
12
+ def test_unescoped_insert
13
+ item = create(nil)
14
+ assert item.in_list?
15
+ assert item.first?
16
+ assert item.last?
17
+ assert_equal 1, item.list_position
18
+
19
+ item_2 = create(nil)
20
+ assert item_2.in_list?
21
+ assert !item_2.first?
22
+ assert item_2.last?
23
+ assert_equal 2, item_2.list_position
24
+ end
25
+
26
+ # Scope Changed Tests
27
+ def test_scoped_should_remove_from_previous_list_after_scope_change
28
+ @items.second.parent_id = 170; @items.second.save
29
+ assert @items.second.in_list?
30
+ assert @items.second.first?
31
+ assert_equal_ids [1,3,4]
32
+ end
33
+
34
+ def test_scoped_should_add_to_new_list_bottoms_position
35
+ @items.second.parent_id = 170; @items.second.save
36
+ @items.second.parent_id = @items.first.parent_id; @items.second.save
37
+ assert @items.second.last?
38
+ assert_equal_ids [1,3,4,2]
39
+ end
40
+
41
+ def test_scoped_changed_to_nil_scope
42
+ @items.second.parent_id = nil; @items.second.save
43
+ assert @items.second.in_list?
44
+ assert @items.second.first?
45
+ end
46
+
47
+ def test_scoped_changed_from_nil
48
+ @items.second.parent_id = nil; @items.second.save
49
+ @items.second.parent_id = @items.first.parent_id; @items.second.save
50
+ assert @items.second.last?
51
+ assert_equal_ids [1,3,4,2]
52
+ end
53
+ end
@@ -0,0 +1,17 @@
1
+ module SimpleGapTests
2
+ # Insert and Remove Tests
3
+ def test_simple_gap_items_should_have_gaps
4
+ assert_equal @ids, ordered_ids
5
+ 1.upto(3) do |index|
6
+ assert @items[index].in_list?
7
+ assert_not_equal @items[index-1].list_position + 1, @items[index].list_position
8
+ end
9
+ end
10
+
11
+ # TODO: test move_up move_down with gaps
12
+ # => Should move clear gaps?
13
+
14
+ # TODO: test insert_at and gaps
15
+ # => Should it take the place of the gap?
16
+ # => or should it shift lower items despite the gap
17
+ end
@@ -0,0 +1,52 @@
1
+ module SimpleGaplessTests
2
+ # Insert and Remove Tests
3
+ def test_simple_gapless_insert_on_list_after_create
4
+ assert_equal @ids, ordered_ids
5
+ @items.each_with_index do |item, index|
6
+ assert item.in_list?
7
+ end
8
+ assert_equal [1,2,3,4], positions
9
+ end
10
+
11
+ def test_simple_gapless_insert_at
12
+ @items.fourth.insert_at(@items.second.list_position)
13
+ # List: [1,4,2,3]
14
+ assert_equal [1,3,4,2], positions
15
+
16
+ @items.first.insert_at(@items.third.list_position)
17
+ # List: [4,2,3,1]
18
+ assert_equal [4,2,3,1], positions
19
+
20
+ @items.third.insert_at(@items.fourth.list_position)
21
+ # List: [3,4,2,1]
22
+ assert_equal [4,3,1,2], positions
23
+
24
+ @items.second.insert_at(@items.fourth.list_position)
25
+ # List: [3,2,4,1]
26
+ assert_equal [4,2,1,3], positions
27
+ end
28
+
29
+ def test_simple_gapless_remove_from_list
30
+ @items.second.remove_from_list
31
+ # List: [1,3,4]
32
+ assert_equal [1,nil,2,3], positions
33
+ end
34
+
35
+ def test_simple_gapless_remove_from_list_after_destroy
36
+ @items.second.destroy
37
+ # List: [1,3,4]
38
+ assert_equal [1,2,3], positions(@items.second)
39
+ end
40
+
41
+ def test_simple_gapless_remove_from_list_shifts_lower_items_up
42
+ @items.first.remove_from_list
43
+ # List: [2,3,4]
44
+ assert_equal [nil,1,2,3], positions
45
+ end
46
+
47
+ def test_simple_gapless_destroy_shifts_lower_items_up
48
+ @items.first.destroy
49
+ # List: [2,3,4]
50
+ assert_equal [1,2,3], positions(@items.first)
51
+ end
52
+ end
@@ -0,0 +1,185 @@
1
+ module SimpleTests
2
+
3
+ # Insert and Remove Tests
4
+ def test_simple_insert_at
5
+ @items.fourth.insert_at(@items.second.list_position)
6
+ reload_items
7
+ assert_equal_ids [1,4,2,3]
8
+
9
+ @items.first.insert_at(@items.third.list_position)
10
+ reload_items
11
+ assert_equal_ids [4,2,3,1]
12
+
13
+ @items.third.insert_at(@items.fourth.list_position)
14
+ reload_items
15
+ assert_equal_ids [3,4,2,1]
16
+
17
+ @items.second.insert_at(@items.fourth.list_position)
18
+ reload_items
19
+ assert_equal_ids [3,2,4,1]
20
+ end
21
+
22
+ def test_simple_insert_at_should_convert_index_higher_than_first_to_first
23
+ @items.third.insert_at(0)
24
+ assert @items.third.first?
25
+ @items.fourth.insert_at(-5)
26
+ assert @items.fourth.first?
27
+ end
28
+
29
+ def test_simple_insert_at_should_convert_index_lower_than_last_to_last
30
+ @items.second.insert_at(@items.last.list_position + 1)
31
+ assert @items.second.last?
32
+ @items.first.insert_at(40)
33
+ assert @items.first.last?
34
+ end
35
+
36
+ def test_simple_insert_at_should_insert_item_as_first_if_empty_list
37
+ @items.each { |item| item.remove_from_list }
38
+ item = @items.fourth
39
+ item.insert_at(2)
40
+ assert item.first?
41
+ assert item.last?
42
+ assert_equal 1, item.list_position
43
+ end
44
+
45
+ def test_simple_insert_at_should_accept_symbols
46
+ @items.third.insert_at(:top)
47
+ assert @items.third.first?
48
+
49
+ @items.third.insert_at(:bottom)
50
+ assert @items.third.last?
51
+
52
+ @items.fourth.insert_at(:first)
53
+ assert @items.fourth.first?
54
+
55
+ @items.fourth.insert_at(:last)
56
+ assert @items.fourth.last?
57
+ end
58
+
59
+ def test_simple_insert_at_top
60
+ @items.second.insert_at_top
61
+ assert @items.second.first?
62
+ end
63
+
64
+ def test_simple_insert_at_bottom
65
+ @items.second.insert_at_bottom
66
+ assert @items.second.last?
67
+ end
68
+
69
+ def test_simple_remove_from_list
70
+ @items.second.remove_from_list
71
+ assert !@items.second.in_list?
72
+ assert_nil @items.second.list_position
73
+ assert_equal_ids [1,3,4]
74
+ end
75
+
76
+ def test_simple_remove_from_list_after_destroy
77
+ @items.second.destroy
78
+ assert_equal_ids [1,3,4]
79
+ end
80
+
81
+ def test_simple_remove_before_destroy_does_not_shift_lower_items_twice
82
+ @items.second.remove_from_list
83
+ @items.second.destroy
84
+ assert_equal_ids [1,3,4]
85
+ third_item_position = @items.third.list_position
86
+ fourth_item_position = @items.fourth.list_position
87
+ reload_items(@items.second)
88
+ assert_equal third_item_position - 1, @items.third.list_position
89
+ assert_equal fourth_item_position - 1, @items.fourth.list_position
90
+ end
91
+
92
+ def test_simple_create_after_destroy_doesnt_introduce_gap
93
+ @items.fourth.destroy
94
+ new_item = create(@items.first.respond_to?(:parent_id) ? @items.first.parent_id : nil)
95
+ assert_equal @items.third.list_position + 1, new_item.list_position
96
+ end
97
+
98
+ def test_simple_create_after_remove_doesnt_introduce_gap
99
+ @items.fourth.remove_from_list
100
+ new_item = create(@items.first.respond_to?(:parent_id) ? @items.first.parent_id : nil)
101
+ assert_equal @items.third.list_position + 1, new_item.list_position
102
+ end
103
+
104
+ # Move Tests
105
+ def test_simple_move_down
106
+ @items.second.move_down
107
+ assert_equal_ids [1,3,2,4]
108
+ end
109
+
110
+ def test_simple_move_up
111
+ @items.third.move_up
112
+ assert_equal_ids [1,3,2,4]
113
+ end
114
+
115
+ def test_simple_move_to_bottom
116
+ @items.second.move_to_bottom
117
+ assert_equal_ids [1,3,4,2]
118
+ end
119
+
120
+ def test_simple_move_to_bottom_should_not_introduce_gap
121
+ last_position = @items.fourth.list_position
122
+ @items.second.move_to_bottom
123
+ reload_items
124
+ assert_equal last_position, @items.second.list_position
125
+ end
126
+
127
+ def test_simple_move_to_top
128
+ @items.third.move_to_top
129
+ assert_equal_ids [3,1,2,4]
130
+ end
131
+
132
+ # First? Last? Tests
133
+ def test_simple_first?
134
+ assert @items.first.first?
135
+ end
136
+
137
+ def test_simple_last?
138
+ assert @items.fourth.last?
139
+ end
140
+
141
+ def test_simple_not_first?
142
+ assert !@items.second.first?
143
+ end
144
+
145
+ def test_simple_not_last?
146
+ assert !@items.third.last?
147
+ end
148
+
149
+ def test_simple_deleted_first?
150
+ @items.first.destroy
151
+ assert @items.second.reload.first?
152
+ end
153
+
154
+ def test_simple_deleted_last?
155
+ @items.fourth.destroy
156
+ assert @items.third.reload.last?
157
+ end
158
+
159
+ def test_simple_removed_first?
160
+ @items.first.remove_from_list
161
+ assert @items.second.reload.first?
162
+ end
163
+
164
+ def test_simple_removed_last?
165
+ @items.fourth.remove_from_list
166
+ assert @items.third.reload.last?
167
+ end
168
+
169
+ # Previous Next Tests
170
+ def test_simple_get_next_item
171
+ assert_equal @items.second, @items.first.next_item
172
+ end
173
+
174
+ def test_simple_should_get_previous_item
175
+ assert_equal @items.second, @items.third.previous_item
176
+ end
177
+
178
+ def test_simple_should_not_get_next_item_if_last_item
179
+ assert_nil @items.fourth.next_item
180
+ end
181
+
182
+ def test_simple_should_not_get_previous_item_if_first_item
183
+ assert_nil @items.first.previous_item
184
+ end
185
+ end
@@ -0,0 +1,37 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+ require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
3
+ require 'test_help'
4
+
5
+ require 'simple_tests'
6
+ require 'simple_gapless_tests'
7
+ require 'simple_gap_tests'
8
+ require 'scoped_tests'
9
+ require 'conditional_tests'
10
+
11
+ class ActiveSupport::TestCase
12
+ self.use_transactional_fixtures = true
13
+ self.use_instantiated_fixtures = false
14
+
15
+ # Asserts expected items ids order matches the actual items ids ordered by position
16
+ def assert_equal_ids(expected, *args)
17
+ if args.empty?
18
+ assert_equal expected.map{ |index| @ids[index-1]}, ordered_ids
19
+ elsif !@ids.is_a?(Hash)
20
+ assert_equal expected.map{ |index| @ids[index-1]}, ordered_ids(args.first)
21
+ else
22
+ assert_equal expected.map{ |index| @ids[args.first][index-1]}, ordered_ids(args.first)
23
+ end
24
+ end
25
+
26
+ def reload_items(except=nil)
27
+ @items.each { |item| item.reload unless item == except}
28
+ end
29
+
30
+ def positions(except=nil)
31
+ reload_items(except)
32
+ @items.reject do |item|
33
+ item == except
34
+ end.map(&:list_position)
35
+ end
36
+ end
37
+
@@ -0,0 +1,36 @@
1
+ require 'test_helper'
2
+
3
+ class ConditionalItemTest < ActiveSupport::TestCase
4
+ def setup
5
+ 8.times { |index| (index % 2) > 0 ? ConditionalItem.create(:tag => 'todo') : ConditionalItem.create(:tag => 'bad')}
6
+ @items = ConditionalItem.find(:all, :conditions => "position IS NOT NULL", :order => 'id')
7
+ @ids = @items.map(&:id)
8
+ end
9
+
10
+ include SimpleTests
11
+ include SimpleGaplessTests
12
+ include ConditionalTests
13
+
14
+ protected
15
+ def ordered_ids
16
+ ConditionalItem.find(:all, :order => 'position', :conditions => "position IS NOT NULL").map(&:id)
17
+ end
18
+
19
+ def create(tag, *args)
20
+ ConditionalItem.create(:tag => tag || 'todo')
21
+ end
22
+
23
+ def create_with_conditions_not_met
24
+ create('bad_tag')
25
+ end
26
+
27
+ def fail_conditions(item)
28
+ item.tag = 'bad_tag'
29
+ item.save
30
+ end
31
+
32
+ def pass_conditions(item)
33
+ item.tag = 'todo'
34
+ item.save
35
+ end
36
+ end
@@ -0,0 +1,21 @@
1
+ require 'test_helper'
2
+
3
+ class DifferentPositionColumnItemTest < ActiveSupport::TestCase
4
+ def setup
5
+ 4.times { DifferentPositionColumnItem.create }
6
+ @items = DifferentPositionColumnItem.find(:all, :order => 'id')
7
+ @ids = @items.map(&:id)
8
+ end
9
+
10
+ include SimpleTests
11
+ include SimpleGaplessTests
12
+
13
+ protected
14
+ def ordered_ids
15
+ DifferentPositionColumnItem.find(:all, :order => 'different_position', :conditions => 'different_position IS NOT NULL').map(&:id)
16
+ end
17
+
18
+ def create(*args)
19
+ DifferentPositionColumnItem.create
20
+ end
21
+ end
@@ -0,0 +1,62 @@
1
+ require 'test_helper'
2
+
3
+ class EvalSupportTest < ActiveSupport::TestCase
4
+
5
+ # Hash Tests
6
+ def test_hash_string
7
+ assert_equal "tag == 'todo'", conditions({:tag => 'todo'})
8
+ end
9
+
10
+ def test_hash_number
11
+ assert_equal "parent_id == 17", conditions({:parent_id => 17})
12
+ end
13
+
14
+ def test_hash_true
15
+ assert_equal "published == true", conditions({:published => true})
16
+ end
17
+
18
+ def test_hash_false
19
+ assert_equal "published == false", conditions({:published => false})
20
+ end
21
+
22
+ def test_nil_value
23
+ assert_equal "parent_id == nil", conditions({:parent_id => nil})
24
+ end
25
+
26
+ def test_hash_multiple_conditions
27
+ assert_include ["tag == 'todo'", "&&", "parent_id == 17"], conditions({:tag => 'todo', :parent_id => 17})
28
+ end
29
+
30
+ # Array Tests
31
+ def test_array_equal_string
32
+ assert_equal "tag == 'todo'", conditions(["tag = ?", 'todo'])
33
+ end
34
+
35
+ def test_array_greater_number
36
+ assert_equal "count >= 17", conditions(["count >= ?", 17])
37
+ end
38
+
39
+ def test_array_multiple_conditions_with_and
40
+ assert_include ["tag == 'todo'", "&&", "parent_id >= 17"], conditions(["tag = ? AND parent_id >= ?", 'todo', 17])
41
+ end
42
+
43
+ def test_array_multiple_conditions_with_or
44
+ assert_include ["tag == 'todo'", "||", "parent_id >= 17"], conditions(["tag = ? OR parent_id >= ?", 'todo', 17])
45
+ end
46
+
47
+ # String Tests
48
+ def test_string_multiple_conditions
49
+ assert_include ["tag == 'todo'", "&&", "parent_id >= 17"], conditions("tag = 'todo' AND parent_id >= 17")
50
+ end
51
+
52
+ protected
53
+ def conditions(cond)
54
+ Positionable::EvalSupport.conditions_to_eval(cond)
55
+ end
56
+
57
+ def assert_include(arr, string)
58
+ arr.each do |arr|
59
+ assert_match arr, string
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,71 @@
1
+ require 'test_helper'
2
+
3
+ class HellOnEarthItemTest < ActiveSupport::TestCase
4
+ def setup
5
+ @items = {}
6
+ @ids = {}
7
+ 4.times do
8
+ HellOnEarthItem.create :parent_id => 1, :session_id => 1, :published => true
9
+ end
10
+ 4.times do |index|
11
+ HellOnEarthItem.create :parent_id => 1, :published => false, :tag => index % 2 > 0 ? 'todo' : 'done'
12
+ end
13
+
14
+ @items[:default] = HellOnEarthItem.find(:all, :order => 'id', :conditions => {:parent_id => 1, :session_id => 1})
15
+ @ids[:default] = @items[:default].map(&:id)
16
+
17
+ @items[:client] = HellOnEarthItem.find(:all, :order => 'id', :conditions => {:parent_id => 1, :published => false})
18
+ @ids[:client] = @items[:client].map(&:id)
19
+
20
+ @items[:developer] = HellOnEarthItem.find(:all, :order => 'id', :conditions => {:parent_id => 1, :published => false, :tag => 'todo'})
21
+ @ids[:developer] = @items[:developer].map(&:id)
22
+ end
23
+
24
+ def test_complex_creation
25
+ assert_equal_ids [1,2,3,4], :default
26
+ assert_equal_ids [1,2,3,4], :client
27
+ assert_equal_ids [1,2], :developer
28
+ end
29
+
30
+ def test_complex_conditions
31
+ assert !@items[:default].first.in_list?(:client)
32
+ assert !@items[:default].first.in_list?(:developer)
33
+
34
+ assert !@items[:client].first.in_list?(:default)
35
+
36
+ assert @items[:developer].first.in_list?(:client)
37
+ end
38
+
39
+ def test_complex_removal
40
+ @items[:developer].first.remove_from_list(:client)
41
+ assert @items[:developer].first.in_list?(:client)
42
+ assert @items[:developer].first.in_list?(:developer)
43
+ end
44
+
45
+ def test_complex_conditions_update
46
+ @items[:default].first.published = false; @items[:default].first.save
47
+ assert !@items[:default].first.in_list?(:default)
48
+ assert @items[:default].first.in_list?(:client)
49
+
50
+ @items[:developer].first.tag = 'done'; @items[:developer].first.save
51
+ assert !@items[:developer].first.in_list?(:developer)
52
+ assert @items[:developer].first.in_list?(:client)
53
+ end
54
+
55
+ protected
56
+ def ordered_ids(list_name)
57
+ send "#{list_name}_ordered_ids"
58
+ end
59
+
60
+ def default_ordered_ids
61
+ HellOnEarthItem.find(:all, :order => 'position', :conditions => "position IS NOT NULL AND parent_id = 1 AND session_id = 1 AND published = 't'").map(&:id)
62
+ end
63
+
64
+ def client_ordered_ids
65
+ HellOnEarthItem.find(:all, :order => 'client_position', :conditions => "client_position IS NOT NULL AND parent_id = 1 AND published = 'f'").map(&:id)
66
+ end
67
+
68
+ def developer_ordered_ids
69
+ HellOnEarthItem.find(:all, :order => 'developer_position', :conditions => "developer_position IS NOT NULL AND parent_id = 1 AND published = 'f' AND tag = 'todo'").map(&:id)
70
+ end
71
+ end
@@ -0,0 +1,69 @@
1
+ require 'test_helper'
2
+
3
+ class PositionableHelperTest < ActionView::TestCase
4
+ def protect_against_forgery?
5
+ end
6
+
7
+ def setup
8
+ @host = 'http://test.host'
9
+ @item = MultipleListItem.create
10
+ @controller = TestController.new
11
+ end
12
+
13
+ %w( move_lower move_down move_higher move_up move_to_bottom insert_at_bottom
14
+ move_to_top insert_at_top insert_at remove_from_list).each do |action|
15
+ test "#{action} path and url" do
16
+ path = "/multiple_list_item/#{@item.id}/client/position/#{action}"
17
+ assert_equal path, send("#{action}_path", @item, :client)
18
+ assert_equal "#{@host}#{path}", send("#{action}_url", @item, :client)
19
+ end
20
+ end
21
+
22
+ test "positionable links should have a ul container" do
23
+ html = positionable_links(@item, :client)
24
+ assert_match '<ul class="positionable_links">', html
25
+ end
26
+
27
+ test "positionable links should disable move up and move to top if first?" do
28
+ html = positionable_links(@item, :client)
29
+ assert_match '<li class="positionable_disabled">Move to top', html
30
+ assert_match '<li class="positionable_disabled">Move up', html
31
+ end
32
+
33
+ test "positionable links should disable move down and move to bottom if last?" do
34
+ html = positionable_links(@item, :client)
35
+ assert_match '<li class="positionable_disabled">Move to bottom', html
36
+ assert_match '<li class="positionable_disabled">Move down', html
37
+ end
38
+
39
+ test "positionable links should return links for up and top if not first?" do
40
+ @item = create
41
+ html = positionable_links(@item, :client)
42
+ assert_match /<a href="[^"]*".*Move to top/i, html
43
+ assert_match /<a href="[^"]*".*Move up/i, html
44
+ end
45
+
46
+ test "positionable links should return links for down and bottom if not last?" do
47
+ create
48
+ html = positionable_links(@item, :client)
49
+ assert_match /<a href="[^"]*".*Move to bottom/i, html
50
+ assert_match /<a href="[^"]*".*Move down/i, html
51
+ end
52
+
53
+ test "positionable links should be insert links if resource not in list" do
54
+ @item.remove_from_list(:client)
55
+ html = positionable_links(@item, :client)
56
+ assert_match /Insert at top/i, html
57
+ assert_match /Insert at bottom/i, html
58
+ end
59
+
60
+ test "positionable buttons should have a ul container" do
61
+ html = positionable_buttons(@item, :client)
62
+ assert_match '<ul class="positionable_buttons">', html
63
+ end
64
+
65
+ protected
66
+ def create
67
+ MultipleListItem.create
68
+ end
69
+ end
@@ -0,0 +1,60 @@
1
+ require 'test_helper'
2
+
3
+ class MultipleListItemTest < ActiveSupport::TestCase
4
+ def setup
5
+ 4.times { MultipleListItem.create }
6
+ @items = MultipleListItem.find(:all, :order => 'id')
7
+ @ids = @items.map(&:id)
8
+ end
9
+
10
+ include SimpleTests
11
+ include SimpleGaplessTests
12
+
13
+ def test_multiple_list_insertion
14
+ item = create
15
+ assert item.in_list?(:default)
16
+ assert item.in_list?(:client)
17
+ assert item.in_list?(:developer)
18
+ end
19
+
20
+ def test_multiple_list_removal_should_not_mess_other_lists
21
+ @items.second.remove_from_list(:client)
22
+ assert_equal_ids [1,3,4], :client
23
+ assert_equal_ids [1,2,3,4], :default
24
+ assert_equal_ids [1,2,3,4], :developer
25
+ end
26
+
27
+ def test_multiple_list_destroy_should_update_all_lists
28
+ @items.second.destroy
29
+ assert_equal_ids [1,3,4], :default
30
+ assert_equal_ids [1,3,4], :client
31
+ assert_equal_ids [1,3,4], :developer
32
+ end
33
+
34
+ def test_multiple_list_move
35
+ @items.second.move_down(:client)
36
+ assert_equal_ids [1,2,3,4], :default
37
+ assert_equal_ids [1,3,2,4], :client
38
+ assert_equal_ids [1,2,3,4], :developer
39
+ end
40
+
41
+ def test_multiple_list_insert_at
42
+ @items.second.insert_at(:bottom, :client)
43
+ assert_equal_ids [1,2,3,4], :default
44
+ assert_equal_ids [1,3,4,2], :client
45
+ assert_equal_ids [1,2,3,4], :developer
46
+ end
47
+
48
+ protected
49
+ def ordered_ids(*args)
50
+ position = 'position'
51
+ unless args.empty?
52
+ position = {:default => 'position', :client => 'client_position', :developer => 'developer_position'}[args.first]
53
+ end
54
+ MultipleListItem.find(:all, :order => position, :conditions => "#{position} IS NOT NULL").map(&:id)
55
+ end
56
+
57
+ def create(*args)
58
+ MultipleListItem.create
59
+ end
60
+ end