Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Applied [82f6a33] Fixed it for Rails 3.2 and broke it for 2.x, change…

…d version 1.2.6 and activerecord dependency to >= 3.0.0

Dropped support for primary_key_format
Added rake task test_all
Bumped version to 2.0.0
Bumped activerecord dependency to >= 3.0.0
Fixed tests for 3.0.0
  • Loading branch information...
commit 8850dcaf66f51e9a17f1d2756e6ba8bef52feb15 1 parent d675199
Stefan Henzen authored
View
3  .gitignore
@@ -3,4 +3,5 @@ doc
**/*.log
**/*.db
test/database.yml
-coverage
+coverage
+Gemfile.lock
View
13 Gemfile
@@ -0,0 +1,13 @@
+source 'http://rubygems.org'
+
+gemspec
+
+group :development do
+ gem 'rdoc'
+end
+
+group :test do
+ gem 'sqlite3'
+ gem 'pg'
+ gem 'mysql'
+end
View
21 Rakefile
@@ -1,7 +1,6 @@
require 'rake'
require 'rake/testtask'
-require 'rake/rdoctask'
-require 'rcov/rcovtask'
+require 'rdoc/task'
desc 'Default: run unit tests.'
task :default => :test
@@ -9,17 +8,21 @@ task :default => :test
desc 'Test the ancestry plugin.'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
+ t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end
-desc 'Determine test code coverage for the ancestry plugin.'
-Rcov::RcovTask.new(:coverage) do |t|
- t.libs << 'lib'
- t.test_files = FileList['test/**/*_test.rb']
- t.verbose = true
- t.output_dir = "test/coverage"
- t.rcov_opts << "-x /gems/,/library/"
+desc 'Test the ancestry plugin with multiple databases and activerecord versions.'
+task :test_all do |t|
+ commands = []
+ %w(3.0.0 3.1.0 3.2.0).each do |activerecord_version|
+ %w(sqlite3 postgresql mysql).each do |database_adapter|
+ commands << "rake test ar=#{activerecord_version} db=#{database_adapter}"
+ end
+ end
+
+ exec commands.join(' && ')
end
desc 'Generate documentation for the ancestry plugin.'
View
4 ancestry.gemspec
@@ -3,7 +3,7 @@ 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.3.0'
+ s.version = '2.0.0'
s.author = 'Stefan Kroes'
s.email = 's.a.kroes@gmail.com'
@@ -22,5 +22,5 @@ Gem::Specification.new do |s|
'README.rdoc'
]
- s.add_dependency 'activerecord', '>= 2.3.14'
+ s.add_dependency 'activerecord', '>= 3.0.0'
end
View
9 lib/ancestry/has_ancestry.rb
@@ -3,7 +3,7 @@ def has_ancestry options = {}
# Check options
raise Ancestry::AncestryException.new("Options for has_ancestry must be in a hash.") unless options.is_a? Hash
options.each do |key, value|
- unless [:ancestry_column, :orphan_strategy, :cache_depth, :depth_cache_column, :primary_key_format].include? key
+ unless [:ancestry_column, :orphan_strategy, :cache_depth, :depth_cache_column].include? key
raise Ancestry::AncestryException.new("Unknown option for has_ancestry: #{key.inspect} => #{value.inspect}.")
end
end
@@ -27,8 +27,7 @@ def has_ancestry options = {}
self.base_class = self
# Validate format of ancestry column value
- primary_key_format = options[:primary_key_format] || /[0-9]+/
- validates_format_of ancestry_column, :with => /\A#{primary_key_format.source}(\/#{primary_key_format.source})*\Z/, :allow_nil => true
+ validates_format_of ancestry_column, :with => /\A[0-9]+(\/[0-9]+)*\Z/, :allow_nil => true
# Validate that the ancestor ids don't include own id
validate :ancestry_exclude_self
@@ -47,8 +46,8 @@ def has_ancestry options = {}
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 #{table_name}.#{ancestry_column} is null then 0 else 1 end), #{table_name}.#{ancestry_column}"
- send scope_method, :ordered_by_ancestry_and, lambda { |order| {:order => "(case when #{table_name}.#{ancestry_column} is null then 0 else 1 end), #{table_name}.#{ancestry_column}, #{order}"} }
+ send scope_method, :ordered_by_ancestry, reorder("(case when #{table_name}.#{ancestry_column} is null then 0 else 1 end), #{table_name}.#{ancestry_column}")
+ send scope_method, :ordered_by_ancestry_and, lambda { |order| reorder("(case when #{table_name}.#{ancestry_column} is null then 0 else 1 end), #{table_name}.#{ancestry_column}, #{order}") }
# Update descendants with new ancestry before save
before_save :update_descendants_with_new_ancestry
View
4 test/database.example.yml
@@ -1,6 +1,3 @@
-sqlite:
- adapter: sqlite
- database: ":memory:"
sqlite3:
adapter: sqlite3
database: ":memory:"
@@ -9,6 +6,7 @@ postgresql:
database: ancestry_test
username: ancestry
password: ancestry
+ min_messages: WARNING
mysql:
adapter: mysql
host: localhost
View
32 test/environment.rb
@@ -1,13 +1,20 @@
require 'rubygems'
-Gem.activate 'activerecord', ENV['ar'] || '3.0.0'
+
+if ENV['ar'].nil?
+ gem 'activerecord'
+else
+ gem 'activerecord', ENV['ar']
+end
+
require 'active_record'
require 'active_support/test_case'
require 'test/unit'
-require 'lib/ancestry'
+require 'ancestry'
+require 'debugger' if RUBY_VERSION =~ /\A1.9/
class AncestryTestDatabase
def self.setup
- ActiveRecord::Base.logger
+ ActiveRecord::Base.logger = ActiveSupport::BufferedLogger.new('log/test.log')
ActiveRecord::Base.establish_connection YAML.load(File.open(File.join(File.dirname(__FILE__), 'database.yml')).read)[ENV['db'] || 'sqlite3']
end
@@ -15,27 +22,26 @@ def self.with_model options = {}
depth = options.delete(:depth) || 0
width = options.delete(:width) || 0
extra_columns = options.delete(:extra_columns)
- primary_key_type = options.delete(:primary_key_type) || :default
default_scope_params = options.delete(:default_scope_params)
- ActiveRecord::Base.connection.create_table 'test_nodes', :id => (primary_key_type == :default) do |table|
- table.string :id, :null => false if primary_key_type == :string
+ 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
+
+ testmethod = caller[0][/`.*'/][1..-2]
+ model_name = testmethod.camelize + "TestNode"
begin
model = Class.new(ActiveRecord::Base)
- (class << model; self; end).send :define_method, :model_name do; Struct.new(:human, :underscore, :i18n_key).new 'TestNode', 'test_node', 'test_node'; end
+ const_set model_name, model
- if primary_key_type == :string
- model.before_create { |instance| instance.id = ActiveSupport::SecureRandom.hex(10) }
- end
- model.send :set_table_name, 'test_nodes'
+ model.table_name = 'test_nodes'
model.send :default_scope, default_scope_params if default_scope_params.present?
+
model.has_ancestry options unless options.delete(:skip_ancestry)
if depth > 0
@@ -44,7 +50,9 @@ def self.with_model options = {}
yield model
end
ensure
+ model.reset_column_information
ActiveRecord::Base.connection.drop_table 'test_nodes'
+ remove_const model_name
end
end
@@ -62,6 +70,6 @@ def self.create_test_nodes model, depth, width, parent = nil
puts "\nRunning Ancestry test suite:"
puts " Ruby: #{RUBY_VERSION}"
-puts " ActiveRecord: #{ENV['ar'] || '3.0.0'}"
+puts " ActiveRecord: #{ActiveRecord::VERSION::STRING}"
puts " Database: #{ActiveRecord::Base.connection.adapter_name}\n\n"
View
53 test/has_ancestry_test.rb
@@ -1,4 +1,4 @@
-require File.join(File.expand_path(File.dirname(__FILE__)), "environment")
+require "environment"
class HasAncestryTreeTest < ActiveSupport::TestCase
def test_default_ancestry_column
@@ -176,35 +176,6 @@ def test_tree_navigation
end
end
- def test_ancestors_with_string_primary_keys
- AncestryTestDatabase.with_model :depth => 3, :width => 3, :primary_key_type => :string, :primary_key_format => /[a-z0-9]+/ do |model, roots|
- 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
- lvl0_children.each do |lvl1_node, lvl1_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
- 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
- end
- end
- end
- end
- end
-
def test_scopes
AncestryTestDatabase.with_model :depth => 3, :width => 3 do |model, roots|
# Roots assertion
@@ -242,18 +213,6 @@ def test_ancestry_column_validation
node.valid?; assert !node.errors[model.ancestry_column].blank?
end
end
-
- AncestryTestDatabase.with_model :primary_key_format => /[0-9a-z]+/ do |model|
- node = model.create
- ['xk7', '9x1/l4n', 'r1c/4z9/8ps', nil].each do |value|
- node.send :write_attribute, model.ancestry_column, value
- node.valid?; assert node.errors[model.ancestry_column].blank?
- end
- ['s9a/xk2/', '/s92/d92', 'X', 'X/Y', 'S23', '/xk2'].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
@@ -756,4 +715,14 @@ def test_node_excluded_by_default_scope_should_be_rootified
assert child.reload.is_root?
end
end
+
+ def test_arrangement_nesting
+ AncestryTestDatabase.with_model :extra_columns => {:name => :string} do |model|
+ model.send :default_scope, model.order('name')
+
+ model.create!(:name => 'Linux').children.create! :name => 'Debian'
+
+ assert_equal 1, model.arrange.count
+ end
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.