$:.unshift File.join(File.dirname(__FILE__),"..","lib") require 'minitest/autorun' require 'rgen/metamodel_builder' require 'rgen/instantiator/reference_resolver' class ReferenceResolverTest < MiniTest::Test class TestNode < RGen::MetamodelBuilder::MMBase has_attr 'name', String has_one 'other', TestNode has_many 'others', TestNode end class TestNode2 < RGen::MetamodelBuilder::MMBase has_attr 'name', String end def test_identifier_resolver nodeA, nodeB, nodeC, unresolved_refs = create_model resolver = RGen::Instantiator::ReferenceResolver.new( :identifier_resolver => proc do |ident| {:a => nodeA, :b => nodeB, :c => nodeC}[ident] end) urefs = resolver.resolve(unresolved_refs) check_model(nodeA, nodeB, nodeC) assert urefs.empty? end def test_add_identifier nodeA, nodeB, nodeC, unresolved_refs = create_model resolver = RGen::Instantiator::ReferenceResolver.new resolver.add_identifier(:a, nodeA) resolver.add_identifier(:b, nodeB) resolver.add_identifier(:c, nodeC) urefs = resolver.resolve(unresolved_refs) check_model(nodeA, nodeB, nodeC) assert urefs.empty? end def test_problems nodeA, nodeB, nodeC, unresolved_refs = create_model resolver = RGen::Instantiator::ReferenceResolver.new( :identifier_resolver => proc do |ident| {:a => [nodeA, nodeB], :c => nodeC}[ident] end) problems = [] urefs = resolver.resolve(unresolved_refs, :problems => problems) assert_equal ["identifier b not found", "identifier a not uniq"], problems assert_equal 2, urefs.size assert urefs.all?{|ur| !ur.target_type_error} end def test_on_resolve_proc nodeA, nodeB, nodeC, unresolved_refs = create_model resolver = RGen::Instantiator::ReferenceResolver.new resolver.add_identifier(:a, nodeA) resolver.add_identifier(:b, nodeB) resolver.add_identifier(:c, nodeC) data = [] resolver.resolve(unresolved_refs, :on_resolve => proc {|ur, e| data << [ ur, e ]}) assert data[0][0].is_a?(RGen::Instantiator::ReferenceResolver::UnresolvedReference) assert_equal nodeA, data[0][0].element assert_equal "other", data[0][0].feature_name assert_equal :b, data[0][0].proxy.targetIdentifier assert_equal nodeB, data[0][1] end def test_target_type_error nodeA, nodeB, nodeC, unresolved_refs = create_model resolver = RGen::Instantiator::ReferenceResolver.new( :identifier_resolver => proc do |ident| {:a => TestNode2.new, :b => TestNode2.new, :c => nodeC}[ident] end) problems = [] urefs = resolver.resolve(unresolved_refs, :problems => problems) assert_equal 2, problems.size assert problems[0] =~ /invalid target type .*TestNode2/ assert problems[1] =~ /invalid target type .*TestNode2/ assert_equal 2, urefs.uniq.size assert urefs[0].target_type_error assert urefs[1].target_type_error assert urefs.any?{|ur| ur.proxy.object_id == nodeA.other.object_id} assert urefs.any?{|ur| ur.proxy.object_id == nodeB.others[0].object_id} end private def create_model nodeA = TestNode.new(:name => "NodeA") nodeB = TestNode.new(:name => "NodeB") nodeC = TestNode.new(:name => "NodeC") bProxy = RGen::MetamodelBuilder::MMProxy.new(:b) nodeA.other = bProxy aProxy = RGen::MetamodelBuilder::MMProxy.new(:a) cProxy = RGen::MetamodelBuilder::MMProxy.new(:c) nodeB.others = [aProxy, cProxy] unresolved_refs = [ RGen::Instantiator::ReferenceResolver::UnresolvedReference.new(nodeA, "other", bProxy), RGen::Instantiator::ReferenceResolver::UnresolvedReference.new(nodeB, "others", aProxy), RGen::Instantiator::ReferenceResolver::UnresolvedReference.new(nodeB, "others", cProxy) ] return nodeA, nodeB, nodeC, unresolved_refs end def check_model(nodeA, nodeB, nodeC) assert_equal nodeB, nodeA.other assert_equal [], nodeA.others assert_nil nodeB.other assert_equal [nodeA, nodeC], nodeB.others assert_nil nodeC.other assert_equal [], nodeC.others end end