You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

acts_as_tree_test.rb 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. # frozen_string_literal: true
  2. require 'test/unit'
  3. require 'rubygems'
  4. require 'active_record'
  5. $:.unshift File.dirname(__FILE__) + '/../lib'
  6. require File.dirname(__FILE__) + '/../init'
  7. class Test::Unit::TestCase
  8. def assert_queries(num = 1)
  9. $query_count = 0
  10. yield
  11. ensure
  12. assert_equal num, $query_count, "#{$query_count} instead of #{num} queries were executed."
  13. end
  14. def assert_no_queries(&block)
  15. assert_queries(0, &block)
  16. end
  17. end
  18. ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:")
  19. # AR keeps printing annoying schema statements
  20. $stdout = StringIO.new
  21. def setup_db
  22. ActiveRecord::Base.logger
  23. ActiveRecord::Schema.define(:version => 1) do
  24. create_table :mixins do |t|
  25. t.column :type, :string
  26. t.column :parent_id, :integer
  27. end
  28. end
  29. end
  30. def teardown_db
  31. ActiveRecord::Base.connection.tables.each do |table|
  32. ActiveRecord::Base.connection.drop_table(table)
  33. end
  34. end
  35. class Mixin < ApplicationRecord
  36. end
  37. class TreeMixin < Mixin
  38. acts_as_tree :foreign_key => "parent_id", :order => "id"
  39. end
  40. class TreeMixinWithoutOrder < Mixin
  41. acts_as_tree :foreign_key => "parent_id"
  42. end
  43. class RecursivelyCascadedTreeMixin < Mixin
  44. acts_as_tree :foreign_key => "parent_id"
  45. has_one :first_child, :class_name => 'RecursivelyCascadedTreeMixin', :foreign_key => :parent_id
  46. end
  47. class TreeTest < Test::Unit::TestCase
  48. def setup
  49. setup_db
  50. @root1 = TreeMixin.create!
  51. @root_child1 = TreeMixin.create! :parent_id => @root1.id
  52. @child1_child = TreeMixin.create! :parent_id => @root_child1.id
  53. @root_child2 = TreeMixin.create! :parent_id => @root1.id
  54. @root2 = TreeMixin.create!
  55. @root3 = TreeMixin.create!
  56. end
  57. def teardown
  58. teardown_db
  59. end
  60. def test_children
  61. assert_equal @root1.children, [@root_child1, @root_child2]
  62. assert_equal @root_child1.children, [@child1_child]
  63. assert_equal @child1_child.children, []
  64. assert_equal @root_child2.children, []
  65. end
  66. def test_parent
  67. assert_equal @root_child1.parent, @root1
  68. assert_equal @root_child1.parent, @root_child2.parent
  69. assert_nil @root1.parent
  70. end
  71. def test_delete
  72. assert_equal 6, TreeMixin.count
  73. @root1.destroy
  74. assert_equal 2, TreeMixin.count
  75. @root2.destroy
  76. @root3.destroy
  77. assert_equal 0, TreeMixin.count
  78. end
  79. def test_insert
  80. @extra = @root1.children.create
  81. assert @extra
  82. assert_equal @extra.parent, @root1
  83. assert_equal 3, @root1.children.size
  84. assert @root1.children.include?(@extra)
  85. assert @root1.children.include?(@root_child1)
  86. assert @root1.children.include?(@root_child2)
  87. end
  88. def test_ancestors
  89. assert_equal [], @root1.ancestors
  90. assert_equal [@root1], @root_child1.ancestors
  91. assert_equal [@root_child1, @root1], @child1_child.ancestors
  92. assert_equal [@root1], @root_child2.ancestors
  93. assert_equal [], @root2.ancestors
  94. assert_equal [], @root3.ancestors
  95. end
  96. def test_root
  97. assert_equal @root1, TreeMixin.root
  98. assert_equal @root1, @root1.root
  99. assert_equal @root1, @root_child1.root
  100. assert_equal @root1, @child1_child.root
  101. assert_equal @root1, @root_child2.root
  102. assert_equal @root2, @root2.root
  103. assert_equal @root3, @root3.root
  104. end
  105. def test_roots
  106. assert_equal [@root1, @root2, @root3], TreeMixin.roots
  107. end
  108. def test_siblings
  109. assert_equal [@root2, @root3], @root1.siblings
  110. assert_equal [@root_child2], @root_child1.siblings
  111. assert_equal [], @child1_child.siblings
  112. assert_equal [@root_child1], @root_child2.siblings
  113. assert_equal [@root1, @root3], @root2.siblings
  114. assert_equal [@root1, @root2], @root3.siblings
  115. end
  116. def test_self_and_siblings
  117. assert_equal [@root1, @root2, @root3], @root1.self_and_siblings
  118. assert_equal [@root_child1, @root_child2], @root_child1.self_and_siblings
  119. assert_equal [@child1_child], @child1_child.self_and_siblings
  120. assert_equal [@root_child1, @root_child2], @root_child2.self_and_siblings
  121. assert_equal [@root1, @root2, @root3], @root2.self_and_siblings
  122. assert_equal [@root1, @root2, @root3], @root3.self_and_siblings
  123. end
  124. end
  125. class TreeTestWithEagerLoading < Test::Unit::TestCase
  126. def setup
  127. teardown_db
  128. setup_db
  129. @root1 = TreeMixin.create!
  130. @root_child1 = TreeMixin.create! :parent_id => @root1.id
  131. @child1_child = TreeMixin.create! :parent_id => @root_child1.id
  132. @root_child2 = TreeMixin.create! :parent_id => @root1.id
  133. @root2 = TreeMixin.create!
  134. @root3 = TreeMixin.create!
  135. @rc1 = RecursivelyCascadedTreeMixin.create!
  136. @rc2 = RecursivelyCascadedTreeMixin.create! :parent_id => @rc1.id
  137. @rc3 = RecursivelyCascadedTreeMixin.create! :parent_id => @rc2.id
  138. @rc4 = RecursivelyCascadedTreeMixin.create! :parent_id => @rc3.id
  139. end
  140. def teardown
  141. teardown_db
  142. end
  143. def test_eager_association_loading
  144. roots = TreeMixin.find(:all, :include => :children, :conditions => "mixins.parent_id IS NULL", :order => "mixins.id")
  145. assert_equal [@root1, @root2, @root3], roots
  146. assert_no_queries do
  147. assert_equal 2, roots[0].children.size
  148. assert_equal 0, roots[1].children.size
  149. assert_equal 0, roots[2].children.size
  150. end
  151. end
  152. def test_eager_association_loading_with_recursive_cascading_three_levels_has_many
  153. root_node = RecursivelyCascadedTreeMixin.find(:first, :include => { :children => { :children => :children } }, :order => 'mixins.id')
  154. assert_equal @rc4, assert_no_queries { root_node.children.first.children.first.children.first }
  155. end
  156. def test_eager_association_loading_with_recursive_cascading_three_levels_has_one
  157. root_node = RecursivelyCascadedTreeMixin.find(:first, :include => { :first_child => { :first_child => :first_child } }, :order => 'mixins.id')
  158. assert_equal @rc4, assert_no_queries { root_node.first_child.first_child.first_child }
  159. end
  160. def test_eager_association_loading_with_recursive_cascading_three_levels_belongs_to
  161. leaf_node = RecursivelyCascadedTreeMixin.find(:first, :include => { :parent => { :parent => :parent } }, :order => 'mixins.id DESC')
  162. assert_equal @rc1, assert_no_queries { leaf_node.parent.parent.parent }
  163. end
  164. end
  165. class TreeTestWithoutOrder < Test::Unit::TestCase
  166. def setup
  167. setup_db
  168. @root1 = TreeMixinWithoutOrder.create!
  169. @root2 = TreeMixinWithoutOrder.create!
  170. end
  171. def teardown
  172. teardown_db
  173. end
  174. def test_root
  175. assert [@root1, @root2].include?(TreeMixinWithoutOrder.root)
  176. end
  177. def test_roots
  178. assert_equal [], [@root1, @root2] - TreeMixinWithoutOrder.roots
  179. end
  180. end