Skip to content
Browse files

Created Mongoid::Tree::Traversal::ClassMethods.traverse .

  • Loading branch information...
1 parent 2a23820 commit 2c4b3b93e31ada259feda7ffbd18b241a1f07bc9 @nickhoffman nickhoffman committed
Showing with 100 additions and 0 deletions.
  1. +44 −0 lib/mongoid/tree/traversal.rb
  2. +56 −0 spec/mongoid/tree/traversal_spec.rb
View
44 lib/mongoid/tree/traversal.rb
@@ -48,6 +48,13 @@ module Tree
module Traversal
##
+ # Extend ClassMethods into the class that's including Traversal.
+ #
+ def self.included(base)
+ base.extend ClassMethods
+ end
+
+ ##
# Traverses the tree using the given traversal method (Default is :depth_first)
# and passes each document node to the block.
#
@@ -80,6 +87,43 @@ def breadth_first_traversal(&block)
end
end
+ ##
+ # The methods in this module are class-level methods.
+ # They're extended into the base class automatically.
+ #
+ module ClassMethods
+
+ ##
+ # Traverses the entire tree, one root at a time, using the given traversal
+ # method (Default is :depth_first).
+ #
+ # See Mongoid::Tree::Traversal for available traversal methods.
+ #
+ # Example:
+ #
+ # # Say we have the following tree, and want to print its hierarchy:
+ # # root_1
+ # # child_1_a
+ # # root_2
+ # # child_2_a
+ # # child_2_a_1
+ #
+ # Node.traverse(:depth_first) do |node|
+ # indentation = ' ' * node.depth
+ #
+ # puts "#{indentation}#{node.name}"
+ # end
+ #
+ def traverse(type = :depth_first, &block)
+ raise ArgumentError, "No block given" unless block_given?
+
+ roots.each do |root|
+ root.traverse type, &block
+ end
+
+ nil
+ end
+ end
end
end
end
View
56 spec/mongoid/tree/traversal_spec.rb
@@ -116,4 +116,60 @@
end
+ describe '.traverse' do
+
+ describe 'when not given a block' do
+
+ it 'raises an error' do
+ expect {Node.traverse}.to raise_error ArgumentError, 'No block given'
+ end
+ end
+
+ before :each do
+ setup_tree <<-ENDTREE
+ - root1
+ - root2
+ ENDTREE
+
+ @block = Proc.new {}
+ @root1 = node(:root1)
+ @root2 = node(:root2)
+
+ Node.stub(:roots).and_return [@root1, @root2]
+ end
+
+ it 'grabs each root' do
+ Node.should_receive(:roots).and_return []
+
+ Node.traverse &@block
+ end
+
+ it 'defaults the "type" arg to :depth_first' do
+ @root1.should_receive(:traverse).with(:depth_first)
+ @root2.should_receive(:traverse).with(:depth_first)
+
+ Node.traverse &@block
+ end
+
+ it 'traverses each root' do
+ @root1.should_receive(:traverse)
+ @root2.should_receive(:traverse)
+
+ Node.traverse &@block
+ end
+
+ describe 'when the "type" arg is :breadth_first' do
+
+ it 'traverses breadth-first' do
+ @root1.should_receive(:traverse).with(:breadth_first)
+ @root2.should_receive(:traverse).with(:breadth_first)
+
+ Node.traverse :breadth_first, &@block
+ end
+ end
+
+ it 'returns nil' do
+ Node.traverse(&@block).should be nil
+ end
+ end
end

0 comments on commit 2c4b3b9

Please sign in to comment.
Something went wrong with that request. Please try again.