require 'test/unit' require 'util/visitor' class TestVisitor < Test::Unit::TestCase class SuperMock include Visitable end class Mock < SuperMock attr_reader :children, :visited def initialize @children = [] end def accept_visitor(visitor) @visited = true visitor.visit_me_then_children self, @children end end class TVisitor include Visitor attr_reader :count def initialize; @count = 0; end def visit_Mock(obj); @count += 1; end end class EmptyVisitor include Visitor end # To test whether super class visit method is used if there is no one # for the actual class class SuperMockVisitor include Visitor attr_reader :count def initialize; @count = 0; end def visit_SuperMock(obj); @count += 1; end end class MockAndSuperMockVisitor include Visitor attr_reader :countSM, :countM def initialize; @countM = @countSM = 0; end def visit_SuperMock(obj); @countSM += 1; end def visit_Mock(obj); @countM += 1; end end def test_01_empty_visitor visitor, m = EmptyVisitor.new, Mock.new assert_nothing_raised {m.accept_visitor(visitor)} assert(m.visited) end def test_02_visit visitor, m = TVisitor.new, Mock.new assert_equal(0, visitor.count) visitor.visit(m) assert_equal(1, visitor.count) m.accept_visitor(visitor) assert_equal(2, visitor.count) end def test_03_visit_nested visitor, m1 = TVisitor.new, Mock.new m1.children << (m2 = Mock.new) m2.children << (m3 = Mock.new) m1.accept_visitor(visitor) assert_equal(3, visitor.count) assert(m1.visited) assert(m2.visited) assert(m3.visited) end def test_04_visit_superclass_visit_method visitor, m1 = SuperMockVisitor.new, Mock.new m1.accept_visitor(visitor) assert_equal(1, visitor.count) end def test_05_visit_our_visitmethod_if_available_both_for_us_and_for_superclass visitor, m1 = MockAndSuperMockVisitor.new, Mock.new m1.accept_visitor(visitor) assert_equal(1, visitor.countM) assert_equal(0, visitor.countSM) end def test_06_visit_each visitor, a = TVisitor.new, [Mock.new, Mock.new] visitor.visit_each(a) assert_equal(2, visitor.count) end end