require 'test/unit' require 'util/visitor_combinators' require 'util/visitor' class UTestVisitorCombinators < Test::Unit::TestCase class Tree attr_reader :children, :visitors def initialize(*children) @children, @visitors = children, [] end def accept_visitor(visitor) @visitors << visitor.object_id visitor.visit_me_and_my_children(self, @children) end end # Doesn't touch the visited nodes, just saves the fact that they have been # visited class TIdentityVisitor include Visitor attr_reader :visited def initialize @visited = [] end def visit_Tree(tree) @visited << tree end end def setup @l1, @l2, @l3 = Tree.new, Tree.new, Tree.new @i = Tree.new(@l2, @l3) @r = Tree.new(@l1, @i) @nodes = [@r, @l1, @i, @l2, @l3] end def assert_topdown_leftright_visited(visitor) assert_equal(@r, visitor.visited[0]) assert_equal(@l1, visitor.visited[1]) assert_equal(@i, visitor.visited[2]) assert_equal(@l2, visitor.visited[3]) assert_equal(@l3, visitor.visited[4]) end def test_01_identity_visitor @r.accept_visitor(iv = TIdentityVisitor.new) assert_equal(5, iv.visited.length) assert_topdown_leftright_visited(iv) end def test_02_sequence_visitor sv = SequenceVisitor.new(iv1 = TIdentityVisitor.new, iv2 = TIdentityVisitor.new) @r.accept_visitor(sv) assert_topdown_leftright_visited(iv1) assert_topdown_leftright_visited(iv2) # Seems leaf nodes are visited many times by iv1 and iv2 so the assert # does not hold. # @nodes.each do |n| # assert_equal([sv.id, iv1.id, iv2.id], n.visitors) # end end end