acts_as_ordered_tree 1.3.1 → 2.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/lib/acts_as_ordered_tree.rb +22 -100
  3. data/lib/acts_as_ordered_tree/adapters.rb +17 -0
  4. data/lib/acts_as_ordered_tree/adapters/abstract.rb +23 -0
  5. data/lib/acts_as_ordered_tree/adapters/postgresql.rb +150 -0
  6. data/lib/acts_as_ordered_tree/adapters/recursive.rb +157 -0
  7. data/lib/acts_as_ordered_tree/compatibility.rb +22 -0
  8. data/lib/acts_as_ordered_tree/compatibility/active_record/association_scope.rb +9 -0
  9. data/lib/acts_as_ordered_tree/compatibility/active_record/default_scoped.rb +19 -0
  10. data/lib/acts_as_ordered_tree/compatibility/active_record/null_relation.rb +71 -0
  11. data/lib/acts_as_ordered_tree/compatibility/features.rb +153 -0
  12. data/lib/acts_as_ordered_tree/deprecate.rb +24 -0
  13. data/lib/acts_as_ordered_tree/hooks.rb +38 -0
  14. data/lib/acts_as_ordered_tree/hooks/update.rb +86 -0
  15. data/lib/acts_as_ordered_tree/instance_methods.rb +92 -453
  16. data/lib/acts_as_ordered_tree/iterators/arranger.rb +35 -0
  17. data/lib/acts_as_ordered_tree/iterators/level_calculator.rb +52 -0
  18. data/lib/acts_as_ordered_tree/iterators/orphans_pruner.rb +58 -0
  19. data/lib/acts_as_ordered_tree/node.rb +78 -0
  20. data/lib/acts_as_ordered_tree/node/attributes.rb +48 -0
  21. data/lib/acts_as_ordered_tree/node/movement.rb +62 -0
  22. data/lib/acts_as_ordered_tree/node/movements.rb +111 -0
  23. data/lib/acts_as_ordered_tree/node/predicates.rb +98 -0
  24. data/lib/acts_as_ordered_tree/node/reloading.rb +49 -0
  25. data/lib/acts_as_ordered_tree/node/siblings.rb +139 -0
  26. data/lib/acts_as_ordered_tree/node/traversals.rb +53 -0
  27. data/lib/acts_as_ordered_tree/persevering_transaction.rb +93 -0
  28. data/lib/acts_as_ordered_tree/position.rb +143 -0
  29. data/lib/acts_as_ordered_tree/relation/arrangeable.rb +33 -0
  30. data/lib/acts_as_ordered_tree/relation/iterable.rb +41 -0
  31. data/lib/acts_as_ordered_tree/relation/preloaded.rb +46 -11
  32. data/lib/acts_as_ordered_tree/transaction/base.rb +57 -0
  33. data/lib/acts_as_ordered_tree/transaction/callbacks.rb +67 -0
  34. data/lib/acts_as_ordered_tree/transaction/create.rb +68 -0
  35. data/lib/acts_as_ordered_tree/transaction/destroy.rb +34 -0
  36. data/lib/acts_as_ordered_tree/transaction/dsl.rb +214 -0
  37. data/lib/acts_as_ordered_tree/transaction/factory.rb +67 -0
  38. data/lib/acts_as_ordered_tree/transaction/move.rb +70 -0
  39. data/lib/acts_as_ordered_tree/transaction/passthrough.rb +12 -0
  40. data/lib/acts_as_ordered_tree/transaction/reorder.rb +42 -0
  41. data/lib/acts_as_ordered_tree/transaction/save.rb +64 -0
  42. data/lib/acts_as_ordered_tree/transaction/update.rb +78 -0
  43. data/lib/acts_as_ordered_tree/tree.rb +148 -0
  44. data/lib/acts_as_ordered_tree/tree/association.rb +20 -0
  45. data/lib/acts_as_ordered_tree/tree/callbacks.rb +57 -0
  46. data/lib/acts_as_ordered_tree/tree/children_association.rb +120 -0
  47. data/lib/acts_as_ordered_tree/tree/columns.rb +102 -0
  48. data/lib/acts_as_ordered_tree/tree/deprecated_columns_accessors.rb +24 -0
  49. data/lib/acts_as_ordered_tree/tree/parent_association.rb +31 -0
  50. data/lib/acts_as_ordered_tree/tree/perseverance.rb +19 -0
  51. data/lib/acts_as_ordered_tree/tree/scopes.rb +56 -0
  52. data/lib/acts_as_ordered_tree/validators.rb +1 -1
  53. data/lib/acts_as_ordered_tree/version.rb +1 -1
  54. data/spec/acts_as_ordered_tree_spec.rb +80 -909
  55. data/spec/adapters/postgresql_spec.rb +14 -0
  56. data/spec/adapters/recursive_spec.rb +12 -0
  57. data/spec/adapters/shared.rb +272 -0
  58. data/spec/callbacks_spec.rb +177 -0
  59. data/spec/counter_cache_spec.rb +31 -0
  60. data/spec/create_spec.rb +110 -0
  61. data/spec/destroy_spec.rb +57 -0
  62. data/spec/inheritance_spec.rb +176 -0
  63. data/spec/move_spec.rb +94 -0
  64. data/spec/node/movements/concurrent_movements_spec.rb +354 -0
  65. data/spec/node/movements/move_higher_spec.rb +46 -0
  66. data/spec/node/movements/move_lower_spec.rb +46 -0
  67. data/spec/node/movements/move_to_child_of_spec.rb +147 -0
  68. data/spec/node/movements/move_to_child_with_index_spec.rb +124 -0
  69. data/spec/node/movements/move_to_child_with_position_spec.rb +85 -0
  70. data/spec/node/movements/move_to_left_of_spec.rb +120 -0
  71. data/spec/node/movements/move_to_right_of_spec.rb +120 -0
  72. data/spec/node/movements/move_to_root_spec.rb +67 -0
  73. data/spec/node/predicates_spec.rb +211 -0
  74. data/spec/node/reloading_spec.rb +42 -0
  75. data/spec/node/siblings_spec.rb +193 -0
  76. data/spec/node/traversals_spec.rb +71 -0
  77. data/spec/persevering_transaction_spec.rb +98 -0
  78. data/spec/relation/arrangeable_spec.rb +88 -0
  79. data/spec/relation/iterable_spec.rb +104 -0
  80. data/spec/relation/preloaded_spec.rb +57 -0
  81. data/spec/reorder_spec.rb +83 -0
  82. data/spec/spec_helper.rb +30 -38
  83. data/spec/support/db/boot.rb +22 -0
  84. data/spec/{db → support/db}/config.travis.yml +2 -0
  85. data/spec/{db → support/db}/config.yml +1 -0
  86. data/spec/{db → support/db}/schema.rb +9 -0
  87. data/spec/support/factories.rb +2 -2
  88. data/spec/support/matchers.rb +67 -58
  89. data/spec/support/models.rb +6 -14
  90. data/spec/support/tree_factory.rb +315 -0
  91. data/spec/tree/children_association_spec.rb +72 -0
  92. data/spec/tree/columns_spec.rb +65 -0
  93. data/spec/tree/scopes_spec.rb +39 -0
  94. metadata +161 -43
  95. data/lib/acts_as_ordered_tree/adapters/postgresql_adapter.rb +0 -104
  96. data/lib/acts_as_ordered_tree/arrangeable.rb +0 -80
  97. data/lib/acts_as_ordered_tree/class_methods.rb +0 -72
  98. data/lib/acts_as_ordered_tree/relation/base.rb +0 -26
  99. data/lib/acts_as_ordered_tree/tenacious_transaction.rb +0 -30
  100. data/spec/concurrency_support_spec.rb +0 -156
@@ -0,0 +1,124 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ActsAsOrderedTree::Node::Movements, '#move_to_child_with_index', :transactional do
6
+ shared_examples '#move_to_child_with_index' do |factory|
7
+ describe "#move_to_child_with_index #{factory}" do
8
+ tree :factory => factory do
9
+ root {
10
+ node_1
11
+ node_2
12
+ node_3 {
13
+ node_4
14
+ }
15
+ }
16
+ end
17
+
18
+ context 'moving node to same parent and same position' do
19
+ before { node_2.move_to_child_with_index(root, 1) }
20
+
21
+ expect_tree_to_match {
22
+ root {
23
+ node_1
24
+ node_2
25
+ node_3 {
26
+ node_4
27
+ }
28
+ }
29
+ }
30
+ end
31
+
32
+ context 'moving node to same parent with another position' do
33
+ before { node_1.move_to_child_with_index(root, 1) }
34
+
35
+ expect_tree_to_match {
36
+ root {
37
+ node_2
38
+ node_1
39
+ node_3 {
40
+ node_4
41
+ }
42
+ }
43
+ }
44
+ end
45
+
46
+ context 'moving node to same parent to lowest position' do
47
+ before { node_1.move_to_child_with_index(root, -1) }
48
+
49
+ expect_tree_to_match {
50
+ root {
51
+ node_2
52
+ node_3 {
53
+ node_4
54
+ }
55
+ node_1
56
+ }
57
+ }
58
+ end
59
+
60
+ context 'moving node to position with negative index' do
61
+ before { node_4.move_to_child_with_index(root, -2) }
62
+
63
+ expect_tree_to_match {
64
+ root {
65
+ node_1
66
+ node_4
67
+ node_2
68
+ node_3
69
+ }
70
+ }
71
+ end
72
+
73
+ context 'moving node to root with index starting from end' do
74
+ before { node_4.move_to_child_with_index(nil, -1) }
75
+
76
+ expect_tree_to_match {
77
+ node_4
78
+ root {
79
+ node_1
80
+ node_2
81
+ node_3
82
+ }
83
+ }
84
+ end
85
+
86
+ context 'moving to node to very position with large negative index' do
87
+ before { node_4.move_to_child_with_index(root, -100) }
88
+
89
+ expect_tree_to_match {
90
+ root {
91
+ node_4
92
+ node_1
93
+ node_2
94
+ node_3
95
+ }
96
+ }
97
+ end
98
+
99
+ context 'moving to node to very large position' do
100
+ before { node_4.move_to_child_with_index(root, 100) }
101
+
102
+ expect_tree_to_match {
103
+ root {
104
+ node_1
105
+ node_2
106
+ node_3
107
+ node_4
108
+ }
109
+ }
110
+ end
111
+
112
+ context 'when attribute, not related to tree, changed' do
113
+ before { @old_name = node_2.name }
114
+ before { node_2.name = 'new name' }
115
+
116
+ it { expect{node_2.move_to_child_with_index(root, 1)}.to change(node_2, :name).to(@old_name) }
117
+ end
118
+ end
119
+ end
120
+
121
+ include_examples '#move_to_child_with_index', :default
122
+ include_examples '#move_to_child_with_index', :default_with_counter_cache
123
+ include_examples '#move_to_child_with_index', :scoped
124
+ end
@@ -0,0 +1,85 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ActsAsOrderedTree::Node::Movements, '#move_to_child_with_position', :transactional do
6
+ shared_examples '#move_to_child_with_position' do |factory|
7
+ describe "#move_to_child_with_position #{factory}" do
8
+ tree :factory => factory do
9
+ root {
10
+ node_1
11
+ node_2
12
+ node_3 {
13
+ node_4
14
+ }
15
+ }
16
+ end
17
+
18
+ context 'moving node to same parent and same position' do
19
+ before { node_2.move_to_child_with_position(root, 2) }
20
+
21
+ expect_tree_to_match {
22
+ root {
23
+ node_1
24
+ node_2
25
+ node_3 {
26
+ node_4
27
+ }
28
+ }
29
+ }
30
+ end
31
+
32
+ context 'moving node to same parent with another position' do
33
+ before { node_1.move_to_child_with_position(root, 2) }
34
+
35
+ expect_tree_to_match {
36
+ root {
37
+ node_2
38
+ node_1
39
+ node_3 {
40
+ node_4
41
+ }
42
+ }
43
+ }
44
+ end
45
+
46
+ context 'moving node to same parent to lowest position' do
47
+ before { node_1.move_to_child_with_position(root, 3) }
48
+
49
+ expect_tree_to_match {
50
+ root {
51
+ node_2
52
+ node_3 {
53
+ node_4
54
+ }
55
+ node_1
56
+ }
57
+ }
58
+ end
59
+
60
+ context 'moving to node to very large position' do
61
+ before { node_4.move_to_child_with_position(root, 100) }
62
+
63
+ expect_tree_to_match {
64
+ root {
65
+ node_1
66
+ node_2
67
+ node_3
68
+ node_4
69
+ }
70
+ }
71
+ end
72
+
73
+ context 'when attribute, not related to tree, changed' do
74
+ before { @old_name = node_2.name }
75
+ before { node_2.name = 'new name' }
76
+
77
+ it { expect{node_2.move_to_child_with_position(root, 2)}.to change(node_2, :name).to(@old_name) }
78
+ end
79
+ end
80
+ end
81
+
82
+ include_examples '#move_to_child_with_position', :default
83
+ include_examples '#move_to_child_with_position', :default_with_counter_cache
84
+ include_examples '#move_to_child_with_position', :scoped
85
+ end
@@ -0,0 +1,120 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ActsAsOrderedTree::Node::Movements, '#move_to_left_of', :transactional do
6
+ shared_examples '#move_to_left_of' do |factory|
7
+ describe "#move_to_left_of #{factory}" do
8
+ tree :factory => factory do
9
+ root {
10
+ node_1
11
+ node_2
12
+ node_3 {
13
+ node_4
14
+ }
15
+ }
16
+ end
17
+
18
+ context 'moving node to next position' do
19
+ before { node_1.move_to_left_of(node_2) }
20
+
21
+ expect_tree_to_match {
22
+ root {
23
+ node_1
24
+ node_2
25
+ node_3 {
26
+ node_4
27
+ }
28
+ }
29
+ }
30
+ end
31
+
32
+ context 'moving node to same parent higher' do
33
+ before { node_3.move_to_left_of(node_1) }
34
+
35
+ expect_tree_to_match {
36
+ root {
37
+ node_3 {
38
+ node_4
39
+ }
40
+ node_1
41
+ node_2
42
+ }
43
+ }
44
+ end
45
+
46
+ context 'moving node to same parent lower' do
47
+ before { node_1.move_to_left_of(node_3) }
48
+
49
+ expect_tree_to_match {
50
+ root {
51
+ node_2
52
+ node_1
53
+ node_3 {
54
+ node_4
55
+ }
56
+ }
57
+ }
58
+ end
59
+
60
+ context 'moving inner node to left of root' do
61
+ before { node_3.move_to_left_of(root) }
62
+
63
+ expect_tree_to_match {
64
+ node_3 {
65
+ node_4
66
+ }
67
+ root {
68
+ node_1
69
+ node_2
70
+ }
71
+ }
72
+ end
73
+
74
+ context 'moving inner node to left of another inner node (shallower)' do
75
+ before { node_4.move_to_left_of(node_1) }
76
+
77
+ expect_tree_to_match {
78
+ root {
79
+ node_4
80
+ node_1
81
+ node_2
82
+ node_3
83
+ }
84
+ }
85
+ end
86
+
87
+ context 'moving inner node to left of another inner node (deeper)' do
88
+ before { node_1.move_to_left_of(node_4) }
89
+
90
+ expect_tree_to_match {
91
+ root {
92
+ node_2
93
+ node_3 {
94
+ node_1
95
+ node_4
96
+ }
97
+ }
98
+ }
99
+ end
100
+
101
+ context 'attempt to perform impossible movement' do
102
+ it { expect{ root.move_to_left_of(node_1) }.not_to change(current_tree, :all) }
103
+ it { expect{ node_3.move_to_left_of(node_4) }.not_to change(current_tree, :all) }
104
+ it { expect{ node_1.move_to_left_of(node_1) }.not_to change(current_tree, :all) }
105
+ it { expect{ node_3.move_to_left_of(node_3) }.not_to change(current_tree, :all) }
106
+ end
107
+
108
+ context 'when attribute, not related to tree, changed' do
109
+ before { @old_name = node_2.name }
110
+ before { node_2.name = 'new name' }
111
+
112
+ it { expect{node_2.move_to_left_of(node_4)}.to change(node_2, :name).to(@old_name) }
113
+ end
114
+ end
115
+ end
116
+
117
+ include_examples '#move_to_left_of', :default
118
+ include_examples '#move_to_left_of', :default_with_counter_cache
119
+ include_examples '#move_to_left_of', :scoped, :scope_type => 's'
120
+ end
@@ -0,0 +1,120 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ActsAsOrderedTree::Node::Movements, '#move_to_right_of', :transactional do
6
+ shared_examples '#move_to_right_of' do |factory|
7
+ describe "#move_to_right_of #{factory}" do
8
+ tree :factory => factory do
9
+ root {
10
+ node_1
11
+ node_2
12
+ node_3 {
13
+ node_4
14
+ }
15
+ }
16
+ end
17
+
18
+ context 'moving node to same parent higher' do
19
+ before { node_3.move_to_right_of(node_1) }
20
+
21
+ expect_tree_to_match {
22
+ root {
23
+ node_1
24
+ node_3 {
25
+ node_4
26
+ }
27
+ node_2
28
+ }
29
+ }
30
+ end
31
+
32
+ context 'moving node to next position' do
33
+ before { node_1.move_to_right_of(node_2) }
34
+
35
+ expect_tree_to_match {
36
+ root {
37
+ node_2
38
+ node_1
39
+ node_3 {
40
+ node_4
41
+ }
42
+ }
43
+ }
44
+ end
45
+
46
+ context 'moving node to same parent lower' do
47
+ before { node_1.move_to_right_of(node_3) }
48
+
49
+ expect_tree_to_match {
50
+ root {
51
+ node_2
52
+ node_3 {
53
+ node_4
54
+ }
55
+ node_1
56
+ }
57
+ }
58
+ end
59
+
60
+ context 'moving inner node to right of root node' do
61
+ before { node_3.move_to_right_of(root) }
62
+
63
+ expect_tree_to_match {
64
+ root {
65
+ node_1
66
+ node_2
67
+ }
68
+ node_3 {
69
+ node_4
70
+ }
71
+ }
72
+ end
73
+
74
+ context 'moving inner node to right of another inner node (shallower)' do
75
+ before { node_4.move_to_right_of(node_1) }
76
+
77
+ expect_tree_to_match {
78
+ root {
79
+ node_1
80
+ node_4
81
+ node_2
82
+ node_3
83
+ }
84
+ }
85
+ end
86
+
87
+ context 'moving inner node to right of another inner node (deeper)' do
88
+ before { node_1.move_to_right_of(node_4) }
89
+
90
+ expect_tree_to_match {
91
+ root {
92
+ node_2
93
+ node_3 {
94
+ node_4
95
+ node_1
96
+ }
97
+ }
98
+ }
99
+ end
100
+
101
+ context 'Attempt to perform impossible movement' do
102
+ it { expect{ root.move_to_right_of(node_1) }.not_to change(current_tree, :all) }
103
+ it { expect{ node_3.move_to_right_of(node_4) }.not_to change(current_tree, :all) }
104
+ it { expect{ node_1.move_to_right_of(node_1) }.not_to change(current_tree, :all) }
105
+ it { expect{ node_3.move_to_right_of(node_3) }.not_to change(current_tree, :all) }
106
+ end
107
+
108
+ context 'when attribute, not related to tree changed' do
109
+ before { @old_name = node_2.name }
110
+ before { node_2.name = 'new name' }
111
+
112
+ it { expect{node_2.move_to_right_of(node_4)}.to change(node_2, :name).to(@old_name) }
113
+ end
114
+ end
115
+ end
116
+
117
+ include_examples '#move_to_right_of', :default
118
+ include_examples '#move_to_right_of', :default_with_counter_cache
119
+ include_examples '#move_to_right_of', :scoped, :scope_type => 's'
120
+ end