Commit 1f06cf88 authored by Eric Davis's avatar Eric Davis

Converted Menus to a Tree structure to allow submenus.

* Bundle the rubytree gem
* Patched RubyTree's TreeNode to add some additional methods.
* Converted the menu rendering to walk the Tree of MenuItems to render
  each item
* Added a menu option for :parent_menu to make this menu a child of the parent
* Added a bunch of tests
* Made MenuItem a subclass of Tree::TreeNode in order to use it's methods
  directly
* Changed the exceptions in MenuItem#new to be ArgumentErrors instead of the
  generic RuntimeError

  #4250

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@3090 e93f8b46-1217-0410-a6f0-8f06a7374b81
parent 5a9528cf
......@@ -50,6 +50,8 @@ Rails::Initializer.run do |config|
# It will automatically turn deliveries on
config.action_mailer.perform_deliveries = false
config.gem 'rubytree', :lib => 'tree'
# Load any local configuration that is kept out of source control
# (e.g. gems, patches).
if File.exists?(File.join(File.dirname(__FILE__), 'additional_environment.rb'))
......
This diff is collapsed.
# Redmine - project management software
# Copyright (C) 2006-2009 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require File.dirname(__FILE__) + '/../../../../test_helper'
class Redmine::MenuManager::MapperTest < Test::Unit::TestCase
context "Mapper#initialize" do
should "be tested"
end
def test_push_onto_root
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.exists?(:test_overview)
end
def test_push_onto_parent
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.push :test_child, { :controller => 'projects', :action => 'show'}, {:parent_menu => :test_overview}
assert menu_mapper.exists?(:test_child)
assert_equal :test_child, menu_mapper.find(:test_child).name
end
def test_push_onto_grandparent
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.push :test_child, { :controller => 'projects', :action => 'show'}, {:parent_menu => :test_overview}
menu_mapper.push :test_grandchild, { :controller => 'projects', :action => 'show'}, {:parent_menu => :test_child}
assert menu_mapper.exists?(:test_grandchild)
grandchild = menu_mapper.find(:test_grandchild)
assert_equal :test_grandchild, grandchild.name
assert_equal :test_child, grandchild.parent_menu
end
def test_push_first
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {:first => true}
root = menu_mapper.find(:root)
assert_equal 5, root.children.size
{0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
assert_not_nil root.children[position]
assert_equal name, root.children[position].name
end
end
def test_push_before
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {:before => :test_fourth}
root = menu_mapper.find(:root)
assert_equal 5, root.children.size
{0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
assert_not_nil root.children[position]
assert_equal name, root.children[position].name
end
end
def test_push_after
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {:after => :test_third}
root = menu_mapper.find(:root)
assert_equal 5, root.children.size
{0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
assert_not_nil root.children[position]
assert_equal name, root.children[position].name
end
end
def test_push_last
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {:last => true}
menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {}
root = menu_mapper.find(:root)
assert_equal 5, root.children.size
{0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
assert_not_nil root.children[position]
assert_equal name, root.children[position].name
end
end
def test_exists_for_child_node
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
menu_mapper.push :test_child, { :controller => 'projects', :action => 'show'}, {:parent_menu => :test_overview }
assert menu_mapper.exists?(:test_child)
end
def test_exists_for_invalid_node
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
assert !menu_mapper.exists?(:nothing)
end
def test_find
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
item = menu_mapper.find(:test_overview)
assert_equal :test_overview, item.name
assert_equal({:controller => 'projects', :action => 'show'}, item.url)
end
def test_find_missing
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
item = menu_mapper.find(:nothing)
assert_equal nil, item
end
def test_delete
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
assert_not_nil menu_mapper.delete(:test_overview)
assert_nil menu_mapper.find(:test_overview)
end
def test_delete_missing
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
assert_nil menu_mapper.delete(:test_missing)
end
end
# Redmine - project management software
# Copyright (C) 2006-2009 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require File.dirname(__FILE__) + '/../../../../test_helper'
class Redmine::MenuManager::MenuHelperTest < HelperTestCase
include Redmine::MenuManager::MenuHelper
include ActionController::Assertions::SelectorAssertions
fixtures :users, :members, :projects, :enabled_modules
# Used by assert_select
def html_document
HTML::Document.new(@response.body)
end
def setup
super
@response = ActionController::TestResponse.new
# Stub the current menu item in the controller
def @controller.current_menu_item
:index
end
end
context "MenuManager#current_menu_item" do
should "be tested"
end
context "MenuManager#render_main_menu" do
should "be tested"
end
context "MenuManager#render_menu" do
should "be tested"
end
context "MenuManager#menu_item_and_children" do
should "be tested"
end
context "MenuManager#extract_node_details" do
should "be tested"
end
def test_render_single_menu_node
node = Redmine::MenuManager::MenuItem.new(:testing, '/test', { })
@response.body = render_single_menu_node(node, 'This is a test', node.url, false)
assert_select("a.testing", "This is a test")
end
def test_render_menu_node
single_node = Redmine::MenuManager::MenuItem.new(:single_node, '/test', { })
@response.body = render_menu_node(single_node, nil)
assert_select("li") do
assert_select("a.single-node", "Single node")
end
end
def test_render_menu_node_with_nested_items
parent_node = Redmine::MenuManager::MenuItem.new(:parent_node, '/test', { })
parent_node << Redmine::MenuManager::MenuItem.new(:child_one_node, '/test', { })
parent_node << Redmine::MenuManager::MenuItem.new(:child_two_node, '/test', { })
parent_node <<
Redmine::MenuManager::MenuItem.new(:child_three_node, '/test', { }) <<
Redmine::MenuManager::MenuItem.new(:child_three_inner_node, '/test', { })
@response.body = render_menu_node(parent_node, nil)
assert_select("li") do
assert_select("a.parent-node", "Parent node")
assert_select("ul") do
assert_select("li a.child-one-node", "Child one node")
assert_select("li a.child-two-node", "Child two node")
assert_select("li") do
assert_select("a.child-three-node", "Child three node")
assert_select("ul") do
assert_select("li a.child-three-inner-node", "Child three inner node")
end
end
end
end
end
def test_menu_items_for_should_yield_all_items_if_passed_a_block
menu_name = :test_menu_items_for_should_yield_all_items_if_passed_a_block
Redmine::MenuManager.map menu_name do |menu|
menu.push(:a_menu, '/', { })
menu.push(:a_menu_2, '/', { })
menu.push(:a_menu_3, '/', { })
end
items_yielded = []
menu_items_for(menu_name) do |item|
items_yielded << item
end
assert_equal 3, items_yielded.size
end
def test_menu_items_for_should_return_all_items
menu_name = :test_menu_items_for_should_return_all_items
Redmine::MenuManager.map menu_name do |menu|
menu.push(:a_menu, '/', { })
menu.push(:a_menu_2, '/', { })
menu.push(:a_menu_3, '/', { })
end
items = menu_items_for(menu_name)
assert_equal 3, items.size
end
def test_menu_items_for_should_skip_unallowed_items_on_a_project
menu_name = :test_menu_items_for_should_skip_unallowed_items_on_a_project
Redmine::MenuManager.map menu_name do |menu|
menu.push(:a_menu, {:controller => 'issues', :action => 'index' }, { })
menu.push(:a_menu_2, {:controller => 'issues', :action => 'index' }, { })
menu.push(:unallowed, {:controller => 'issues', :action => 'unallowed' }, { })
end
User.current = User.find(2)
items = menu_items_for(menu_name, Project.find(1))
assert_equal 2, items.size
end
def test_menu_items_for_should_skip_items_that_fail_the_conditions
menu_name = :test_menu_items_for_should_skip_items_that_fail_the_conditions
Redmine::MenuManager.map menu_name do |menu|
menu.push(:a_menu, {:controller => 'issues', :action => 'index' }, { })
menu.push(:unallowed,
{:controller => 'issues', :action => 'index' },
{ :if => Proc.new { false }})
end
User.current = User.find(2)
items = menu_items_for(menu_name, Project.find(1))
assert_equal 1, items.size
end
end
# Redmine - project management software
# Copyright (C) 2006-2009 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require File.dirname(__FILE__) + '/../../../../test_helper'
module RedmineMenuTestHelper
# Helpers
def get_menu_item(menu_name, item_name)
Redmine::MenuManager.items(menu_name).find {|item| item.name == item_name.to_sym}
end
end
class Redmine::MenuManager::MenuItemTest < Test::Unit::TestCase
include RedmineMenuTestHelper
Redmine::MenuManager.map :test_menu do |menu|
menu.push(:parent_menu, '/test', { })
menu.push(:child_menu, '/test', { :parent_menu => :parent_menu})
menu.push(:child2_menu, '/test', { :parent_menu => :parent_menu})
end
context "MenuItem#caption" do
should "be tested"
end
context "MenuItem#html_options" do
should "be tested"
end
# context new menu item
def test_new_menu_item_should_require_a_name
assert_raises ArgumentError do
Redmine::MenuManager::MenuItem.new
end
end
def test_new_menu_item_should_require_an_url
assert_raises ArgumentError do
Redmine::MenuManager::MenuItem.new(:test_missing_url)
end
end
def test_new_menu_item_should_require_the_options
assert_raises ArgumentError do
Redmine::MenuManager::MenuItem.new(:test_missing_options, '/test')
end
end
def test_new_menu_item_with_all_required_parameters
assert Redmine::MenuManager::MenuItem.new(:test_good_menu, '/test', {})
end
def test_new_menu_item_should_require_a_proc_to_use_for_the_if_condition
assert_raises ArgumentError do
Redmine::MenuManager::MenuItem.new(:test_error, '/test',
{
:if => ['not_a_proc']
})
end
assert Redmine::MenuManager::MenuItem.new(:test_good_if, '/test',
{
:if => Proc.new{}
})
end
def test_new_menu_item_should_allow_a_hash_for_extra_html_options
assert_raises ArgumentError do
Redmine::MenuManager::MenuItem.new(:test_error, '/test',
{
:html => ['not_a_hash']
})
end
assert Redmine::MenuManager::MenuItem.new(:test_good_html, '/test',
{
:html => { :onclick => 'doSomething'}
})
end
def test_new_should_not_allow_setting_the_parent_menu_item_to_the_current_item
assert_raises ArgumentError do
Redmine::MenuManager::MenuItem.new(:test_error, '/test', { :parent_menu => :test_error })
end
end
def test_has_children
parent_item = get_menu_item(:test_menu, :parent_menu)
assert parent_item.hasChildren?
assert_equal 2, parent_item.children.size
assert_equal get_menu_item(:test_menu, :child_menu), parent_item.children[0]
assert_equal get_menu_item(:test_menu, :child2_menu), parent_item.children[1]
end
end
# Redmine - project management software
# Copyright (C) 2006-2009 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require File.dirname(__FILE__) + '/../../../test_helper'
class Redmine::MenuManagerTest < Test::Unit::TestCase
context "MenuManager#map" do
should "be tested"
end
context "MenuManager#items" do
should "be tested"
end
end
# Redmine - project management software
# Copyright (C) 2006-2009 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require File.dirname(__FILE__) + '/../../test_helper'
module RedmineMenuTestHelper
# Assertions
def assert_number_of_items_in_menu(menu_name, count)
assert Redmine::MenuManager.items(menu_name).size >= count, "Menu has less than #{count} items"
end
def assert_menu_contains_item_named(menu_name, item_name)
assert Redmine::MenuManager.items(menu_name).collect(&:name).include?(item_name.to_sym), "Menu did not have an item named #{item_name}"
end
# Helpers
def get_menu_item(menu_name, item_name)
Redmine::MenuManager.items(menu_name).find {|item| item.name == item_name.to_sym}
end
end
class RedmineTest < Test::Unit::TestCase
include RedmineMenuTestHelper
def test_top_menu
assert_number_of_items_in_menu :top_menu, 5
assert_menu_contains_item_named :top_menu, :home
assert_menu_contains_item_named :top_menu, :my_page
assert_menu_contains_item_named :top_menu, :projects
assert_menu_contains_item_named :top_menu, :administration
assert_menu_contains_item_named :top_menu, :help
end
def test_account_menu
assert_number_of_items_in_menu :account_menu, 4
assert_menu_contains_item_named :account_menu, :login
assert_menu_contains_item_named :account_menu, :register
assert_menu_contains_item_named :account_menu, :my_account
assert_menu_contains_item_named :account_menu, :logout
end
def test_application_menu
assert_number_of_items_in_menu :application_menu, 0
end
def test_admin_menu
assert_number_of_items_in_menu :admin_menu, 0
end
def test_project_menu
assert_number_of_items_in_menu :project_menu, 12
assert_menu_contains_item_named :project_menu, :overview
assert_menu_contains_item_named :project_menu, :activity
assert_menu_contains_item_named :project_menu, :roadmap
assert_menu_contains_item_named :project_menu, :issues
assert_menu_contains_item_named :project_menu, :new_issue
assert_menu_contains_item_named :project_menu, :news
assert_menu_contains_item_named :project_menu, :documents
assert_menu_contains_item_named :project_menu, :wiki
assert_menu_contains_item_named :project_menu, :boards
assert_menu_contains_item_named :project_menu, :files
assert_menu_contains_item_named :project_menu, :repository
assert_menu_contains_item_named :project_menu, :settings
end
def test_new_issue_should_have_root_as_a_parent
new_issue = get_menu_item(:project_menu, :new_issue)
assert_equal :root, new_issue.parent.name
end
end
--- !ruby/object:Gem::Specification
name: rubytree
version: !ruby/object:Gem::Version
version: 0.5.2
platform: ruby
authors:
- Anupam Sengupta
autorequire: tree
bindir: bin
cert_chain: []
date: 2007-12-20 00:00:00 -08:00
default_executable:
dependencies:
- !ruby/object:Gem::Dependency
name: hoe
type: :runtime
version_requirement:
version_requirements: !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
version: 1.3.0
version:
description: "Provides a generic tree data-structure with ability to store keyed node-elements in the tree. The implementation mixes in the Enumerable module. Website: http://rubytree.rubyforge.org/"
email: anupamsg@gmail.com
executables: []
extensions: []
extra_rdoc_files:
- README
- COPYING
- ChangeLog
- History.txt
files:
- COPYING
- ChangeLog
- History.txt
- Manifest.txt
- README
- Rakefile
- TODO
- lib/tree.rb
- lib/tree/binarytree.rb
- setup.rb
- test/test_binarytree.rb
- test/test_tree.rb
has_rdoc: true
homepage: http://rubytree.rubyforge.org/
licenses: []
post_install_message:
rdoc_options:
- --main
- README
require_paths:
- lib
required_ruby_version: !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
version: "0"
version:
required_rubygems_version: !ruby/object:Gem::Requirement
requirements:
- - ">="
- !ruby/object:Gem::Version
version: "0"
version:
requirements: []
rubyforge_project: rubytree
rubygems_version: 1.3.5
signing_key:
specification_version: 2
summary: Ruby implementation of the Tree data structure.
test_files:
- test/test_binarytree.rb
- test/test_tree.rb
RUBYTREE - http://rubytree.rubyforge.org
========================================
Copyright (c) 2006, 2007 Anupam Sengupta
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
- Neither the name of the organization nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2007-12-21 Anupam Sengupta <anupamsg@gmail.com>
* Rakefile: Added the rcov option to exclude rcov itself from
coverage reports.
* lib/tree.rb: Minor comment changes.
* test/test_tree.rb: Added the TestTree enclosing module, and
renamed tests to meet ZenTest requirements. Also added a few
missing test cases.
* test/test_binarytree.rb: Added the TestTree enclosing Module,
and renamed the tests to meet ZenTest requirements.
2007-12-19 Anupam Sengupta <anupamsg@gmail.com>
* README (Module): Modified the install instructions from source.
* lib/tree.rb (Tree::TreeNode::initialize): Removed the
unnecessary self_initialize method.
(Tree::TreeNode): Removed the spurious self_initialize from the
protected list.
(Module): Updated the minor version number.
* Rakefile: Fixed a problem with reading the Tree::VERSION for the
gem packaging, if any prior version of the gem is already installed.
2007-12-18 Anupam Sengupta <anupamsg@gmail.com>
* lib/tree.rb: Updated the marshalling logic to correctly handle
non-string content.
(Tree::TreeNode::createDumpRep): Minor code change to use symbols
instead of string key names.
(Tree): Version number change to 0.5.0
(Tree::TreeNode::hasContent): Minor fix to the comments.
* test/test_tree.rb (TC_TreeTest::test_breadth_each): Updated test
cases for the marshalling logic.
2007-11-12 Anupam Sengupta <anupamsg@gmail.com>
* test/test_binarytree.rb: Minor documentation correction.
* lib/tree/binarytree.rb (Tree::BinaryTreeNode::isRightChild):
Minor documentation change.
2007-10-10 Anupam Sengupta <anupamsg@gmail.com>
* README: Restructured the format.
* Rakefile: Added Hoe related logic. If not present, the Rakefile
will default to old behavior.
2007-10-09 Anupam Sengupta <anupamsg@gmail.com>
* Rakefile: Added setup.rb related tasks. Also added the setup.rb in the PKG_FILES list.
2007-10-01 Anupam Sengupta <anupamsg@gmail.com>
* Rakefile: Added an optional task for rcov code coverage.
Added a dependency for rake in the Gem Specification.
* test/test_binarytree.rb: Removed the unnecessary dependency on "Person" class.
* test/test_tree.rb: Removed dependency on the redundant "Person" class.
(TC_TreeTest::test_comparator): Added a new test for the spaceship operator.
(TC_TreeTest::test_hasContent): Added tests for hasContent? and length methods.
2007-08-30 Anupam Sengupta <anupamsg@gmail.com>
* test/test_tree.rb (TC_TreeTest::test_preordered_each, TC_TreeTest::test_breadth_each, TC_TreeTest::test_detached_copy):
Added new tests for the new functions added to tree.rb.
* lib/tree.rb (Tree::TreeNode::detached_copy, Tree::TreeNode::preordered_each, Tree::TreeNode::breadth_each):
Added new functions for returning a detached copy of the node and
for performing breadth first traversal. Also added the pre-ordered
traversal function which is an alias of the existing 'each' method.
* test/test_binarytree.rb (TC_BinaryTreeTest::test_swap_children):
Added a test case for the children swap function.
* lib/tree/binarytree.rb (Tree::BinaryTreeNode::swap_children):
Added new function to swap the children. Other minor changes in
comments and code.
2007-07-18 Anupam Sengupta <anupamsg@gmail.com>
* lib/tree/binarytree.rb (Tree::BinaryTreeNode::leftChild /
rightChild): Minor cosmetic change on the parameter name.
* test/testbinarytree.rb (TC_BinaryTreeTest::test_isLeftChild):
Minor syntax correction.
* lib/tree.rb (Tree::TreeNode::depth): Added a tree depth
computation method.
(Tree::TreeNode::breadth): Added a tree breadth method.
* test/testtree.rb (TC_TreeTest::test_depth/test_breadth): Added a
test for the depth and breadth method.
* lib/tree/binarytree.rb (Tree::BinaryTreeNode::is*Child):
Added tests for determining whether a node is a left or right
child.
* test/testbinarytree.rb: Added the test cases for the binary tree
implementation.
(TC_BinaryTreeTest::test_is*Child): Added tests for right or left
childs.
* lib/tree/binarytree.rb: Added the binary tree implementation.
2007-07-17 Anupam Sengupta <anupamsg@gmail.com>
* lib/tree.rb (Tree::TreeNode::parentage): Renamed 'ancestors'
method to 'parentage' to avoid clobbering Module.ancestors
2007-07-16 Anupam Sengupta <anupamsg@gmail.com>
* Rakefile: Added an optional rtags task to generate TAGS file for
Emacs.
* lib/tree.rb (Tree::TreeNode): Added navigation methods for
siblings and children. Also added some convenience methods.
2007-07-08 Anupam Sengupta <anupamsg@gmail.com>
* Rakefile: Added a developer target for generating rdoc for the
website.
2007-06-24 Anupam Sengupta <anupamsg@gmail.com>
* test/testtree.rb, lib/tree.rb: Added the each_leaf traversal method.
* README: Replaced all occurrances of LICENSE with COPYING
and lowercased all instances of the word 'RubyTree'.
* Rakefile: Replaced all occurrances of LICENSE with COPYING
2007-06-23 Anupam Sengupta <anupamsg@gmail.com>
* lib/tree.rb (Tree::TreeNode::isLeaf): Added a isLeaf? method.
* test/testtree.rb (TC_TreeTest::test_removeFromParent): Added
test for isLeaf? method
* Rakefile: Added the LICENSE and ChangeLog to the extra RDoc files.
* lib/tree.rb: Minor updates to the comments.
* test/testtree.rb: Added the Copyright and License header.
* test/person.rb: Added the Copyright and License header.
* lib/tree.rb: Added the Copyright and License header.
* Rakefile: Added the LICENSE and Changelog to be part of the RDoc task.
* README: Added documentation in the README, including install
instructions and an example.
* LICENSE: Added the BSD LICENSE file.
* Changelog: Added the Changelog file.
= 0.5.2 / 2007-12-21
* Added more test cases and enabled ZenTest compatibility for the test case
names.
= 0.5.1 / 2007-12-20
* Minor code refactoring.
= 0.5.0 / 2007-12-18
* Fixed the marshalling code to correctly handle non-string content.
= 0.4.3 / 2007-10-09
* Changes to the build mechanism (now uses Hoe).
= 0.4.2 / 2007-10-01
* Minor code refactoring. Changes in the Rakefile.
COPYING
ChangeLog
History.txt
Manifest.txt
README
Rakefile
TODO
lib/tree.rb
lib/tree/binarytree.rb
setup.rb
test/test_binarytree.rb
test/test_tree.rb
__ _ _
/__\_ _| |__ _ _| |_ _ __ ___ ___
/ \// | | | '_ \| | | | __| '__/ _ \/ _ \
/ _ \ |_| | |_) | |_| | |_| | | __/ __/
\/ \_/\__,_|_.__/ \__, |\__|_| \___|\___|
|___/
(c) 2006, 2007 Anupam Sengupta
http://rubytree.rubyforge.org
Rubytree is a simple implementation of the generic Tree data structure. This
implementation is node-centric, where the individual nodes on the tree are the
primary objects and drive the structure.
== INSTALL:
Rubytree is an open source project and is hosted at:
http://rubytree.rubyforge.org
Rubytree can be downloaded as a Rubygem or as a tar/zip file from:
http://rubyforge.org/frs/?group_id=1215&release_id=8817
The file-name is one of:
rubytree-<VERSION>.gem - The Rubygem
rubytree-<VERSION>.tgz - GZipped source files
rubytree-<VERSION>.zip - Zipped source files
Download the appropriate file-type for your system.
It is recommended to install Rubytree as a Ruby Gem, as this is an easy way to
keep the version updated, and keep multiple versions of the library available on
your system.
=== Installing the Gem
To Install the Gem, from a Terminal/CLI command prompt, issue the command:
gem install rubytree
This should install the gem file for Rubytree. Note that you may need to be a
super-user (root) to successfully install the gem.
=== Installing from the tgz/zip file
Extract the archive file (tgz or zip) and run the following command from the
top-level source directory:
ruby ./setup.rb
You may need administrator/super-user privileges to complete the setup using
this method.
== DOCUMENTATION:
The primary class for this implementation is Tree::TreeNode. See the
class documentation for an usage example.
From a command line/terminal prompt, you can issue the following command to view
the text mode ri documentation:
ri Tree::TreeNode
Documentation on the web is available at:
http://rubytree.rubyforge.org/rdoc
== EXAMPLE:
The following code-snippet implements this tree structure:
+------------+
| ROOT |
+-----+------+
+-------------+------------+
| |
+-------+-------+ +-------+-------+
| CHILD 1 | | CHILD 2 |
+-------+-------+ +---------------+
|
|
+-------+-------+
| GRANDCHILD 1 |
+---------------+
require 'tree'
myTreeRoot = Tree::TreeNode.new("ROOT", "Root Content")
myTreeRoot << Tree::TreeNode.new("CHILD1", "Child1 Content") << Tree::TreeNode.new("GRANDCHILD1", "GrandChild1 Content")
myTreeRoot << Tree::TreeNode.new("CHILD2", "Child2 Content")
myTreeRoot.printTree
child1 = myTreeRoot["CHILD1"]
grandChild1 = myTreeRoot["CHILD1"]["GRANDCHILD1"]
siblingsOfChild1Array = child1.siblings
immediateChildrenArray = myTreeRoot.children
# Process all nodes
myTreeRoot.each { |node| node.content.reverse }
myTreeRoot.remove!(child1) # Remove the child
== LICENSE:
Rubytree is licensed under BSD license.
Copyright (c) 2006, 2007 Anupam Sengupta
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
- Neither the name of the organization nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(Document Revision: $Revision: 1.16 $ by $Author: anupamsg $)
# Rakefile
#
# $Revision: 1.27 $ by $Author: anupamsg $
# $Name: $
#
# Copyright (c) 2006, 2007 Anupam Sengupta
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# - Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# - Redistributions in binary form must reproduce the above copyright notice, this
# list of conditions and the following disclaimer in the documentation and/or
# other materials provided with the distribution.
#
# - Neither the name of the organization nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
require 'rubygems'
require 'rake/gempackagetask'
require 'rake/clean'
require 'rake/packagetask'
require 'rake/testtask'
require 'rake/rdoctask'
require 'fileutils'
# General Stuff ####################################################
$:.insert 0, File.expand_path( File.join( File.dirname(__FILE__), 'lib' ) )
require 'tree' # To read the version information.
PKG_NAME = "rubytree"
PKG_VERSION = Tree::VERSION
PKG_FULLNAME = PKG_NAME + "-" + PKG_VERSION
PKG_SUMMARY = "Ruby implementation of the Tree data structure."
PKG_DESCRIPTION = <<-END
Provides a generic tree data-structure with ability to
store keyed node-elements in the tree. The implementation
mixes in the Enumerable module.
Website: http://rubytree.rubyforge.org/
END
PKG_FILES = FileList[
'[A-Z]*',
'*.rb',
'lib/**/*.rb',
'test/**/*.rb'
]
# Default is to create a rubygem.
desc "Default Task"
task :default => :gem
begin # Try loading hoe
require 'hoe'
# If Hoe is found, use it to define tasks
# =======================================
Hoe.new(PKG_NAME, PKG_VERSION) do |p|
p.rubyforge_name = PKG_NAME
p.author = "Anupam Sengupta"
p.email = "anupamsg@gmail.com"
p.summary = PKG_SUMMARY
p.description = PKG_DESCRIPTION
p.url = "http://rubytree.rubyforge.org/"
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
p.remote_rdoc_dir = 'rdoc'
p.need_tar = true
p.need_zip = true
p.test_globs = ['test/test_*.rb']
p.spec_extras = {
:has_rdoc => true,
:platform => Gem::Platform::RUBY,
:has_rdoc => true,
:extra_rdoc_files => ['README', 'COPYING', 'ChangeLog', 'History.txt'],
:rdoc_options => ['--main', 'README'],
:autorequire => 'tree'
}
end
rescue LoadError # If Hoe is not found
# If Hoe is not found, then use the usual Gemspec based Rake tasks
# ================================================================
spec = Gem::Specification.new do |s|
s.name = PKG_NAME
s.version = PKG_VERSION
s.platform = Gem::Platform::RUBY
s.author = "Anupam Sengupta"
s.email = "anupamsg@gmail.com"
s.homepage = "http://rubytree.rubyforge.org/"
s.rubyforge_project = 'rubytree'
s.summary = PKG_SUMMARY
s.add_dependency('rake', '>= 0.7.2')
s.description = PKG_DESCRIPTION
s.has_rdoc = true
s.extra_rdoc_files = ['README', 'COPYING', 'ChangeLog']
s.autorequire = "tree"
s.files = PKG_FILES.to_a
s.test_files = Dir.glob('test/test*.rb')
end
desc "Prepares for installation"
task :prepare do
ruby "setup.rb config"
ruby "setup.rb setup"
end
desc "Installs the package #{PKG_NAME}"
task :install => [:prepare] do
ruby "setup.rb install"
end
Rake::GemPackageTask.new(spec) do |pkg|
pkg.need_zip = true
pkg.need_tar = true
end
Rake::TestTask.new do |t|
t.libs << "test"
t.test_files = FileList['test/test*.rb']
t.verbose = true
end
end # End loading Hoerc
# ================================================================
# The following tasks are loaded independently of Hoe
# Hoe's rdoc task is ugly.
Rake::RDocTask.new(:docs) do |rd|
rd.rdoc_files.include("README", "COPYING", "ChangeLog", "lib/**/*.rb")
rd.rdoc_dir = 'doc'
rd.title = "#{PKG_FULLNAME} Documentation"
# Use the template only if it is present, otherwise, the standard template is
# used.
template = "../allison/allison.rb"
rd.template = template if File.file?(template)
rd.options << '--line-numbers' << '--inline-source'
end
# Optional TAGS Task.
# Needs https://rubyforge.org/projects/rtagstask/
begin
require 'rtagstask'
RTagsTask.new do |rd|
rd.vi = false
end
rescue LoadError
end
# Optional RCOV Task
# Needs http://eigenclass.org/hiki/rcov
begin
require 'rcov/rcovtask'
Rcov::RcovTask.new do |t|
t.test_files = FileList['test/test*.rb']
t.rcov_opts << "--exclude 'rcov.rb'" # rcov itself should not be profiled
# t.verbose = true # uncomment to see the executed commands
end
rescue LoadError
end
#Rakefile,v $
# Revision 1.21 2007/07/21 05:14:43 anupamsg
# Added a VERSION constant to the Tree module,
# and using the same in the Rakefile.
#
# Revision 1.20 2007/07/21 03:24:25 anupamsg
# Minor edits to parameter names. User visible functionality does not change.
#
# Revision 1.19 2007/07/19 02:16:01 anupamsg
# Release 0.4.0 (and minor fix in Rakefile).
#
# Revision 1.18 2007/07/18 20:15:06 anupamsg
# Added two predicate methods in BinaryTreeNode to determine whether a node
# is a left or a right node.
#
# Revision 1.17 2007/07/18 07:17:34 anupamsg
# Fixed a issue where TreeNode.ancestors was shadowing Module.ancestors. This method
# has been renamed to TreeNode.parentage.
#
# Revision 1.16 2007/07/17 05:34:03 anupamsg
# Added an optional tags Rake-task for generating the TAGS file for Emacs.
#
# Revision 1.15 2007/07/17 04:42:45 anupamsg
# Minor fixes to the Rakefile.
#
# Revision 1.14 2007/07/17 03:39:28 anupamsg
# Moved the CVS Log keyword to end of the files.
#
# -*- mode: outline; coding: utf-8-unix; -*-
* Add logic in Rakefile to read the file list from Manifest.txt file.
* Add a YAML export method to the TreeNode class.
This diff is collapsed.
# binarytree.rb
#
# $Revision: 1.5 $ by $Author: anupamsg $
# $Name: $
#
# = binarytree.rb - Binary Tree implementation
#
# Provides a generic tree data structure with ability to
# store keyed node elements in the tree. The implementation
# mixes in the Enumerable module.
#
# Author:: Anupam Sengupta (anupamsg@gmail.com)
#
# Copyright (c) 2007 Anupam Sengupta
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# - Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# - Redistributions in binary form must reproduce the above copyright notice, this
# list of conditions and the following disclaimer in the documentation and/or
# other materials provided with the distribution.
#
# - Neither the name of the organization nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
require 'tree'
module Tree
# Provides a Binary tree implementation. This tree node allows only two child
# nodes (left and right childs). It also provides direct access to the left
# and right children, including assignment to the same.
class BinaryTreeNode < TreeNode
# Adds the specified child node to the receiver node. The child node's
# parent is set to be the receiver. The child nodes are added in the order
# of addition, i.e., the first child added becomes the left node, and the
# second child will be the second node.
# If only one child is present, then this will be the left child.
def add(child)
raise "Already has two child nodes" if @children.size == 2
super(child)
end
# Returns the left child node. Note that
# left Child == first Child
def leftChild
children.first
end
# Returns the right child node. Note that
# right child == last child unless there is only one child.
# Returns nil if the right child does not exist.
def rightChild
children[1]
end
# Sets the left child. If a previous child existed, it is replaced.
def leftChild=(child)
@children[0] = child
@childrenHash[child.name] = child if child # Assign the name mapping
end
# Sets the right child. If a previous child existed, it is replaced.
def rightChild=(child)
@children[1] = child
@childrenHash[child.name] = child if child # Assign the name mapping
end
# Returns true if this is the left child of its parent. Always returns false
# if this is the root node.
def isLeftChild?
return nil if isRoot?
self == parent.leftChild
end
# Returns true if this is the right child of its parent. Always returns false
# if this is the root node.
def isRightChild?
return nil if isRoot?
self == parent.rightChild
end
# Swaps the left and right children with each other
def swap_children
tempChild = leftChild
self.leftChild= rightChild
self.rightChild= tempChild
end
end
end
# $Log: binarytree.rb,v $
# Revision 1.5 2007/12/18 23:11:29 anupamsg
# Minor documentation changes in the binarytree class.
#
# Revision 1.4 2007/08/30 22:08:58 anupamsg
# Added a new swap_children method for Binary Tree. Also added minor
# documentation and test updates.
#
# Revision 1.3 2007/07/21 03:24:25 anupamsg
# Minor edits to parameter names. User visible functionality does not change.
#
# Revision 1.2 2007/07/18 20:15:06 anupamsg
# Added two predicate methods in BinaryTreeNode to determine whether a node
# is a left or a right node.
#
# Revision 1.1 2007/07/18 19:33:27 anupamsg
# Added a new binary tree implementation.
#
This diff is collapsed.
#!/usr/bin/env ruby
# test_binarytree.rb
#
# $Revision: 1.5 $ by $Author: anupamsg $
# $Name: $
#
# Copyright (c) 2006, 2007 Anupam Sengupta
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# - Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# - Redistributions in binary form must reproduce the above copyright notice, this
# list of conditions and the following disclaimer in the documentation and/or
# other materials provided with the distribution.
#
# - Neither the name of the organization nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
require 'test/unit'
require 'tree/binarytree'
module TestTree
# Test class for the Tree node.
class TestBinaryTreeNode < Test::Unit::TestCase
def setup
@root = Tree::BinaryTreeNode.new("ROOT", "Root Node")
@left_child1 = Tree::BinaryTreeNode.new("A Child at Left", "Child Node @ left")
@right_child1 = Tree::BinaryTreeNode.new("B Child at Right", "Child Node @ right")
end
def teardown
@root.remove!(@left_child1)
@root.remove!(@right_child1)
@root = nil
end
def test_initialize
assert_not_nil(@root, "Binary tree's Root should have been created")
end
def test_add
@root.add @left_child1
assert_same(@left_child1, @root.leftChild, "The left node should be left_child1")
assert_same(@left_child1, @root.firstChild, "The first node should be left_child1")
@root.add @right_child1
assert_same(@right_child1, @root.rightChild, "The right node should be right_child1")
assert_same(@right_child1, @root.lastChild, "The first node should be right_child1")
assert_raise RuntimeError do
@root.add Tree::BinaryTreeNode.new("The third child!")
end
assert_raise RuntimeError do
@root << Tree::BinaryTreeNode.new("The third child!")
end
end
def test_leftChild
@root << @left_child1
@root << @right_child1
assert_same(@left_child1, @root.leftChild, "The left child should be 'left_child1")
assert_not_same(@right_child1, @root.leftChild, "The right_child1 is not the left child")
end
def test_rightChild
@root << @left_child1
@root << @right_child1
assert_same(@right_child1, @root.rightChild, "The right child should be 'right_child1")
assert_not_same(@left_child1, @root.rightChild, "The left_child1 is not the left child")
end
def test_leftChild_equals
@root << @left_child1
@root << @right_child1
assert_same(@left_child1, @root.leftChild, "The left child should be 'left_child1")
@root.leftChild = Tree::BinaryTreeNode.new("New Left Child")
assert_equal("New Left Child", @root.leftChild.name, "The left child should now be the new child")
assert_equal("B Child at Right", @root.lastChild.name, "The last child should now be the right child")
# Now set the left child as nil, and retest
@root.leftChild = nil
assert_nil(@root.leftChild, "The left child should now be nil")
assert_nil(@root.firstChild, "The first child is now nil")
assert_equal("B Child at Right", @root.lastChild.name, "The last child should now be the right child")
end
def test_rightChild_equals
@root << @left_child1
@root << @right_child1
assert_same(@right_child1, @root.rightChild, "The right child should be 'right_child1")
@root.rightChild = Tree::BinaryTreeNode.new("New Right Child")
assert_equal("New Right Child", @root.rightChild.name, "The right child should now be the new child")
assert_equal("A Child at Left", @root.firstChild.name, "The first child should now be the left child")
assert_equal("New Right Child", @root.lastChild.name, "The last child should now be the right child")
# Now set the right child as nil, and retest
@root.rightChild = nil
assert_nil(@root.rightChild, "The right child should now be nil")
assert_equal("A Child at Left", @root.firstChild.name, "The first child should now be the left child")
assert_nil(@root.lastChild, "The first child is now nil")
end
def test_isLeftChild_eh
@root << @left_child1
@root << @right_child1
assert(@left_child1.isLeftChild?, "left_child1 should be the left child")
assert(!@right_child1.isLeftChild?, "left_child1 should be the left child")
# Now set the right child as nil, and retest
@root.rightChild = nil
assert(@left_child1.isLeftChild?, "left_child1 should be the left child")
assert(!@root.isLeftChild?, "Root is neither left child nor right")
end
def test_isRightChild_eh
@root << @left_child1
@root << @right_child1
assert(@right_child1.isRightChild?, "right_child1 should be the right child")
assert(!@left_child1.isRightChild?, "right_child1 should be the right child")
# Now set the left child as nil, and retest
@root.leftChild = nil
assert(@right_child1.isRightChild?, "right_child1 should be the right child")
assert(!@root.isRightChild?, "Root is neither left child nor right")
end
def test_swap_children
@root << @left_child1
@root << @right_child1
assert(@right_child1.isRightChild?, "right_child1 should be the right child")
assert(!@left_child1.isRightChild?, "right_child1 should be the right child")
@root.swap_children
assert(@right_child1.isLeftChild?, "right_child1 should now be the left child")
assert(@left_child1.isRightChild?, "left_child1 should now be the right child")
assert_equal(@right_child1, @root.firstChild, "right_child1 should now be the first child")
assert_equal(@left_child1, @root.lastChild, "left_child1 should now be the last child")
assert_equal(@right_child1, @root[0], "right_child1 should now be the first child")
assert_equal(@left_child1, @root[1], "left_child1 should now be the last child")
end
end
end
# $Log: test_binarytree.rb,v $
# Revision 1.5 2007/12/22 00:28:59 anupamsg
# Added more test cases, and enabled ZenTest compatibility.
#
# Revision 1.4 2007/12/18 23:11:29 anupamsg
# Minor documentation changes in the binarytree class.
#
# Revision 1.3 2007/10/02 03:07:30 anupamsg
# * Rakefile: Added an optional task for rcov code coverage.
#
# * test/test_binarytree.rb: Removed the unnecessary dependency on "Person" class.
#
# * test/test_tree.rb: Removed dependency on the redundant "Person" class.
#
# Revision 1.2 2007/08/30 22:06:13 anupamsg
# Added a new swap_children method for the Binary Tree class.
# Also made minor documentation updates and test additions.
#
# Revision 1.1 2007/07/21 04:52:37 anupamsg
# Renamed the test files.
#
# Revision 1.4 2007/07/19 02:03:57 anupamsg
# Minor syntax correction.
#
# Revision 1.3 2007/07/19 02:02:12 anupamsg
# Removed useless files (including rdoc, which should be generated for each release.
#
# Revision 1.2 2007/07/18 20:15:06 anupamsg
# Added two predicate methods in BinaryTreeNode to determine whether a node
# is a left or a right node.
#
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment