rgen 0.5.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+