diff --git a/README.rdoc b/README.rdoc index 091f24da..8f774f2a 100644 --- a/README.rdoc +++ b/README.rdoc @@ -1,6 +1,6 @@ = Ancestry -Ancestry is a gem/plugin that allows the records of a Ruby on Rails ActiveRecord model to be organised as a tree structure (or hierarchy). It uses a single, intuitively formatted database column, using a variation on the materialised path pattern. It exposes all the standard tree structure relations (ancestors, parent, root, children, siblings, descendants) and all of them can be fetched in a single sql query. Additional features are STI support, named_scopes, depth caching, depth constraints, easy migration from older plugins/gems, integrity checking, integrity restoration, arrangement of (sub)tree into hashes and different strategies for dealing with orphaned records. +Ancestry is a gem/plugin that allows the records of a Ruby on Rails ActiveRecord model to be organised as a tree structure (or hierarchy). It uses a single, intuitively formatted database column, using a variation on the materialised path pattern. It exposes all the standard tree structure relations (ancestors, parent, root, children, siblings, descendants) and all of them can be fetched in a single sql query. Additional features are STI support, scopes, depth caching, depth constraints, easy migration from older plugins/gems, integrity checking, integrity restoration, arrangement of (sub)tree into hashes and different strategies for dealing with orphaned records. = Installation diff --git a/ancestry.gemspec b/ancestry.gemspec index 85898f55..99963658 100644 --- a/ancestry.gemspec +++ b/ancestry.gemspec @@ -5,14 +5,25 @@ Gem::Specification.new do |s| s.description = 'Organise ActiveRecord model into a tree structure' s.summary = 'Ancestry allows the records of a ActiveRecord model to be organised in a tree structure, using a single, intuitively formatted database column. It exposes all the standard tree structure relations (ancestors, parent, root, children, siblings, descendants) and all of them can be fetched in a single sql query. Additional features are named_scopes, integrity checking, integrity restoration, arrangement of (sub)tree into hashes and different strategies for dealing with orphaned records.' - s.version = '1.2.0' + s.version = '1.3.0' s.date = '2010-01-27' s.author = 'Stefan Kroes' s.email = 's.a.kroes@gmail.com' s.homepage = 'http://github.com/stefankroes/ancestry' - s.files = FileList['ancestry.gemspec', '*.rb', 'lib/**/*.rb', 'test/*', 'Rakefile', 'MIT-LICENSE', 'README.rdoc'] + s.files = FileList[ + 'ancestry.gemspec', + 'init.rb', + 'install.rb', + 'lib/ancestry.rb', + 'lib/ancestry/has_ancestry.rb', + 'lib/ancestry/exceptions.rb', + 'lib/ancestry/class_methods.rb', + 'lib/ancestry/instance_methods.rb', + 'MIT-LICENSE', + 'README.rdoc' + ] s.add_dependency 'activerecord', '>= 2.1.0' end \ No newline at end of file diff --git a/install.rb b/install.rb index 08982d95..71e5b60e 100644 --- a/install.rb +++ b/install.rb @@ -1,2 +1 @@ -# Install hook code here puts "Thank you for installing Ancestry. You can visit http://github.com/stefankroes/ancestry to read the documentation." diff --git a/lib/ancestry/class_methods.rb b/lib/ancestry/class_methods.rb index dd099c6c..27a947bb 100644 --- a/lib/ancestry/class_methods.rb +++ b/lib/ancestry/class_methods.rb @@ -53,7 +53,7 @@ def check_ancestry_integrity! # For each node ... self.base_class.all.each do |node| # ... check validity of ancestry column - if !node.valid? and node.errors.invalid?(node.class.ancestry_column) + if !node.valid? and node.errors[node.class.ancestry_column].blank? raise Ancestry::AncestryIntegrityException.new("Invalid format for ancestry column of node #{node.id}: #{node.read_attribute node.ancestry_column}.") end # ... check that all ancestors exist @@ -78,7 +78,7 @@ def restore_ancestry_integrity! # For each node ... self.base_class.all.each do |node| # ... set its ancestry to nil if invalid - if node.errors.invalid? node.class.ancestry_column + if node.errors[node.class.ancestry_column].blank? node.without_ancestry_callbacks do node.update_attributes :ancestry => nil end diff --git a/lib/ancestry/has_ancestry.rb b/lib/ancestry/has_ancestry.rb index 76dab59c..c3a76e77 100644 --- a/lib/ancestry/has_ancestry.rb +++ b/lib/ancestry/has_ancestry.rb @@ -36,15 +36,19 @@ def has_ancestry options = {} # Validate that the ancestor ids don't include own id validate :ancestry_exclude_self + # Workaround to support Rails 2 + scope_method = if ActiveRecord::VERSION::MAJOR < 3 then :named_scope else :scope end + + # Named scopes - named_scope :roots, :conditions => {ancestry_column => nil} - named_scope :ancestors_of, lambda { |object| {:conditions => to_node(object).ancestor_conditions} } - named_scope :children_of, lambda { |object| {:conditions => to_node(object).child_conditions} } - named_scope :descendants_of, lambda { |object| {:conditions => to_node(object).descendant_conditions} } - named_scope :subtree_of, lambda { |object| {:conditions => to_node(object).subtree_conditions} } - named_scope :siblings_of, lambda { |object| {:conditions => to_node(object).sibling_conditions} } - named_scope :ordered_by_ancestry, :order => "(case when #{ancestry_column} is null then 0 else 1 end), #{ancestry_column}" - named_scope :ordered_by_ancestry_and, lambda { |order| {:order => "(case when #{ancestry_column} is null then 0 else 1 end), #{ancestry_column}, #{order}"} } + send scope_method, :roots, :conditions => {ancestry_column => nil} + send scope_method, :ancestors_of, lambda { |object| {:conditions => to_node(object).ancestor_conditions} } + send scope_method, :children_of, lambda { |object| {:conditions => to_node(object).child_conditions} } + send scope_method, :descendants_of, lambda { |object| {:conditions => to_node(object).descendant_conditions} } + send scope_method, :subtree_of, lambda { |object| {:conditions => to_node(object).subtree_conditions} } + send scope_method, :siblings_of, lambda { |object| {:conditions => to_node(object).sibling_conditions} } + send scope_method, :ordered_by_ancestry, :order => "(case when #{ancestry_column} is null then 0 else 1 end), #{ancestry_column}" + send scope_method, :ordered_by_ancestry_and, lambda { |order| {:order => "(case when #{ancestry_column} is null then 0 else 1 end), #{ancestry_column}, #{order}"} } # Update descendants with new ancestry before save before_save :update_descendants_with_new_ancestry @@ -67,7 +71,7 @@ def has_ancestry options = {} # Create named scopes for depth {:before_depth => '<', :to_depth => '<=', :at_depth => '=', :from_depth => '>=', :after_depth => '>'}.each do |scope_name, operator| - named_scope scope_name, lambda { |depth| + send scope_method, scope_name, lambda { |depth| raise Ancestry::AncestryException.new("Named scope '#{scope_name}' is only available when depth caching is enabled.") unless options[:cache_depth] {:conditions => ["#{depth_cache_column} #{operator} ?", depth]} } diff --git a/lib/ancestry/instance_methods.rb b/lib/ancestry/instance_methods.rb index f680424d..76f5d5b7 100644 --- a/lib/ancestry/instance_methods.rb +++ b/lib/ancestry/instance_methods.rb @@ -1,8 +1,8 @@ module Ancestry - module InstanceMethods + module InstanceMethods # Validate that the ancestors don't include itself def ancestry_exclude_self - errors.add_to_base "#{self.class.name.humanize} cannot be a descendant of itself." if ancestor_ids.include? self.id + add_error_to_base "#{self.class.name.humanize} cannot be a descendant of itself." if ancestor_ids.include? self.id end # Update descendants with new ancestry @@ -205,5 +205,16 @@ def without_ancestry_callbacks def ancestry_callbacks_disabled? !!@disable_ancestry_callbacks end + + private + + # Workaround to support Rails 2 + def add_error_to_base error + if ActiveRecord::VERSION::MAJOR < 3 + errors.add_to_base error + else + errors[:base] << error + end + end end end \ No newline at end of file diff --git a/test/database.yml b/test/database.yml index 66bcae9c..c4edec0b 100644 --- a/test/database.yml +++ b/test/database.yml @@ -1,17 +1,17 @@ sqlite: adapter: sqlite - database: vendor/plugins/ancestry/test/ancestry_plugin.sqlite.db + database: ":memory:" sqlite3: adapter: sqlite3 - database: vendor/plugins/ancestry/test/ancestry_plugin.sqlite3.db + database: ":memory:" postgresql: adapter: postgresql - database: ancestry_development + database: ancestry_test username: ancestry password: ancestry mysql: adapter: mysql host: localhost - username: ancestry_plugin_test - password: ancestry_plugin_test - database: ancestry_plugin_test \ No newline at end of file + database: ancestry_test + username: ancestry + password: ancestry diff --git a/test/has_ancestry_test.rb b/test/has_ancestry_test.rb index c8f66fe4..80a9169a 100644 --- a/test/has_ancestry_test.rb +++ b/test/has_ancestry_test.rb @@ -1,84 +1,118 @@ -require File.dirname(__FILE__) + '/test_helper.rb' - -# Setup the required models for all test cases - -class TestNode < ActiveRecord::Base - has_ancestry :cache_depth => true, :depth_cache_column => :depth_cache -end - -class AlternativeTestNode < ActiveRecord::Base - has_ancestry :ancestry_column => :alternative_ancestry, :orphan_strategy => :rootify -end - -class ActsAsTreeTestNode < ActiveRecord::Base - acts_as_tree -end - -class ParentIdTestNode < ActiveRecord::Base -end - -class TestNodeSub1 < TestNode -end - -class TestNodeSub2 < TestNode -end - -class ActsAsTreeTest < ActiveSupport::TestCase - load_schema +require 'rubygems' +Gem.activate 'activerecord', ENV['ar'] || '3.0.0' +require 'active_record' +require 'active_support/test_case' +require 'test/unit' +require 'ancestry' + +class AncestryTestDatabase + def self.setup + ActiveRecord::Base.logger + ActiveRecord::Base.establish_connection YAML.load(File.open(File.join(File.dirname(__FILE__), 'database.yml')).read)[ENV['db'] || 'sqlite3'] + end - def setup_test_nodes model, level, quantity - model.delete_all - create_test_nodes model, nil, level, quantity + def self.with_model options = {} + depth = options.delete(:depth) || 0 + width = options.delete(:width) || 0 + extra_columns = options.delete(:extra_columns) + + ActiveRecord::Base.connection.create_table 'test_nodes' do |table| + table.string options[:ancestry_column] || :ancestry + table.integer options[:depth_cache_column] || :ancestry_depth if options[:cache_depth] + extra_columns.each do |name, type| + table.send type, name + end unless extra_columns.nil? + end + + begin + model = Class.new(ActiveRecord::Base) + (class << model; self; end).send :define_method, :model_name do; Struct.new(:human, :underscore).new 'TestNode', 'test_node'; end + const_set 'TestNode', model + + model.send :set_table_name, 'test_nodes' + model.has_ancestry options unless options.delete(:skip_ancestry) + + if depth > 0 + yield model, create_test_nodes(model, depth, width) + else + yield model + end + ensure + ActiveRecord::Base.connection.drop_table 'test_nodes' + remove_const "TestNode" + end end - - def create_test_nodes model, parent, level, quantity - unless level == 0 - (1..quantity).map do |i| + + def self.create_test_nodes model, depth, width, parent = nil + unless depth == 0 + Array.new width do node = model.create!(:parent => parent) - [node, create_test_nodes(model, node, level - 1, quantity)] + [node, create_test_nodes(model, depth - 1, width, node)] end else; []; end end +end +AncestryTestDatabase.setup + +puts "\nRunning Ancestry test suite:" +puts " Ruby: #{RUBY_VERSION}" +#puts " ActiveRecord: #{ActiveRecord::VERSION::STRING}" +puts " Database: #{ActiveRecord::Base.connection.adapter_name}\n\n" + +class HasAncestryTreeTest < ActiveSupport::TestCase def test_default_ancestry_column - assert_equal :ancestry, TestNode.ancestry_column + AncestryTestDatabase.with_model do |model| + assert_equal :ancestry, model.ancestry_column + end end def test_non_default_ancestry_column - assert_equal :alternative_ancestry, AlternativeTestNode.ancestry_column + AncestryTestDatabase.with_model :ancestry_column => :alternative_ancestry do |model| + assert_equal :alternative_ancestry, model.ancestry_column + end end def test_setting_ancestry_column - TestNode.ancestry_column = :ancestors - assert_equal :ancestors, TestNode.ancestry_column - TestNode.ancestry_column = :ancestry - assert_equal :ancestry, TestNode.ancestry_column + AncestryTestDatabase.with_model do |model| + model.ancestry_column = :ancestors + assert_equal :ancestors, model.ancestry_column + model.ancestry_column = :ancestry + assert_equal :ancestry, model.ancestry_column + end end def test_default_orphan_strategy - assert_equal :destroy, TestNode.orphan_strategy + AncestryTestDatabase.with_model do |model| + assert_equal :destroy, model.orphan_strategy + end end def test_non_default_orphan_strategy - assert_equal :rootify, AlternativeTestNode.orphan_strategy + AncestryTestDatabase.with_model :orphan_strategy => :rootify do |model| + assert_equal :rootify, model.orphan_strategy + end end def test_setting_orphan_strategy - TestNode.orphan_strategy = :rootify - assert_equal :rootify, TestNode.orphan_strategy - TestNode.orphan_strategy = :destroy - assert_equal :destroy, TestNode.orphan_strategy + AncestryTestDatabase.with_model do |model| + model.orphan_strategy = :rootify + assert_equal :rootify, model.orphan_strategy + model.orphan_strategy = :destroy + assert_equal :destroy, model.orphan_strategy + end end - + def test_setting_invalid_orphan_strategy - assert_raise Ancestry::AncestryException do - TestNode.orphan_strategy = :non_existent_orphan_strategy + AncestryTestDatabase.with_model do |model| + assert_raise Ancestry::AncestryException do + model.orphan_strategy = :non_existent_orphan_strategy + end end end - + def test_setup_test_nodes - [TestNode, AlternativeTestNode, ActsAsTreeTestNode].each do |model| - roots = setup_test_nodes model, 3, 3 + AncestryTestDatabase.with_model :depth => 3, :width => 3 do |model, roots| assert_equal Array, roots.class assert_equal 3, roots.length roots.each do |node, children| @@ -98,341 +132,384 @@ def test_setup_test_nodes end end end - + def test_tree_navigation - roots = setup_test_nodes TestNode, 3, 3 - roots.each do |lvl0_node, lvl0_children| - # Ancestors assertions - assert_equal [], lvl0_node.ancestor_ids - assert_equal [], lvl0_node.ancestors - assert_equal [lvl0_node.id], lvl0_node.path_ids - assert_equal [lvl0_node], lvl0_node.path - assert_equal 0, lvl0_node.depth - # Parent assertions - assert_equal nil, lvl0_node.parent_id - assert_equal nil, lvl0_node.parent - # Root assertions - assert_equal lvl0_node.id, lvl0_node.root_id - assert_equal lvl0_node, lvl0_node.root - assert lvl0_node.is_root? - # Children assertions - assert_equal lvl0_children.map(&:first).map(&:id), lvl0_node.child_ids - assert_equal lvl0_children.map(&:first), lvl0_node.children - assert lvl0_node.has_children? - assert !lvl0_node.is_childless? - # Siblings assertions - assert_equal roots.map(&:first).map(&:id), lvl0_node.sibling_ids - assert_equal roots.map(&:first), lvl0_node.siblings - assert lvl0_node.has_siblings? - assert !lvl0_node.is_only_child? - # Descendants assertions - descendants = TestNode.all.find_all do |node| - node.ancestor_ids.include? lvl0_node.id - end - assert_equal descendants.map(&:id), lvl0_node.descendant_ids - assert_equal descendants, lvl0_node.descendants - assert_equal [lvl0_node] + descendants, lvl0_node.subtree - - lvl0_children.each do |lvl1_node, lvl1_children| + AncestryTestDatabase.with_model :depth => 3, :width => 3 do |model, roots| + roots.each do |lvl0_node, lvl0_children| # Ancestors assertions - assert_equal [lvl0_node.id], lvl1_node.ancestor_ids - assert_equal [lvl0_node], lvl1_node.ancestors - assert_equal [lvl0_node.id, lvl1_node.id], lvl1_node.path_ids - assert_equal [lvl0_node, lvl1_node], lvl1_node.path - assert_equal 1, lvl1_node.depth + assert_equal [], lvl0_node.ancestor_ids + assert_equal [], lvl0_node.ancestors + assert_equal [lvl0_node.id], lvl0_node.path_ids + assert_equal [lvl0_node], lvl0_node.path + assert_equal 0, lvl0_node.depth # Parent assertions - assert_equal lvl0_node.id, lvl1_node.parent_id - assert_equal lvl0_node, lvl1_node.parent + assert_equal nil, lvl0_node.parent_id + assert_equal nil, lvl0_node.parent # Root assertions - assert_equal lvl0_node.id, lvl1_node.root_id - assert_equal lvl0_node, lvl1_node.root - assert !lvl1_node.is_root? + assert_equal lvl0_node.id, lvl0_node.root_id + assert_equal lvl0_node, lvl0_node.root + assert lvl0_node.is_root? # Children assertions - assert_equal lvl1_children.map(&:first).map(&:id), lvl1_node.child_ids - assert_equal lvl1_children.map(&:first), lvl1_node.children - assert lvl1_node.has_children? - assert !lvl1_node.is_childless? + assert_equal lvl0_children.map(&:first).map(&:id), lvl0_node.child_ids + assert_equal lvl0_children.map(&:first), lvl0_node.children + assert lvl0_node.has_children? + assert !lvl0_node.is_childless? # Siblings assertions - assert_equal lvl0_children.map(&:first).map(&:id), lvl1_node.sibling_ids - assert_equal lvl0_children.map(&:first), lvl1_node.siblings - assert lvl1_node.has_siblings? - assert !lvl1_node.is_only_child? + assert_equal roots.map(&:first).map(&:id), lvl0_node.sibling_ids + assert_equal roots.map(&:first), lvl0_node.siblings + assert lvl0_node.has_siblings? + assert !lvl0_node.is_only_child? # Descendants assertions - descendants = TestNode.all.find_all do |node| - node.ancestor_ids.include? lvl1_node.id + descendants = model.all.find_all do |node| + node.ancestor_ids.include? lvl0_node.id end - assert_equal descendants.map(&:id), lvl1_node.descendant_ids - assert_equal descendants, lvl1_node.descendants - assert_equal [lvl1_node] + descendants, lvl1_node.subtree - - lvl1_children.each do |lvl2_node, lvl2_children| + assert_equal descendants.map(&:id), lvl0_node.descendant_ids + assert_equal descendants, lvl0_node.descendants + assert_equal [lvl0_node] + descendants, lvl0_node.subtree + + lvl0_children.each do |lvl1_node, lvl1_children| # Ancestors assertions - assert_equal [lvl0_node.id, lvl1_node.id], lvl2_node.ancestor_ids - assert_equal [lvl0_node, lvl1_node], lvl2_node.ancestors - assert_equal [lvl0_node.id, lvl1_node.id, lvl2_node.id], lvl2_node.path_ids - assert_equal [lvl0_node, lvl1_node, lvl2_node], lvl2_node.path - assert_equal 2, lvl2_node.depth + assert_equal [lvl0_node.id], lvl1_node.ancestor_ids + assert_equal [lvl0_node], lvl1_node.ancestors + assert_equal [lvl0_node.id, lvl1_node.id], lvl1_node.path_ids + assert_equal [lvl0_node, lvl1_node], lvl1_node.path + assert_equal 1, lvl1_node.depth # Parent assertions - assert_equal lvl1_node.id, lvl2_node.parent_id - assert_equal lvl1_node, lvl2_node.parent + assert_equal lvl0_node.id, lvl1_node.parent_id + assert_equal lvl0_node, lvl1_node.parent # Root assertions - assert_equal lvl0_node.id, lvl2_node.root_id - assert_equal lvl0_node, lvl2_node.root - assert !lvl2_node.is_root? + assert_equal lvl0_node.id, lvl1_node.root_id + assert_equal lvl0_node, lvl1_node.root + assert !lvl1_node.is_root? # Children assertions - assert_equal [], lvl2_node.child_ids - assert_equal [], lvl2_node.children - assert !lvl2_node.has_children? - assert lvl2_node.is_childless? + assert_equal lvl1_children.map(&:first).map(&:id), lvl1_node.child_ids + assert_equal lvl1_children.map(&:first), lvl1_node.children + assert lvl1_node.has_children? + assert !lvl1_node.is_childless? # Siblings assertions - assert_equal lvl1_children.map(&:first).map(&:id), lvl2_node.sibling_ids - assert_equal lvl1_children.map(&:first), lvl2_node.siblings - assert lvl2_node.has_siblings? - assert !lvl2_node.is_only_child? + assert_equal lvl0_children.map(&:first).map(&:id), lvl1_node.sibling_ids + assert_equal lvl0_children.map(&:first), lvl1_node.siblings + assert lvl1_node.has_siblings? + assert !lvl1_node.is_only_child? # Descendants assertions - descendants = TestNode.all.find_all do |node| - node.ancestor_ids.include? lvl2_node.id + descendants = model.all.find_all do |node| + node.ancestor_ids.include? lvl1_node.id + end + assert_equal descendants.map(&:id), lvl1_node.descendant_ids + assert_equal descendants, lvl1_node.descendants + assert_equal [lvl1_node] + descendants, lvl1_node.subtree + + lvl1_children.each do |lvl2_node, lvl2_children| + # Ancestors assertions + assert_equal [lvl0_node.id, lvl1_node.id], lvl2_node.ancestor_ids + assert_equal [lvl0_node, lvl1_node], lvl2_node.ancestors + assert_equal [lvl0_node.id, lvl1_node.id, lvl2_node.id], lvl2_node.path_ids + assert_equal [lvl0_node, lvl1_node, lvl2_node], lvl2_node.path + assert_equal 2, lvl2_node.depth + # Parent assertions + assert_equal lvl1_node.id, lvl2_node.parent_id + assert_equal lvl1_node, lvl2_node.parent + # Root assertions + assert_equal lvl0_node.id, lvl2_node.root_id + assert_equal lvl0_node, lvl2_node.root + assert !lvl2_node.is_root? + # Children assertions + assert_equal [], lvl2_node.child_ids + assert_equal [], lvl2_node.children + assert !lvl2_node.has_children? + assert lvl2_node.is_childless? + # Siblings assertions + assert_equal lvl1_children.map(&:first).map(&:id), lvl2_node.sibling_ids + assert_equal lvl1_children.map(&:first), lvl2_node.siblings + assert lvl2_node.has_siblings? + assert !lvl2_node.is_only_child? + # Descendants assertions + descendants = model.all.find_all do |node| + node.ancestor_ids.include? lvl2_node.id + end + assert_equal descendants.map(&:id), lvl2_node.descendant_ids + assert_equal descendants, lvl2_node.descendants + assert_equal [lvl2_node] + descendants, lvl2_node.subtree end - assert_equal descendants.map(&:id), lvl2_node.descendant_ids - assert_equal descendants, lvl2_node.descendants - assert_equal [lvl2_node] + descendants, lvl2_node.subtree end end end end - - def test_named_scopes - roots = setup_test_nodes TestNode, 3, 3 - # Roots assertion - assert_equal roots.map(&:first), TestNode.roots.all + def test_scopes + AncestryTestDatabase.with_model :depth => 3, :width => 3 do |model, roots| + # Roots assertion + assert_equal roots.map(&:first), model.roots.all - TestNode.all.each do |test_node| - # Assertions for ancestors_of named scope - assert_equal test_node.ancestors, TestNode.ancestors_of(test_node) - assert_equal test_node.ancestors, TestNode.ancestors_of(test_node.id) - # Assertions for children_of named scope - assert_equal test_node.children, TestNode.children_of(test_node) - assert_equal test_node.children, TestNode.children_of(test_node.id) - # Assertions for descendants_of named scope - assert_equal test_node.descendants, TestNode.descendants_of(test_node) - assert_equal test_node.descendants, TestNode.descendants_of(test_node.id) - # Assertions for subtree_of named scope - assert_equal test_node.subtree, TestNode.subtree_of(test_node) - assert_equal test_node.subtree, TestNode.subtree_of(test_node.id) - # Assertions for siblings_of named scope - assert_equal test_node.siblings, TestNode.siblings_of(test_node) - assert_equal test_node.siblings, TestNode.siblings_of(test_node.id) + model.all.each do |test_node| + # Assertions for ancestors_of named scope + assert_equal test_node.ancestors.all, model.ancestors_of(test_node).all + assert_equal test_node.ancestors.all, model.ancestors_of(test_node.id).all + # Assertions for children_of named scope + assert_equal test_node.children.all, model.children_of(test_node).all + assert_equal test_node.children.all, model.children_of(test_node.id).all + # Assertions for descendants_of named scope + assert_equal test_node.descendants.all, model.descendants_of(test_node).all + assert_equal test_node.descendants.all, model.descendants_of(test_node.id).all + # Assertions for subtree_of named scope + assert_equal test_node.subtree.all, model.subtree_of(test_node).all + assert_equal test_node.subtree.all, model.subtree_of(test_node.id).all + # Assertions for siblings_of named scope + assert_equal test_node.siblings.all, model.siblings_of(test_node).all + assert_equal test_node.siblings.all, model.siblings_of(test_node.id).all + end end end - def test_ancestroy_column_validation - node = TestNode.create - ['3', '10/2', '1/4/30', nil].each do |value| - node.write_attribute TestNode.ancestry_column, value - node.valid?; assert !node.errors.invalid?(TestNode.ancestry_column) - end - ['1/3/', '/2/3', 'a', 'a/b', '-34', '/54'].each do |value| - node.write_attribute TestNode.ancestry_column, value - node.valid?; assert node.errors.invalid?(TestNode.ancestry_column) + def test_ancestry_column_validation + AncestryTestDatabase.with_model do |model| + node = model.create + ['3', '10/2', '1/4/30', nil].each do |value| + node.send :write_attribute, model.ancestry_column, value + node.valid?; assert node.errors[model.ancestry_column].blank? + end + ['1/3/', '/2/3', 'a', 'a/b', '-34', '/54'].each do |value| + node.send :write_attribute, model.ancestry_column, value + node.valid?; assert !node.errors[model.ancestry_column].blank? + end end end def test_descendants_move_with_node - root1, root2, root3 = setup_test_nodes(TestNode, 3, 3).map(&:first) - assert_no_difference 'root1.descendants.size' do - assert_difference 'root2.descendants.size', root1.subtree.size do - root1.parent = root2 - root1.save! + AncestryTestDatabase.with_model :depth => 3, :width => 3 do |model, roots| + root1, root2, root3 = roots.map(&:first) + assert_no_difference 'root1.descendants.size' do + assert_difference 'root2.descendants.size', root1.subtree.size do + root1.parent = root2 + root1.save! + end end - end - assert_no_difference 'root2.descendants.size' do - assert_difference 'root3.descendants.size', root2.subtree.size do - root2.parent = root3 - root2.save! + assert_no_difference 'root2.descendants.size' do + assert_difference 'root3.descendants.size', root2.subtree.size do + root2.parent = root3 + root2.save! + end end - end - assert_no_difference 'root1.descendants.size' do - assert_difference 'root2.descendants.size', -root1.subtree.size do - assert_difference 'root3.descendants.size', -root1.subtree.size do - root1.parent = nil - root1.save! + assert_no_difference 'root1.descendants.size' do + assert_difference 'root2.descendants.size', -root1.subtree.size do + assert_difference 'root3.descendants.size', -root1.subtree.size do + root1.parent = nil + root1.save! + end end end end end def test_orphan_rootify_strategy - TestNode.orphan_strategy = :rootify - root = setup_test_nodes(TestNode, 3, 3).first.first - children = root.children.all - root.destroy - children.each do |child| - child.reload - assert child.is_root? - assert_equal 3, child.children.size + AncestryTestDatabase.with_model :depth => 3, :width => 3 do |model, roots| + model.orphan_strategy = :rootify + root = roots.first.first + children = root.children.all + root.destroy + children.each do |child| + child.reload + assert child.is_root? + assert_equal 3, child.children.size + end end end - + def test_orphan_destroy_strategy - TestNode.orphan_strategy = :destroy - root = setup_test_nodes(TestNode, 3, 3).first.first - assert_difference 'TestNode.count', -root.subtree.size do - root.destroy - end - node = TestNode.roots.first.children.first - assert_difference 'TestNode.count', -node.subtree.size do - node.destroy + AncestryTestDatabase.with_model :depth => 3, :width => 3 do |model, roots| + model.orphan_strategy = :destroy + root = roots.first.first + assert_difference 'model.count', -root.subtree.size do + root.destroy + end + node = model.roots.first.children.first + assert_difference 'model.count', -node.subtree.size do + node.destroy + end end end - + def test_orphan_restrict_strategy - TestNode.orphan_strategy = :restrict - setup_test_nodes(TestNode, 3, 3) - root = TestNode.roots.first - assert_raise Ancestry::AncestryException do - root.destroy - end - assert_nothing_raised Ancestry::AncestryException do - root.children.first.children.first.destroy + AncestryTestDatabase.with_model :depth => 3, :width => 3 do |model, roots| + model.orphan_strategy = :restrict + root = roots.first.first + assert_raise Ancestry::AncestryException do + root.destroy + end + assert_nothing_raised Ancestry::AncestryException do + root.children.first.children.first.destroy + end end - end def test_integrity_checking - # Check that there are no errors on a valid data set - setup_test_nodes(TestNode, 3, 3) - assert_nothing_raised do - TestNode.check_ancestry_integrity! + AncestryTestDatabase.with_model :width => 3, :depth => 3 do |model, roots| + # Check that there are no errors on a valid tree + assert_nothing_raised do + model.check_ancestry_integrity! + end end - - # Check detection of invalid format for ancestry column - setup_test_nodes(TestNode, 3, 3).first.first.update_attribute TestNode.ancestry_column, 'invalid_ancestry' - assert_raise Ancestry::AncestryIntegrityException do - TestNode.check_ancestry_integrity! + + AncestryTestDatabase.with_model :width => 3, :depth => 3 do |model, roots| + # Check detection of invalid format for ancestry column + roots.first.first.update_attribute model.ancestry_column, 'invalid_ancestry' + assert_raise Ancestry::AncestryIntegrityException do + model.check_ancestry_integrity! + end end - # Check detection of non-existent ancestor - setup_test_nodes(TestNode, 3, 3).first.first.update_attribute TestNode.ancestry_column, 35 - assert_raise Ancestry::AncestryIntegrityException do - TestNode.check_ancestry_integrity! + AncestryTestDatabase.with_model :width => 3, :depth => 3 do |model, roots| + # Check detection of non-existent ancestor + roots.first.first.update_attribute model.ancestry_column, 35 + assert_raise Ancestry::AncestryIntegrityException do + model.check_ancestry_integrity! + end end - - # Check detection of cyclic ancestry - node = setup_test_nodes(TestNode, 3, 3).first.first - node.update_attribute TestNode.ancestry_column, node.id - assert_raise Ancestry::AncestryIntegrityException do - TestNode.check_ancestry_integrity! + + AncestryTestDatabase.with_model :width => 3, :depth => 3 do |model, roots| + # Check detection of cyclic ancestry + node = roots.first.first + node.update_attribute model.ancestry_column, node.id + assert_raise Ancestry::AncestryIntegrityException do + model.check_ancestry_integrity! + end end - - # Check detection of conflicting parent id - TestNode.destroy_all - TestNode.create!(TestNode.ancestry_column => TestNode.create!(TestNode.ancestry_column => TestNode.create!(TestNode.ancestry_column => nil).id).id) - assert_raise Ancestry::AncestryIntegrityException do - TestNode.check_ancestry_integrity! + + AncestryTestDatabase.with_model do |model| + # Check detection of conflicting parent id + model.destroy_all + model.create!(model.ancestry_column => model.create!(model.ancestry_column => model.create!(model.ancestry_column => nil).id).id) + assert_raise Ancestry::AncestryIntegrityException do + model.check_ancestry_integrity! + end end end - - def assert_integrity_restoration + + def assert_integrity_restoration model assert_raise Ancestry::AncestryIntegrityException do - TestNode.check_ancestry_integrity! + model.check_ancestry_integrity! end - TestNode.restore_ancestry_integrity! + model.restore_ancestry_integrity! assert_nothing_raised do - TestNode.check_ancestry_integrity! + model.check_ancestry_integrity! end end - + def test_integrity_restoration # Check that integrity is restored for invalid format for ancestry column - setup_test_nodes(TestNode, 3, 3).first.first.update_attribute TestNode.ancestry_column, 'invalid_ancestry' - assert_integrity_restoration + AncestryTestDatabase.with_model :width => 3, :depth => 3 do |model, roots| + roots.first.first.update_attribute model.ancestry_column, 'invalid_ancestry' + assert_integrity_restoration model + end # Check that integrity is restored for non-existent ancestor - setup_test_nodes(TestNode, 3, 3).first.first.update_attribute TestNode.ancestry_column, 35 - assert_integrity_restoration - + AncestryTestDatabase.with_model :width => 3, :depth => 3 do |model, roots| + roots.first.first.update_attribute model.ancestry_column, 35 + assert_integrity_restoration model + end + # Check that integrity is restored for cyclic ancestry - node = setup_test_nodes(TestNode, 3, 3).first.first - node.update_attribute TestNode.ancestry_column, node.id - assert_integrity_restoration - + AncestryTestDatabase.with_model :width => 3, :depth => 3 do |model, roots| + node = roots.first.first + node.update_attribute model.ancestry_column, node.id + assert_integrity_restoration model + end + # Check that integrity is restored for conflicting parent id - TestNode.destroy_all - TestNode.create!(TestNode.ancestry_column => TestNode.create!(TestNode.ancestry_column => TestNode.create!(TestNode.ancestry_column => nil).id).id) - assert_integrity_restoration + AncestryTestDatabase.with_model do |model| + model.destroy_all + model.create!(model.ancestry_column => model.create!(model.ancestry_column => model.create!(model.ancestry_column => nil).id).id) + assert_integrity_restoration model + end end def test_arrangement - id_sorter = Proc.new do |a, b|; a.id <=> b.id; end - setup_test_nodes(TestNode, 3, 3) - arranged_nodes = TestNode.arrange - assert_equal 3, arranged_nodes.size - arranged_nodes.each do |node, children| - assert_equal node.children.sort(&id_sorter), children.keys.sort(&id_sorter) - children.each do |node, children| + AncestryTestDatabase.with_model :depth => 3, :width => 3 do |model, roots| + id_sorter = Proc.new do |a, b|; a.id <=> b.id; end + arranged_nodes = model.arrange + assert_equal 3, arranged_nodes.size + arranged_nodes.each do |node, children| assert_equal node.children.sort(&id_sorter), children.keys.sort(&id_sorter) children.each do |node, children| - assert_equal 0, children.size + assert_equal node.children.sort(&id_sorter), children.keys.sort(&id_sorter) + children.each do |node, children| + assert_equal 0, children.size + end end end end end def test_node_creation_though_scope - node = TestNode.create! - child = node.children.create - assert_equal node, child.parent - - other_child = child.siblings.create! - assert_equal node, other_child.parent - - grandchild = TestNode.children_of(child).new - grandchild.save - assert_equal child, grandchild.parent - - other_grandchild = TestNode.siblings_of(grandchild).new - other_grandchild.save! - assert_equal child, other_grandchild.parent + AncestryTestDatabase.with_model do |model| + node = model.create! + child = node.children.create + assert_equal node, child.parent + + other_child = child.siblings.create! + assert_equal node, other_child.parent + + grandchild = model.children_of(child).new + grandchild.save + assert_equal child, grandchild.parent + + other_grandchild = model.siblings_of(grandchild).new + other_grandchild.save! + assert_equal child, other_grandchild.parent + end end def test_validate_ancestry_exclude_self - parent = TestNode.create! - child = parent.children.create! - assert_raise ActiveRecord::RecordInvalid do - parent.update_attributes! :parent => child + AncestryTestDatabase.with_model do |model| + parent = model.create! + child = parent.children.create! + assert_raise ActiveRecord::RecordInvalid do + parent.update_attributes! :parent => child + end end end def test_depth_caching - roots = setup_test_nodes TestNode, 3, 3 - roots.each do |lvl0_node, lvl0_children| - assert_equal 0, lvl0_node.depth_cache - lvl0_children.each do |lvl1_node, lvl1_children| - assert_equal 1, lvl1_node.depth_cache - lvl1_children.each do |lvl2_node, lvl2_children| - assert_equal 2, lvl2_node.depth_cache + AncestryTestDatabase.with_model :depth => 3, :width => 3, :cache_depth => true, :depth_cache_column => :depth_cache do |model, roots| + roots.each do |lvl0_node, lvl0_children| + assert_equal 0, lvl0_node.depth_cache + lvl0_children.each do |lvl1_node, lvl1_children| + assert_equal 1, lvl1_node.depth_cache + lvl1_children.each do |lvl2_node, lvl2_children| + assert_equal 2, lvl2_node.depth_cache + end end end end end def test_depth_scopes - setup_test_nodes TestNode, 4, 4 - TestNode.before_depth(2).all? { |node| assert node.depth < 2 } - TestNode.to_depth(2).all? { |node| assert node.depth <= 2 } - TestNode.at_depth(2).all? { |node| assert node.depth == 2 } - TestNode.from_depth(2).all? { |node| assert node.depth >= 2 } - TestNode.after_depth(2).all? { |node| assert node.depth > 2 } + AncestryTestDatabase.with_model :depth => 4, :width => 2, :cache_depth => true do |model, roots| + model.before_depth(2).all? { |node| assert node.depth < 2 } + model.to_depth(2).all? { |node| assert node.depth <= 2 } + model.at_depth(2).all? { |node| assert node.depth == 2 } + model.from_depth(2).all? { |node| assert node.depth >= 2 } + model.after_depth(2).all? { |node| assert node.depth > 2 } + end end def test_depth_scopes_unavailable - assert_raise Ancestry::AncestryException do - AlternativeTestNode.before_depth(1) - AlternativeTestNode.to_depth(1) - AlternativeTestNode.at_depth(1) - AlternativeTestNode.from_depth(1) - AlternativeTestNode.after_depth(1) + AncestryTestDatabase.with_model do |model| + assert_raise Ancestry::AncestryException do + model.before_depth(1) + end + assert_raise Ancestry::AncestryException do + model.to_depth(1) + end + assert_raise Ancestry::AncestryException do + model.at_depth(1) + end + assert_raise Ancestry::AncestryException do + model.from_depth(1) + end + assert_raise Ancestry::AncestryException do + model.after_depth(1) + end end end @@ -446,38 +523,40 @@ def test_invalid_has_ancestry_options end def test_build_ancestry_from_parent_ids - [ParentIdTestNode.create!].each do |parent| - (Array.new(5) { ParentIdTestNode.create! :parent_id => parent.id }).each do |parent| - (Array.new(5) { ParentIdTestNode.create! :parent_id => parent.id }).each do |parent| - (Array.new(5) { ParentIdTestNode.create! :parent_id => parent.id }) + AncestryTestDatabase.with_model :skip_ancestry => true, :extra_columns => {:parent_id => :integer} do |model| + [model.create!].each do |parent| + (Array.new(5) { model.create! :parent_id => parent.id }).each do |parent| + (Array.new(5) { model.create! :parent_id => parent.id }).each do |parent| + (Array.new(5) { model.create! :parent_id => parent.id }) + end end end - end - # Assert all nodes where created - assert_equal 156, ParentIdTestNode.count - - ParentIdTestNode.has_ancestry - ParentIdTestNode.build_ancestry_from_parent_ids! - - # Assert ancestry integirty - assert_nothing_raised do - ParentIdTestNode.check_ancestry_integrity! - end - - roots = ParentIdTestNode.roots.all - # Assert single root node - assert_equal 1, roots.size - - # Assert it has 5 children - roots.each do |parent| - assert 5, parent.children.count - parent.children.each do |parent| + # Assert all nodes where created + assert_equal 156, model.count + + model.has_ancestry + model.build_ancestry_from_parent_ids! + + # Assert ancestry integrity + assert_nothing_raised do + model.check_ancestry_integrity! + end + + roots = model.roots.all + # Assert single root node + assert_equal 1, roots.size + + # Assert it has 5 children + roots.each do |parent| assert 5, parent.children.count parent.children.each do |parent| assert 5, parent.children.count parent.children.each do |parent| - assert 0, parent.children.count + assert 5, parent.children.count + parent.children.each do |parent| + assert 0, parent.children.count + end end end end @@ -485,106 +564,124 @@ def test_build_ancestry_from_parent_ids end def test_rebuild_depth_cache - setup_test_nodes TestNode, 3, 3 - TestNode.connection.execute("update test_nodes set depth_cache = null;") + AncestryTestDatabase.with_model :depth => 3, :width => 3, :cache_depth => true, :depth_cache_column => :depth_cache do |model, roots| + model.connection.execute("update test_nodes set depth_cache = null;") - # Assert cache was emptied correctly - TestNode.all.each do |test_node| - assert_equal nil, test_node.depth_cache - end + # Assert cache was emptied correctly + model.all.each do |test_node| + assert_equal nil, test_node.depth_cache + end - # Rebuild cache - TestNode.rebuild_depth_cache! + # Rebuild cache + model.rebuild_depth_cache! - # Assert cache was rebuild correctly - TestNode.all.each do |test_node| - assert_equal test_node.depth, test_node.depth_cache + # Assert cache was rebuild correctly + model.all.each do |test_node| + assert_equal test_node.depth, test_node.depth_cache + end end end def test_exception_when_rebuilding_depth_cache_for_model_without_depth_caching - assert_raise Ancestry::AncestryException do - AlternativeTestNode.rebuild_depth_cache! + AncestryTestDatabase.with_model do |model| + assert_raise Ancestry::AncestryException do + model.rebuild_depth_cache! + end end end def test_descendants_with_depth_constraints - setup_test_nodes TestNode, 4, 4 - - assert_equal 4, TestNode.roots.first.descendants(:before_depth => 2).count - assert_equal 20, TestNode.roots.first.descendants(:to_depth => 2).count - assert_equal 16, TestNode.roots.first.descendants(:at_depth => 2).count - assert_equal 80, TestNode.roots.first.descendants(:from_depth => 2).count - assert_equal 64, TestNode.roots.first.descendants(:after_depth => 2).count + AncestryTestDatabase.with_model :depth => 4, :width => 4, :cache_depth => true do |model, roots| + assert_equal 4, model.roots.first.descendants(:before_depth => 2).count + assert_equal 20, model.roots.first.descendants(:to_depth => 2).count + assert_equal 16, model.roots.first.descendants(:at_depth => 2).count + assert_equal 80, model.roots.first.descendants(:from_depth => 2).count + assert_equal 64, model.roots.first.descendants(:after_depth => 2).count + end end - + def test_subtree_with_depth_constraints - setup_test_nodes TestNode, 4, 4 - - assert_equal 5, TestNode.roots.first.subtree(:before_depth => 2).count - assert_equal 21, TestNode.roots.first.subtree(:to_depth => 2).count - assert_equal 16, TestNode.roots.first.subtree(:at_depth => 2).count - assert_equal 80, TestNode.roots.first.subtree(:from_depth => 2).count - assert_equal 64, TestNode.roots.first.subtree(:after_depth => 2).count + AncestryTestDatabase.with_model :depth => 4, :width => 4, :cache_depth => true do |model, roots| + assert_equal 5, model.roots.first.subtree(:before_depth => 2).count + assert_equal 21, model.roots.first.subtree(:to_depth => 2).count + assert_equal 16, model.roots.first.subtree(:at_depth => 2).count + assert_equal 80, model.roots.first.subtree(:from_depth => 2).count + assert_equal 64, model.roots.first.subtree(:after_depth => 2).count + end end - - + + def test_ancestors_with_depth_constraints - node1 = TestNode.create! - node2 = node1.children.create! - node3 = node2.children.create! - node4 = node3.children.create! - node5 = node4.children.create! - leaf = node5.children.create! - - assert_equal [node1, node2, node3], leaf.ancestors(:before_depth => -2) - assert_equal [node1, node2, node3, node4], leaf.ancestors(:to_depth => -2) - assert_equal [node4], leaf.ancestors(:at_depth => -2) - assert_equal [node4, node5], leaf.ancestors(:from_depth => -2) - assert_equal [node5], leaf.ancestors(:after_depth => -2) + AncestryTestDatabase.with_model :cache_depth => true do |model| + node1 = model.create! + node2 = node1.children.create! + node3 = node2.children.create! + node4 = node3.children.create! + node5 = node4.children.create! + leaf = node5.children.create! + + assert_equal [node1, node2, node3], leaf.ancestors(:before_depth => -2) + assert_equal [node1, node2, node3, node4], leaf.ancestors(:to_depth => -2) + assert_equal [node4], leaf.ancestors(:at_depth => -2) + assert_equal [node4, node5], leaf.ancestors(:from_depth => -2) + assert_equal [node5], leaf.ancestors(:after_depth => -2) + end end - + def test_path_with_depth_constraints - node1 = TestNode.create! - node2 = node1.children.create! - node3 = node2.children.create! - node4 = node3.children.create! - node5 = node4.children.create! - leaf = node5.children.create! - - assert_equal [node1, node2, node3], leaf.path(:before_depth => -2) - assert_equal [node1, node2, node3, node4], leaf.path(:to_depth => -2) - assert_equal [node4], leaf.path(:at_depth => -2) - assert_equal [node4, node5, leaf], leaf.path(:from_depth => -2) - assert_equal [node5, leaf], leaf.path(:after_depth => -2) + AncestryTestDatabase.with_model :cache_depth => true do |model| + node1 = model.create! + node2 = node1.children.create! + node3 = node2.children.create! + node4 = node3.children.create! + node5 = node4.children.create! + leaf = node5.children.create! + + assert_equal [node1, node2, node3], leaf.path(:before_depth => -2) + assert_equal [node1, node2, node3, node4], leaf.path(:to_depth => -2) + assert_equal [node4], leaf.path(:at_depth => -2) + assert_equal [node4, node5, leaf], leaf.path(:from_depth => -2) + assert_equal [node5, leaf], leaf.path(:after_depth => -2) + end end def test_exception_on_unknown_depth_column - assert_raise Ancestry::AncestryException do - TestNode.create!.subtree(:this_is_not_a_valid_depth_option => 42) + AncestryTestDatabase.with_model :cache_depth => true do |model| + assert_raise Ancestry::AncestryException do + model.create!.subtree(:this_is_not_a_valid_depth_option => 42) + end end end def test_sti_support - node1 = TestNodeSub1.create! - node2 = TestNodeSub2.create! :parent => node1 - node3 = TestNodeSub1.create! :parent => node2 - node4 = TestNodeSub2.create! :parent => node3 - node5 = TestNodeSub1.create! :parent => node4 - - assert_equal [node2, node3, node4, node5], node1.descendants - assert_equal [node1, node2, node3, node4, node5], node1.subtree - assert_equal [node1, node2, node3, node4], node5.ancestors - assert_equal [node1, node2, node3, node4, node5], node5.path + AncestryTestDatabase.with_model :extra_columns => {:type => :string} do |model| + subclass1 = Object.const_set 'Subclass1', Class.new(model) + (class << subclass1; self; end).send :define_method, :model_name do; Struct.new(:human, :underscore).new 'Subclass1', 'subclass1'; end + subclass2 = Object.const_set 'Subclass2', Class.new(model) + (class << subclass2; self; end).send :define_method, :model_name do; Struct.new(:human, :underscore).new 'Subclass1', 'subclass1'; end + + node1 = subclass1.create! + node2 = subclass2.create! :parent => node1 + node3 = subclass1.create! :parent => node2 + node4 = subclass2.create! :parent => node3 + node5 = subclass1.create! :parent => node4 + + model.all.each do |node| + assert [subclass1, subclass2].include?(node.class) + end + + assert_equal [node2.id, node3.id, node4.id, node5.id], node1.descendants.map(&:id) + assert_equal [node1.id, node2.id, node3.id, node4.id, node5.id], node1.subtree.map(&:id) + assert_equal [node1.id, node2.id, node3.id, node4.id], node5.ancestors.map(&:id) + assert_equal [node1.id, node2.id, node3.id, node4.id, node5.id], node5.path.map(&:id) + end end def test_arrange_order_option - # In Ruby versions before 1.9 hashes aren't ordered so this doesn't make sense - unless RUBY_VERSION =~ /^1\.8/ - roots = setup_test_nodes TestNode, 3, 3 - descending_nodes_lvl0 = TestNode.arrange :order => 'id desc' - ascending_nodes_lvl0 = TestNode.arrange :order => 'id asc' - + AncestryTestDatabase.with_model :width => 3, :depth => 3 do |model, roots| + descending_nodes_lvl0 = model.arrange :order => 'id desc' + ascending_nodes_lvl0 = model.arrange :order => 'id asc' + descending_nodes_lvl0.keys.zip(ascending_nodes_lvl0.keys.reverse).each do |descending_node, ascending_node| assert_equal descending_node, ascending_node descending_nodes_lvl1 = descending_nodes_lvl0[descending_node] diff --git a/test/schema.rb b/test/schema.rb deleted file mode 100644 index 9d265c6f..00000000 --- a/test/schema.rb +++ /dev/null @@ -1,24 +0,0 @@ -ActiveRecord::Schema.define(:version => 0) do - create_table :test_nodes, :force => true do |t| - t.string :ancestry - t.integer :depth_cache - t.string :type - end - - create_table :alternative_test_nodes, :force => true do |t| - t.string :alternative_ancestry - end - - create_table :other_test_nodes, :force => true do |t| - t.string :ancestry - end - - create_table :parent_id_test_nodes, :force => true do |t| - t.string :ancestry - t.integer :parent_id - end - - create_table :acts_as_tree_test_nodes, :force => true do |t| - t.string :ancestry - end -end \ No newline at end of file diff --git a/test/test_helper.rb b/test/test_helper.rb deleted file mode 100644 index 87db7435..00000000 --- a/test/test_helper.rb +++ /dev/null @@ -1,31 +0,0 @@ -ENV['RAILS_ENV'] = 'test' -ENV['RAILS_ROOT'] ||= File.dirname(__FILE__) + '/../../../..' - -require 'test/unit' -require File.expand_path(File.join(ENV['RAILS_ROOT'], 'config/environment.rb')) -require 'test_help' - -def load_schema - config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml')) - ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log") - db_adapter = ENV['DB'] - # no db passed, try one of these fine config-free DBs before bombing. - db_adapter ||= begin - require 'rubygems' - require 'sqlite' - 'sqlite' - rescue MissingSourceFile - begin - require 'sqlite3' - 'sqlite3' - rescue MissingSourceFile - end - end - - if db_adapter.nil? - raise "No DB Adapter selected. Pass the DB= option to pick one, or install Sqlite or Sqlite3." - end - ActiveRecord::Base.establish_connection(config[db_adapter]) - load(File.dirname(__FILE__) + "/schema.rb") - require File.dirname(__FILE__) + '/../init.rb' -end \ No newline at end of file