Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixes for 1.2.1

  • Loading branch information...
commit 34a13a921fa1b133b00f7d9d611852005ae997b2 1 parent f1955bb
@stefankroes stefankroes authored
View
1  .gitignore
@@ -2,3 +2,4 @@ doc
*.gem
**/*.log
**/*.db
+test/database.yml
View
40 lib/ancestry/class_methods.rb
@@ -48,28 +48,38 @@ def arrange options = {}
end
# Integrity checking
- def check_ancestry_integrity!
+ def check_ancestry_integrity! options = {}
parents = {}
+ exceptions = [] if options[:report] == :list
# For each node ...
self.base_class.all.each do |node|
- # ... check validity of 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
- node.ancestor_ids.each do |ancestor_id|
- unless exists? ancestor_id
- raise Ancestry::AncestryIntegrityException.new("Reference to non-existent node in node #{node.id}: #{ancestor_id}.")
+ begin
+ # ... check validity of 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
- end
- # ... check that all node parents are consistent with values observed earlier
- node.path_ids.zip([nil] + node.path_ids).each do |node_id, parent_id|
- parents[node_id] = parent_id unless parents.has_key? node_id
- unless parents[node_id] == parent_id
- raise Ancestry::AncestryIntegrityException.new("Conflicting parent id in node #{node.id}: #{parent_id || 'nil'} for node #{node_id}, expecting #{parents[node_id] || 'nil'}")
+ # ... check that all ancestors exist
+ node.ancestor_ids.each do |ancestor_id|
+ unless exists? ancestor_id
+ raise Ancestry::AncestryIntegrityException.new "Reference to non-existent node in node #{node.id}: #{ancestor_id}."
+ end
+ end
+ # ... check that all node parents are consistent with values observed earlier
+ node.path_ids.zip([nil] + node.path_ids).each do |node_id, parent_id|
+ parents[node_id] = parent_id unless parents.has_key? node_id
+ unless parents[node_id] == parent_id
+ raise Ancestry::AncestryIntegrityException.new "Conflicting parent id found in node #{node.id}: #{parent_id || 'nil'} for node #{node_id} while expecting #{parents[node_id] || 'nil'}"
+ end
+ end
+ rescue Ancestry::AncestryIntegrityException => integrity_exception
+ case options[:report]
+ when :list then exceptions << integrity_exception
+ when :echo then puts integrity_exception
+ else raise integrity_exception
end
end
end
+ exceptions if options[:report] == :list
end
# Integrity restoration
View
6 lib/ancestry/has_ancestry.rb
@@ -36,8 +36,12 @@ def has_ancestry options = {}
# Validate that the ancestor ids don't include own id
validate :ancestry_exclude_self
+ # Save ActiveRecord version
+ self.cattr_accessor :rails_3
+ self.rails_3 = defined?(ActiveRecord::VERSION) and ActiveRecord::VERSION::MAJOR >= 3
+
# Workaround to support Rails 2
- scope_method = if ActiveRecord::VERSION::MAJOR < 3 then :named_scope else :scope end
+ scope_method = if rails_3 then :scope else :named_scope end
# Named scopes
View
6 lib/ancestry/instance_methods.rb
@@ -210,10 +210,10 @@ def ancestry_callbacks_disabled?
# Workaround to support Rails 2
def add_error_to_base error
- if ActiveRecord::VERSION::MAJOR < 3
- errors.add_to_base error
- else
+ if rails_3
errors[:base] << error
+ else
+ errors.add_to_base error
end
end
end
View
0  test/database.yml → test/database.example.yml
File renamed without changes
View
62 test/environment.rb
@@ -0,0 +1,62 @@
+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 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 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, depth - 1, width, node)]
+ end
+ else; []; end
+ end
+end
+
+AncestryTestDatabase.setup
+
+puts "\nRunning Ancestry test suite:"
+puts " Ruby: #{RUBY_VERSION}"
+puts " ActiveRecord: #{ENV['ar'] || '3.0.0'}"
+puts " Database: #{ActiveRecord::Base.connection.adapter_name}\n\n"
+
View
79 test/has_ancestry_test.rb
@@ -1,64 +1,4 @@
-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 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 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, 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"
+require File.join(File.expand_path(File.dirname(__FILE__)), "environment")
class HasAncestryTreeTest < ActiveSupport::TestCase
def test_default_ancestry_column
@@ -348,6 +288,7 @@ def test_integrity_checking
assert_nothing_raised do
model.check_ancestry_integrity!
end
+ assert_equal 0, model.check_ancestry_integrity!(:report => :list).size
end
AncestryTestDatabase.with_model :width => 3, :depth => 3 do |model, roots|
@@ -356,6 +297,7 @@ def test_integrity_checking
assert_raise Ancestry::AncestryIntegrityException do
model.check_ancestry_integrity!
end
+ assert_equal 1, model.check_ancestry_integrity!(:report => :list).size
end
AncestryTestDatabase.with_model :width => 3, :depth => 3 do |model, roots|
@@ -364,6 +306,7 @@ def test_integrity_checking
assert_raise Ancestry::AncestryIntegrityException do
model.check_ancestry_integrity!
end
+ assert_equal 1, model.check_ancestry_integrity!(:report => :list).size
end
AncestryTestDatabase.with_model :width => 3, :depth => 3 do |model, roots|
@@ -373,6 +316,7 @@ def test_integrity_checking
assert_raise Ancestry::AncestryIntegrityException do
model.check_ancestry_integrity!
end
+ assert_equal 1, model.check_ancestry_integrity!(:report => :list).size
end
AncestryTestDatabase.with_model do |model|
@@ -382,6 +326,7 @@ def test_integrity_checking
assert_raise Ancestry::AncestryIntegrityException do
model.check_ancestry_integrity!
end
+ assert_equal 1, model.check_ancestry_integrity!(:report => :list).size
end
end
@@ -533,8 +478,8 @@ def test_build_ancestry_from_parent_ids
end
# Assert all nodes where created
- assert_equal 156, model.count
-
+ assert_equal (0..3).map { |n| 5 ** n }.sum, model.count
+
model.has_ancestry
model.build_ancestry_from_parent_ids!
@@ -549,13 +494,13 @@ def test_build_ancestry_from_parent_ids
# Assert it has 5 children
roots.each do |parent|
- assert 5, parent.children.count
+ assert_equal 5, parent.children.count
parent.children.each do |parent|
- assert 5, parent.children.count
+ assert_equal 5, parent.children.count
parent.children.each do |parent|
- assert 5, parent.children.count
+ assert_equal 5, parent.children.count
parent.children.each do |parent|
- assert 0, parent.children.count
+ assert_equal 0, parent.children.count
end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.