$:.unshift(File.dirname(__FILE__)+"/../../lib") require 'minitest/autorun' require 'rgen/environment' require 'rgen/metamodel_builder' require 'rgen/model_builder' require 'rgen/util/pattern_matcher' class PatternMatcherTest < MiniTest::Test module TestMM extend RGen::MetamodelBuilder::ModuleExtension class Node < RGen::MetamodelBuilder::MMBase has_attr 'name', String contains_many 'children', Node, 'parent' end end def modelA env = RGen::Environment.new RGen::ModelBuilder.build(TestMM, env) do node "A" do node "AA" end node "B" do node "B1" node "B2" node "B3" end node "C" do node "C1" node "C2" end node "D" do node "DD" end end env end def test_simple matcher = RGen::Util::PatternMatcher.new matcher.add_pattern("simple") do |env, c| TestMM::Node.new(:name => "A", :children => [ TestMM::Node.new(:name => "AA")]) end matcher.add_pattern("bad") do |env, c| TestMM::Node.new(:name => "X") end env = modelA match = matcher.find_pattern(env, "simple") assert match != nil assert_equal "A", match.root.name assert_equal env.find(:class => TestMM::Node, :name => "A").first.object_id, match.root.object_id assert_equal 2, match.elements.size assert_equal [nil], match.bound_values assert_nil matcher.find_pattern(env, "bad") end def test_value_binding matcher = RGen::Util::PatternMatcher.new matcher.add_pattern("single_child") do |env, name, child| TestMM::Node.new(:name => name, :children => [ child ]) end matcher.add_pattern("double_child") do |env, name, child1, child2| TestMM::Node.new(:name => name, :children => [ child1, child2 ]) end matcher.add_pattern("child_pattern") do |env, child_name| TestMM::Node.new(:name => "A", :children => [ TestMM::Node.new(:name => child_name)]) end env = modelA match = matcher.find_pattern(env, "single_child") assert match != nil assert_equal "A", match.root.name assert_equal "AA", match.bound_values[1].name match = matcher.find_pattern(env, "single_child", "D") assert match != nil assert_equal "D", match.root.name assert_equal "DD", match.bound_values[0].name match = matcher.find_pattern(env, "double_child") assert match != nil assert_equal "C", match.root.name match = matcher.find_pattern(env, "child_pattern") assert match != nil assert_equal ["AA"], match.bound_values end end