require 'test/unit' require 'util/enter_leave_visitor' class TestEnterLeaveVisitor < Test::Unit::TestCase class Mock end class SuperMock include EnterLeaveVisitable end class ELMock < SuperMock end class SuperTELVisitor include EnterLeaveVisitor attr_reader :calls def initialize; @calls = []; end def enter_SuperMock(obj); @calls << :enterSuperM; end def visit_SuperMock(obj); @calls << :visitSuperM; end def leave_SuperMock(obj); @calls << :leaveSuperM; end end class TELVisitor < SuperTELVisitor def enter_Mock(obj); @calls << :enterM; end def visit_Mock(obj); @calls << :visitM; end def leave_Mock(obj); @calls << :leaveM; end def enter_ELMock(obj); @calls << :enterELM; end def visit_ELMock(obj); @calls << :visitELM; end def leave_ELMock(obj); @calls << :leaveELM; end def enter_SMock(obj); @calls << :enterSM; end def visit_SMock(obj); @calls << :visitSM; end def leave_SMock(obj); @calls << :leaveSM; end end class SMock def initialize(c1, c2) @c1, @c2 = c1, c2 end def accept_visitor(v) v.visit_me_then_children self, [@c1, @c2] end end class EmptyVisitor include EnterLeaveVisitor end def test_01_empty_visitor visitor, m = EmptyVisitor.new, ELMock.new assert_nothing_raised {m.accept_visitor(visitor)} end def test_02_visit_std_visitable visitor, m = TELVisitor.new, Mock.new visitor.visit m assert_equal([:enterM, :visitM, :leaveM], visitor.calls) end def test_03_visit_enterleavevisitable visitor, m = TELVisitor.new, ELMock.new visitor.visit m assert_equal([:enterELM, :visitELM, :leaveELM], visitor.calls) end def test_04_visit_nested_objects visitor, sm = TELVisitor.new, SMock.new(c1 = ELMock.new, c2 = ELMock.new) sm.accept_visitor(visitor) assert_equal([:enterSM, :visitSM, :enterELM, :visitELM, :leaveELM, :enterELM, :visitELM, :leaveELM, :leaveSM], visitor.calls) end def test_05_visit_superclass_visit_method visitor, m1 = SuperTELVisitor.new, ELMock.new m1.accept_visitor(visitor) assert_equal([:enterSuperM, :visitSuperM, :leaveSuperM], visitor.calls) end def test_06_visit_our_visitmethod_if_available_both_for_us_and_for_superclass visitor, m1 = TELVisitor.new, ELMock.new m1.accept_visitor(visitor) assert_equal([:enterELM, :visitELM, :leaveELM], visitor.calls) end end