rgen 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,7 +7,9 @@ module Serializer
7
7
  class XMI20Serializer < XMLSerializer
8
8
 
9
9
  def serialize(rootElement)
10
+ @referenceStrings = {}
10
11
  buildReferenceStrings(rootElement, "#/")
12
+ addBuiltinReferenceStrings
11
13
  attrs = attributeHash(rootElement)
12
14
  attrs['xmi:version'] = "2.0"
13
15
  attrs['xmlns:xmi'] = "http://www.omg.org/XMI"
@@ -36,7 +38,7 @@ class XMI20Serializer < XMLSerializer
36
38
  val = element.getGeneric(a.name)
37
39
  result[a.name] = val unless val.nil? || val == ""
38
40
  end
39
- eAllReferences(element).select{|r| !r.containment && !r.derived}.each do |r|
41
+ eAllReferences(element).select{|r| !r.containment && !(r.eOpposite && r.eOpposite.containment) && !r.derived}.each do |r|
40
42
  targetElements = element.getGeneric(r.name)
41
43
  targetElements = [targetElements] unless targetElements.is_a?(Array)
42
44
  val = targetElements.collect{|te| @referenceStrings[te]}.compact.join(' ')
@@ -46,15 +48,24 @@ class XMI20Serializer < XMLSerializer
46
48
  end
47
49
 
48
50
  def buildReferenceStrings(element, string)
49
- @referenceStrings ||= {}
50
51
  @referenceStrings[element] = string
51
52
  eachReferencedElement(element, containmentReferences(element)) do |r,te|
52
53
  buildReferenceStrings(te, string+"/"+te.name) if te.respond_to?(:name)
53
54
  end
54
55
  end
55
56
 
57
+ def addBuiltinReferenceStrings
58
+ pre = "ecore:EDataType http://www.eclipse.org/emf/2002/Ecore"
59
+ @referenceStrings[RGen::ECore::EString] = pre+"#//EString"
60
+ @referenceStrings[RGen::ECore::EInt] = pre+"#//EInt"
61
+ @referenceStrings[RGen::ECore::EFloat] = pre+"#//EFloat"
62
+ @referenceStrings[RGen::ECore::EBoolean] = pre+"#//EBoolean"
63
+ @referenceStrings[RGen::ECore::EJavaObject] = pre+"#//EJavaObject"
64
+ @referenceStrings[RGen::ECore::EJavaClass] = pre+"#//EJavaClass"
65
+ end
66
+
56
67
  end
57
68
 
58
69
  end
59
70
 
60
- end
71
+ end
@@ -0,0 +1,91 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),"..","lib")
2
+
3
+ require 'test/unit'
4
+ require 'rgen/environment'
5
+ require 'rgen/metamodel_builder'
6
+ require 'rgen/serializer/json_serializer'
7
+ require 'rgen/instantiator/json_instantiator'
8
+
9
+ class JsonTest < Test::Unit::TestCase
10
+
11
+ module TestMM
12
+ extend RGen::MetamodelBuilder::ModuleExtension
13
+ class TestNode < RGen::MetamodelBuilder::MMBase
14
+ has_attr 'text', String
15
+ has_attr 'integer', Integer
16
+ has_attr 'float', Float
17
+ contains_many 'childs', TestNode, 'parent'
18
+ end
19
+ end
20
+
21
+ class StringWriter < String
22
+ alias write concat
23
+ end
24
+
25
+ def test_json_serializer
26
+ testModel = TestMM::TestNode.new(:text => "some text", :childs => [
27
+ TestMM::TestNode.new(:text => "child")])
28
+
29
+ output = StringWriter.new
30
+ ser = RGen::Serializer::JsonSerializer.new(output)
31
+
32
+ assert_equal %q({ "_class": "TestNode", "text": "some text", "childs": [
33
+ { "_class": "TestNode", "text": "child" }] }), ser.serialize(testModel)
34
+ end
35
+
36
+ def test_json_instantiator
37
+ env = RGen::Environment.new
38
+ inst = RGen::Instantiator::JsonInstantiator.new(env, TestMM)
39
+ inst.instantiate(%q({ "_class": "TestNode", "text": "some text", "childs": [
40
+ { "_class": "TestNode", "text": "child" }] }))
41
+ root = env.find(:class => TestMM::TestNode, :text => "some text").first
42
+ assert_not_nil root
43
+ assert_equal 1, root.childs.size
44
+ assert_equal TestMM::TestNode, root.childs.first.class
45
+ assert_equal "child", root.childs.first.text
46
+ end
47
+
48
+ def test_json_serializer_escapes
49
+ testModel = TestMM::TestNode.new(:text => %q(some " \ \" text))
50
+ output = StringWriter.new
51
+ ser = RGen::Serializer::JsonSerializer.new(output)
52
+
53
+ assert_equal %q({ "_class": "TestNode", "text": "some \" \\ \\\" text" }), ser.serialize(testModel)
54
+ end
55
+
56
+ def test_json_instantiator_escapes
57
+ env = RGen::Environment.new
58
+ inst = RGen::Instantiator::JsonInstantiator.new(env, TestMM)
59
+ inst.instantiate(%q({ "_class": "TestNode", "text": "some \" \\ \\\\\" text" }))
60
+ assert_equal %q(some " \ \" text), env.elements.first.text
61
+ end
62
+
63
+ def test_json_serializer_integer
64
+ testModel = TestMM::TestNode.new(:integer => 7)
65
+ output = StringWriter.new
66
+ ser = RGen::Serializer::JsonSerializer.new(output)
67
+ assert_equal %q({ "_class": "TestNode", "integer": 7 }), ser.serialize(testModel)
68
+ end
69
+
70
+ def test_json_instantiator_integer
71
+ env = RGen::Environment.new
72
+ inst = RGen::Instantiator::JsonInstantiator.new(env, TestMM)
73
+ inst.instantiate(%q({ "_class": "TestNode", "integer": 7 }))
74
+ assert_equal 7, env.elements.first.integer
75
+ end
76
+
77
+ def test_json_serializer_float
78
+ testModel = TestMM::TestNode.new(:float => 1.23)
79
+ output = StringWriter.new
80
+ ser = RGen::Serializer::JsonSerializer.new(output)
81
+ assert_equal %q({ "_class": "TestNode", "float": 1.23 }), ser.serialize(testModel)
82
+ end
83
+
84
+ def test_json_instantiator_float
85
+ env = RGen::Environment.new
86
+ inst = RGen::Instantiator::JsonInstantiator.new(env, TestMM)
87
+ inst.instantiate(%q({ "_class": "TestNode", "float": 1.23 }))
88
+ assert_equal 1.23, env.elements.first.float
89
+ end
90
+ end
91
+
@@ -73,6 +73,76 @@ class MetamodelBuilderTest < Test::Unit::TestCase
73
73
  assert_equal ["extended", "simple"], enum.eLiterals.name.sort
74
74
  end
75
75
 
76
+ class ManyAttrClass < RGen::MetamodelBuilder::MMBase
77
+ has_many_attr 'literals', String
78
+ has_many_attr 'bools', Boolean
79
+ has_many_attr 'integers', Integer
80
+ has_many_attr 'enums', RGen::MetamodelBuilder::DataTypes::Enum.new([:a, :b, :c])
81
+ has_many_attr 'limitTest', Integer, :upperBound => 2
82
+ end
83
+
84
+ def test_many_attr
85
+ o = ManyAttrClass.new
86
+
87
+ assert_respond_to o, :literals
88
+ assert_respond_to o, :addLiterals
89
+ assert_respond_to o, :removeLiterals
90
+
91
+ assert_raise(StandardError) do
92
+ o.addLiterals(1)
93
+ end
94
+
95
+ assert_equal [], o.literals
96
+ o.addLiterals("a")
97
+ assert_equal ["a"], o.literals
98
+ o.addLiterals("b")
99
+ assert_equal ["a", "b"], o.literals
100
+ # check for duplicates works by object identity, so there can be two strings "b"
101
+ o.addLiterals("b")
102
+ assert_equal ["a", "b", "b"], o.literals
103
+ # but the same string object "a" can only occur once
104
+ o.addLiterals(o.literals.first)
105
+ assert_equal ["a", "b", "b"], o.literals
106
+ # removing works by object identity, so providing a new string won't delete an existing one
107
+ o.removeLiterals("a")
108
+ assert_equal ["a", "b", "b"], o.literals
109
+ theA = o.literals.first
110
+ o.removeLiterals(theA)
111
+ assert_equal ["b", "b"], o.literals
112
+ # removing something which is not present has no effect
113
+ o.removeLiterals(theA)
114
+ assert_equal ["b", "b"], o.literals
115
+ o.removeLiterals(o.literals.first)
116
+ assert_equal ["b"], o.literals
117
+ o.removeLiterals(o.literals.first)
118
+ assert_equal [], o.literals
119
+
120
+ # setting multiple elements at a time
121
+ o.literals = ["a", "b", "c"]
122
+ assert_equal ["a", "b", "c"], o.literals
123
+ # can only take arrays
124
+ assert_raise(StandardError) do
125
+ o.literals = "a"
126
+ end
127
+
128
+ o.bools = [true, false, true, false]
129
+ assert_equal [true, false], o.bools
130
+
131
+ o.integers = [1, 2, 2, 3, 3]
132
+ assert_equal [1, 2, 3], o.integers
133
+
134
+ o.enums = [:a, :a, :b, :c, :c]
135
+ assert_equal [:a, :b, :c], o.enums
136
+
137
+ lit = ManyAttrClass.ecore.eAttributes.find{|a| a.name == "literals"}
138
+ assert lit.is_a?(RGen::ECore::EAttribute)
139
+ assert lit.many
140
+
141
+ lim = ManyAttrClass.ecore.eAttributes.find{|a| a.name == "limitTest"}
142
+ assert lit.many
143
+ assert_equal 2, lim.upperBound
144
+ end
145
+
76
146
  class ClassA < RGen::MetamodelBuilder::MMBase
77
147
  # metamodel accessors must work independent of the ==() method
78
148
  module ClassModule
@@ -493,5 +563,129 @@ class MetamodelBuilderTest < Test::Unit::TestCase
493
563
  somePackage = SomePackage.ecore
494
564
  assert_equal somePackage.eSubpackages.first.object_id, subPackage.object_id
495
565
  end
566
+
567
+ def test_proxy
568
+ p = RGen::MetamodelBuilder::MMProxy.new("test")
569
+ assert_equal "test", p.targetIdentifier
570
+ p.targetIdentifier = 123
571
+ assert_equal 123, p.targetIdentifier
572
+ end
573
+
574
+ def test_proxies_has_one
575
+ e = HasOneTestClass.new
576
+ proxy = RGen::MetamodelBuilder::MMProxy.new
577
+ e.classA = proxy
578
+ assert_equal proxy, e.classA
579
+ a = ClassA.new
580
+ # displace proxy
581
+ e.classA = a
582
+ assert_equal a, e.classA
583
+ # displace by proxy
584
+ e.classA = proxy
585
+ assert_equal proxy, e.classA
586
+ end
587
+
588
+ def test_proxies_has_many
589
+ e = HasManyTestClass.new
590
+ proxy = RGen::MetamodelBuilder::MMProxy.new
591
+ e.addClassA(proxy)
592
+ assert_equal [proxy], e.classA
593
+ # again
594
+ e.addClassA(proxy)
595
+ assert_equal [proxy], e.classA
596
+ proxy2 = RGen::MetamodelBuilder::MMProxy.new
597
+ e.addClassA(proxy2)
598
+ assert_equal [proxy, proxy2], e.classA
599
+ e.removeClassA(proxy)
600
+ assert_equal [proxy2], e.classA
601
+ # again
602
+ e.removeClassA(proxy)
603
+ assert_equal [proxy2], e.classA
604
+ e.removeClassA(proxy2)
605
+ assert_equal [], e.classA
606
+ end
607
+
608
+ def test_proxies_one_to_one
609
+ ea = AClassOO.new
610
+ eb = BClassOO.new
611
+ proxy1 = RGen::MetamodelBuilder::MMProxy.new
612
+ proxy2 = RGen::MetamodelBuilder::MMProxy.new
613
+ ea.bClass = proxy1
614
+ eb.aClass = proxy2
615
+ assert_equal proxy1, ea.bClass
616
+ assert_equal proxy2, eb.aClass
617
+ # displace proxies
618
+ ea.bClass = eb
619
+ assert_equal eb, ea.bClass
620
+ assert_equal ea, eb.aClass
621
+ # displace by proxy
622
+ ea.bClass = proxy1
623
+ assert_equal proxy1, ea.bClass
624
+ assert_nil eb.aClass
625
+ end
626
+
627
+ def test_proxies_one_to_many
628
+ eo = OneClass.new
629
+ em = ManyClass.new
630
+ proxy1 = RGen::MetamodelBuilder::MMProxy.new
631
+ proxy2 = RGen::MetamodelBuilder::MMProxy.new
632
+ eo.addManyClasses(proxy1)
633
+ assert_equal [proxy1], eo.manyClasses
634
+ em.oneClass = proxy2
635
+ assert_equal proxy2, em.oneClass
636
+ # displace proxies at many side
637
+ # adding em will set em.oneClass to eo and displace the proxy from em.oneClass
638
+ eo.addManyClasses(em)
639
+ assert_equal [proxy1, em], eo.manyClasses
640
+ assert_equal eo, em.oneClass
641
+ eo.removeManyClasses(proxy1)
642
+ assert_equal [em], eo.manyClasses
643
+ assert_equal eo, em.oneClass
644
+ # displace by proxy
645
+ em.oneClass = proxy2
646
+ assert_equal [], eo.manyClasses
647
+ assert_equal proxy2, em.oneClass
648
+ # displace proxies at one side
649
+ em.oneClass = eo
650
+ assert_equal [em], eo.manyClasses
651
+ assert_equal eo, em.oneClass
652
+ end
653
+
654
+ def test_proxies_many_to_many
655
+ e1 = AClassMM.new
656
+ e2 = BClassMM.new
657
+ proxy1 = RGen::MetamodelBuilder::MMProxy.new
658
+ proxy2 = RGen::MetamodelBuilder::MMProxy.new
659
+ e1.addBClasses(proxy1)
660
+ e2.addAClasses(proxy2)
661
+ assert_equal [proxy1], e1.bClasses
662
+ assert_equal [proxy2], e2.aClasses
663
+ e1.addBClasses(e2)
664
+ assert_equal [proxy1, e2], e1.bClasses
665
+ assert_equal [proxy2, e1], e2.aClasses
666
+ e1.removeBClasses(proxy1)
667
+ e2.removeAClasses(proxy2)
668
+ assert_equal [e2], e1.bClasses
669
+ assert_equal [e1], e2.aClasses
670
+ end
496
671
 
672
+ def test_genericAccess
673
+ e1 = OneClass.new
674
+ e2 = ManyClass.new
675
+ e3 = OneClass.new
676
+ e4 = ManyClass.new
677
+ # use on "many" feature
678
+ e1.setOrAddGeneric("manyClasses", e2)
679
+ assert_equal [e2], e1.manyClasses
680
+ assert_equal [e2], e1.getGeneric("manyClasses")
681
+ assert_equal [e2], e1.getGenericAsArray("manyClasses")
682
+ # use on "one" feature
683
+ e2.setOrAddGeneric("oneClass", e3)
684
+ assert_equal e3, e2.oneClass
685
+ assert_equal e3, e2.getGeneric("oneClass")
686
+ assert_equal [e3], e2.getGenericAsArray("oneClass")
687
+ assert_nil e4.getGeneric("oneClass")
688
+ assert_equal [], e4.getGenericAsArray("oneClass")
689
+ end
690
+
497
691
  end
@@ -7,7 +7,7 @@ require 'mmgen/metamodel_generator'
7
7
  require 'rgen/instantiator/ecore_xml_instantiator'
8
8
  require 'rgen/serializer/xmi20_serializer'
9
9
 
10
- class MetamodelGeneratorTest < Test::Unit::TestCase
10
+ class MetamodelRoundtripTest < Test::Unit::TestCase
11
11
 
12
12
  TEST_DIR = File.dirname(__FILE__)+"/metamodel_roundtrip_test"
13
13
 
@@ -57,5 +57,39 @@ class MetamodelGeneratorTest < Test::Unit::TestCase
57
57
  ser.serialize(HouseMetamodel.ecore)
58
58
  end
59
59
  end
60
-
61
- end
60
+
61
+ BuiltinTypesTestEcore = TEST_DIR+"/using_builtin_types.ecore"
62
+
63
+ def test_ecore_serializer_builtin_types
64
+ mm = RGen::ECore::EPackage.new(:name => "P1", :eClassifiers => [
65
+ RGen::ECore::EClass.new(:name => "C1", :eStructuralFeatures => [
66
+ RGen::ECore::EAttribute.new(:name => "a1", :eType => RGen::ECore::EString),
67
+ RGen::ECore::EAttribute.new(:name => "a2", :eType => RGen::ECore::EInt),
68
+ RGen::ECore::EAttribute.new(:name => "a3", :eType => RGen::ECore::EFloat),
69
+ RGen::ECore::EAttribute.new(:name => "a4", :eType => RGen::ECore::EBoolean)
70
+ ])
71
+ ])
72
+ outfile = TEST_DIR+"/using_builtin_types_serialized.ecore"
73
+ File.open(outfile, "w") do |f|
74
+ ser = RGen::Serializer::XMI20Serializer.new(f)
75
+ ser.serialize(mm)
76
+ end
77
+ assert_equal(File.read(BuiltinTypesTestEcore), File.read(outfile))
78
+ end
79
+
80
+ def test_ecore_instantiator_builtin_types
81
+ env = RGen::Environment.new
82
+ File.open(BuiltinTypesTestEcore) { |f|
83
+ ECoreXMLInstantiator.new(env).instantiate(f.read)
84
+ }
85
+ a1 = env.find(:class => RGen::ECore::EAttribute, :name => "a1").first
86
+ assert_equal(RGen::ECore::EString, a1.eType)
87
+ a2 = env.find(:class => RGen::ECore::EAttribute, :name => "a2").first
88
+ assert_equal(RGen::ECore::EInt, a2.eType)
89
+ a3 = env.find(:class => RGen::ECore::EAttribute, :name => "a3").first
90
+ assert_equal(RGen::ECore::EFloat, a3.eType)
91
+ a4 = env.find(:class => RGen::ECore::EAttribute, :name => "a4").first
92
+ assert_equal(RGen::ECore::EBoolean, a4.eType)
93
+ end
94
+
95
+ end
@@ -15,6 +15,7 @@ module HouseMetamodel
15
15
  class Person < RGen::MetamodelBuilder::MMBase
16
16
  annotation 'complexity' => '1', 'date_created' => '2006-06-27 08:34:23', 'date_modified' => '2006-06-27 08:34:26', 'ea_ntype' => '0', 'ea_stype' => 'Class', 'gentype' => 'Java', 'isSpecification' => 'false', 'package' => 'EAPK_A1B83D59_CAE1_422c_BA5F_D3624D7156AD', 'package_name' => 'HouseMetamodel', 'phase' => '1.0', 'status' => 'Proposed', 'style' => 'BackColor=-1;BorderColor=-1;BorderWidth=-1;FontColor=-1;VSwimLanes=0;HSwimLanes=0;BorderStyle=0;', 'tagged' => '0', 'version' => '1.0'
17
17
  has_attr 'sex', SexEnum
18
+ has_many_attr 'nicknames', String
18
19
  end
19
20
 
20
21
  class House < RGen::MetamodelBuilder::MMBase
@@ -65,4 +66,4 @@ end
65
66
  HouseMetamodel::House.contains_many 'room', HouseMetamodel::Rooms::Room, 'house', :lowerBound => 1 do
66
67
  # only an opposite annotation
67
68
  opposite_annotation 'containment' => 'Unspecified'
68
- end
69
+ end
@@ -20,6 +20,7 @@
20
20
  <eStructuralFeatures xsi:type="ecore:EReference" name="house" upperBound="-1"
21
21
  eType="#//House"/>
22
22
  <eStructuralFeatures xsi:type="ecore:EAttribute" name="sex" eType="#//SexEnum"/>
23
+ <eStructuralFeatures xsi:type="ecore:EAttribute" name="nicknames" upperBound="-1" eType="#//String"/>
23
24
  </eClassifiers>
24
25
  <eClassifiers xsi:type="ecore:EDataType" name="String" instanceClassName="java.lang.String"/>
25
26
  <eClassifiers xsi:type="ecore:EEnum" name="SexEnum">
@@ -16,6 +16,7 @@ module HouseMetamodel
16
16
 
17
17
  class Person < RGen::MetamodelBuilder::MMBase
18
18
  has_attr 'sex', HouseMetamodel::SexEnum
19
+ has_many_attr 'nicknames', String
19
20
  end
20
21
 
21
22
 
@@ -0,0 +1,8 @@
1
+ <ecore:EPackage xmi:version="2.0" name="P1" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore">
2
+ <eClassifiers name="C1" xsi:type="ecore:EClass">
3
+ <eStructuralFeatures name="a1" derived="false" transient="false" changeable="true" unsettable="false" iD="false" xsi:type="ecore:EAttribute" upperBound="1" ordered="true" volatile="false" lowerBound="0" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" unique="true"/>
4
+ <eStructuralFeatures name="a2" derived="false" transient="false" changeable="true" unsettable="false" iD="false" xsi:type="ecore:EAttribute" upperBound="1" ordered="true" volatile="false" lowerBound="0" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt" unique="true"/>
5
+ <eStructuralFeatures name="a3" derived="false" transient="false" changeable="true" unsettable="false" iD="false" xsi:type="ecore:EAttribute" upperBound="1" ordered="true" volatile="false" lowerBound="0" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloat" unique="true"/>
6
+ <eStructuralFeatures name="a4" derived="false" transient="false" changeable="true" unsettable="false" iD="false" xsi:type="ecore:EAttribute" upperBound="1" ordered="true" volatile="false" lowerBound="0" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean" unique="true"/>
7
+ </eClassifiers>
8
+ </ecore:EPackage>
@@ -0,0 +1,8 @@
1
+ <ecore:EPackage xmi:version="2.0" name="P1" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore">
2
+ <eClassifiers name="C1" xsi:type="ecore:EClass">
3
+ <eStructuralFeatures name="a1" derived="false" transient="false" changeable="true" unsettable="false" iD="false" xsi:type="ecore:EAttribute" upperBound="1" ordered="true" volatile="false" lowerBound="0" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString" unique="true"/>
4
+ <eStructuralFeatures name="a2" derived="false" transient="false" changeable="true" unsettable="false" iD="false" xsi:type="ecore:EAttribute" upperBound="1" ordered="true" volatile="false" lowerBound="0" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt" unique="true"/>
5
+ <eStructuralFeatures name="a3" derived="false" transient="false" changeable="true" unsettable="false" iD="false" xsi:type="ecore:EAttribute" upperBound="1" ordered="true" volatile="false" lowerBound="0" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloat" unique="true"/>
6
+ <eStructuralFeatures name="a4" derived="false" transient="false" changeable="true" unsettable="false" iD="false" xsi:type="ecore:EAttribute" upperBound="1" ordered="true" volatile="false" lowerBound="0" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean" unique="true"/>
7
+ </eClassifiers>
8
+ </ecore:EPackage>
@@ -0,0 +1,102 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),"..","lib")
2
+
3
+ require 'test/unit'
4
+ require 'rgen/metamodel_builder'
5
+ require 'rgen/instantiator/qualified_name_resolver'
6
+
7
+ class QualifiedNameResolverTest < Test::Unit::TestCase
8
+
9
+ class TestNode < RGen::MetamodelBuilder::MMBase
10
+ has_attr 'name', String
11
+ has_one 'nextSibling', TestNode
12
+ contains_many 'children', TestNode, "parent"
13
+ end
14
+
15
+ class TestNode2 < RGen::MetamodelBuilder::MMBase
16
+ has_attr 'cname', String
17
+ has_one 'nextSibling', TestNode2
18
+ contains_many 'children', TestNode2, "parent"
19
+ end
20
+
21
+ class TestNode3 < RGen::MetamodelBuilder::MMBase
22
+ has_attr 'name', String
23
+ contains_one 'child', TestNode3, "parent"
24
+ end
25
+
26
+ def testModel
27
+ [TestNode.new(:name => "Root1", :children => [
28
+ TestNode.new(:name => "Sub11"),
29
+ TestNode.new(:name => "Sub12", :children => [
30
+ TestNode.new(:name => "Sub121")])]),
31
+ TestNode.new(:name => "Root2", :children => [
32
+ TestNode.new(:name => "Sub21", :children => [
33
+ TestNode.new(:name => "Sub211")])]),
34
+ TestNode.new(:name => "Root3"),
35
+ TestNode.new(:name => "Root3")
36
+ ]
37
+ end
38
+
39
+ def testModel2
40
+ [TestNode2.new(:cname => "Root1", :children => [
41
+ TestNode2.new(:cname => "Sub11")])]
42
+ end
43
+
44
+ def testModel3
45
+ [TestNode3.new(:name => "Root1", :child =>
46
+ TestNode3.new(:name => "Sub11", :child =>
47
+ TestNode3.new(:name => "Sub111")))]
48
+ end
49
+
50
+ def test_customNameAttribute
51
+ model = testModel2
52
+ res = RGen::Instantiator::QualifiedNameResolver.new(model, :nameAttribute => "cname")
53
+ assert_equal model[0], res.resolveIdentifier("/Root1")
54
+ assert_equal model[0].children[0], res.resolveIdentifier("/Root1/Sub11")
55
+ end
56
+
57
+ def test_customSeparator
58
+ model = testModel
59
+ res = RGen::Instantiator::QualifiedNameResolver.new(model, :separator => "|")
60
+ assert_equal model[0], res.resolveIdentifier("|Root1")
61
+ assert_nil res.resolveIdentifier("/Root1")
62
+ assert_equal model[0].children[0], res.resolveIdentifier("|Root1|Sub11")
63
+ end
64
+
65
+ def test_noLeadingSeparator
66
+ model = testModel
67
+ res = RGen::Instantiator::QualifiedNameResolver.new(model, :leadingSeparator => false)
68
+ assert_equal model[0], res.resolveIdentifier("Root1")
69
+ assert_nil res.resolveIdentifier("/Root1")
70
+ assert_equal model[0].children[0], res.resolveIdentifier("Root1/Sub11")
71
+ end
72
+
73
+ def test_resolve
74
+ model = testModel
75
+ res = RGen::Instantiator::QualifiedNameResolver.new(model)
76
+ assert_equal model[0], res.resolveIdentifier("/Root1")
77
+ # again
78
+ assert_equal model[0], res.resolveIdentifier("/Root1")
79
+ assert_equal model[0].children[0], res.resolveIdentifier("/Root1/Sub11")
80
+ # again
81
+ assert_equal model[0].children[0], res.resolveIdentifier("/Root1/Sub11")
82
+ assert_equal model[0].children[1], res.resolveIdentifier("/Root1/Sub12")
83
+ assert_equal model[0].children[1].children[0], res.resolveIdentifier("/Root1/Sub12/Sub121")
84
+ assert_equal model[1], res.resolveIdentifier("/Root2")
85
+ assert_equal model[1].children[0], res.resolveIdentifier("/Root2/Sub21")
86
+ assert_equal model[1].children[0].children[0], res.resolveIdentifier("/Root2/Sub21/Sub211")
87
+ # duplicate name yields two result elements
88
+ assert_equal [model[2], model[3]], res.resolveIdentifier("/Root3")
89
+ assert_equal nil, res.resolveIdentifier("/RootX")
90
+ assert_equal nil, res.resolveIdentifier("/Root1/SubX")
91
+ end
92
+
93
+ def test_oneChild
94
+ model = testModel3
95
+ res = RGen::Instantiator::QualifiedNameResolver.new(model)
96
+ assert_equal model[0], res.resolveIdentifier("/Root1")
97
+ assert_equal model[0].child, res.resolveIdentifier("/Root1/Sub11")
98
+ assert_equal model[0].child.child, res.resolveIdentifier("/Root1/Sub11/Sub111")
99
+ end
100
+
101
+ end
102
+