rgen 0.6.6 → 0.7.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fe212a74ff9c45d6fcd848596acb527d6def24f5
4
+ data.tar.gz: 3c99d2170dab24b922a30a5a5420f03aaa05779e
5
+ SHA512:
6
+ metadata.gz: a70a59af207fcf7d3c35c0f8785a9bcceebb370b9a0f41e07a2103bc563256acd6e5160d256c1e8c786d52f48f9e540ed62e2105348b9b9a520a57f9d0a99c0b
7
+ data.tar.gz: eae33d63df0964a0175917aa7efd711306e933a4ab56fa938976a5d28eb8fc53a3e7e18e984a4c89dd134d0421418f6d86ff02a60c1e7e011620a544a62b6edd
data/CHANGELOG CHANGED
@@ -186,3 +186,12 @@
186
186
  * Major performance improvement of FragmentedModel#resolve
187
187
  * Fixed a Ruby 2.0 related warning
188
188
 
189
+ =0.7.0
190
+
191
+ * Enforce unique container rule by automatically disconnecting elements from other containers
192
+ * Added support for long typed values (ELong), thanks to Thomas Hallgren;
193
+ Note that this is merely an EMF compatibility thing, RGen could already handle big integers before
194
+ * Added eContents and eAllContents methods
195
+ * Added setNilOrRemoveGeneric and setNilOrRemoveAllGeneric methods
196
+ * Added disconnectContainer method
197
+
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ require 'rdoc/task'
3
3
 
4
4
  RGenGemSpec = Gem::Specification.new do |s|
5
5
  s.name = %q{rgen}
6
- s.version = "0.6.6"
6
+ s.version = "0.7.0"
7
7
  s.date = Time.now.strftime("%Y-%m-%d")
8
8
  s.summary = %q{Ruby Modelling and Generator Framework}
9
9
  s.email = %q{martin dot thiede at gmx de}
@@ -54,7 +54,7 @@ module RGen
54
54
  def defaultValue_derived
55
55
  return nil if defaultValueLiteral.nil?
56
56
  case eType
57
- when EInt
57
+ when EInt, ELong
58
58
  defaultValueLiteral.to_i
59
59
  when EFloat
60
60
  defaultValueLiteral.to_f
@@ -81,7 +81,10 @@ module RGen
81
81
  has_attr 'instanceClassName', String
82
82
  module ClassModule
83
83
  def instanceClass_derived
84
- map = {"java.lang.string" => "String", "boolean" => "RGen::MetamodelBuilder::DataTypes::Boolean", "int" => "Integer"}
84
+ map = {"java.lang.string" => "String",
85
+ "boolean" => "RGen::MetamodelBuilder::DataTypes::Boolean",
86
+ "int" => "Integer",
87
+ "long" => "RGen::MetamodelBuilder::DataTypes::Long"}
85
88
  icn = instanceClassName
86
89
  icn = "NilClass" if icn.nil?
87
90
  icn = map[icn.downcase] if map[icn.downcase]
@@ -181,6 +184,7 @@ module RGen
181
184
 
182
185
  EString = EDataType.new(:name => "EString", :instanceClassName => "String")
183
186
  EInt = EDataType.new(:name => "EInt", :instanceClassName => "Integer")
187
+ ELong = EDataType.new(:name => "ELong", :instanceClassName => "Long")
184
188
  EBoolean = EDataType.new(:name => "EBoolean", :instanceClassName => "Boolean")
185
189
  EFloat = EDataType.new(:name => "EFloat", :instanceClassName => "Float")
186
190
  ERubyObject = EDataType.new(:name => "ERubyObject", :instanceClassName => "Object")
@@ -111,7 +111,7 @@ class ModelFragment
111
111
  @elements = []
112
112
  @root_elements.each do |e|
113
113
  @elements << e
114
- all_child_elements(e, @elements)
114
+ @elements.concat(e.eAllContents)
115
115
  end
116
116
  @elements
117
117
  end
@@ -274,21 +274,6 @@ class ModelFragment
274
274
  end
275
275
  end
276
276
 
277
- def all_child_elements(element, childs)
278
- containment_references(element.class).each do |r|
279
- element.getGenericAsArray(r.name).each do |c|
280
- childs << c
281
- all_child_elements(c, childs)
282
- end
283
- end
284
- end
285
-
286
- def containment_references(clazz)
287
- @@containment_references_cache ||= {}
288
- @@containment_references_cache[clazz] ||=
289
- clazz.ecore.eAllReferences.select{|r| r.containment}
290
- end
291
-
292
277
  def non_containment_references(clazz)
293
278
  @@non_containment_references_cache ||= {}
294
279
  @@non_containment_references_cache[clazz] ||=
@@ -84,7 +84,7 @@ class ECoreXMLInstantiator < AbstractXMLInstantiator
84
84
  elsif eFeat
85
85
  value = true if value == "true" && eFeat.eType == EBoolean
86
86
  value = false if value == "false" && eFeat.eType == EBoolean
87
- value = value.to_i if eFeat.eType == EInt
87
+ value = value.to_i if eFeat.eType == EInt || eFeat.eType == ELong
88
88
  @elementstack.last.setGeneric(attr, value)
89
89
  else
90
90
  log WARN, "Feature not found: #{attr} on #{@elementstack.last}"
@@ -134,6 +134,7 @@ class ECoreXMLInstantiator < AbstractXMLInstantiator
134
134
  case $1
135
135
  when "EString"; RGen::ECore::EString
136
136
  when "EInt"; RGen::ECore::EInt
137
+ when "ELong"; RGen::ECore::ELong
137
138
  when "EBoolean"; RGen::ECore::EBoolean
138
139
  when "EFloat"; RGen::ECore::EFloat
139
140
  when "EJavaObject"; RGen::ECore::EJavaObject
@@ -116,7 +116,7 @@ class XMI11Instantiator < AbstractXMLInstantiator
116
116
  value = map_feature_value(attr_name, value) || value
117
117
  value = true if value == "true" && eFeat.eType == EBoolean
118
118
  value = false if value == "false" && eFeat.eType == EBoolean
119
- value = value.to_i if eFeat.eType == EInt
119
+ value = value.to_i if eFeat.eType == EInt || eFeat.eType == ELong
120
120
  value = value.to_f if eFeat.eType == EFloat
121
121
  value = value.to_sym if eFeat.eType.is_a?(EEnum)
122
122
  @elementstack.last.setGeneric(attr_name, value)
@@ -487,7 +487,7 @@ module BuilderExtensions
487
487
 
488
488
  def check_default_value_literal(literal, props)
489
489
  return if literal.nil? || props.impl_type == String
490
- if props.impl_type == Integer
490
+ if props.impl_type == Integer || props.impl_type == RGen::MetamodelBuilder::DataTypes::Long
491
491
  unless literal =~ /^\d+$/
492
492
  raise StandardError.new("Property #{props.value(:name)} can not take value #{literal}, expected an Integer")
493
493
  end
@@ -510,7 +510,11 @@ module BuilderExtensions
510
510
 
511
511
  def type_check_code(varname, props)
512
512
  code = ""
513
- if props.impl_type.is_a?(Class)
513
+ if props.impl_type == RGen::MetamodelBuilder::DataTypes::Long
514
+ code << "unless #{varname}.nil? || #{varname}.is_a?(Integer) || #{varname}.is_a?(MMGeneric)"
515
+ code << "\n"
516
+ expected = "Integer"
517
+ elsif props.impl_type.is_a?(Class)
514
518
  code << "unless #{varname}.nil? || #{varname}.is_a?(#{props.impl_type}) || #{varname}.is_a?(MMGeneric)"
515
519
  code << " || #{varname}.is_a?(BigDecimal)" if props.impl_type == Float && defined?(BigDecimal)
516
520
  code << "\n"
@@ -42,6 +42,22 @@ module BuilderRuntime
42
42
  end
43
43
  end
44
44
 
45
+ def setNilOrRemoveGeneric(role, value)
46
+ if hasManyMethods(role)
47
+ removeGeneric(role, value)
48
+ else
49
+ setGeneric(role, nil)
50
+ end
51
+ end
52
+
53
+ def setNilOrRemoveAllGeneric(role)
54
+ if hasManyMethods(role)
55
+ setGeneric(role, [])
56
+ else
57
+ setGeneric(role, nil)
58
+ end
59
+ end
60
+
45
61
  def getGeneric(role)
46
62
  send("get#{firstToUpper(role.to_s)}")
47
63
  end
@@ -73,11 +89,70 @@ module BuilderRuntime
73
89
  @_containing_feature_name
74
90
  end
75
91
 
92
+ # returns the contained elements in no particular order
93
+ def eContents
94
+ if @_contained_elements
95
+ @_contained_elements.dup
96
+ else
97
+ []
98
+ end
99
+ end
100
+
101
+ # if a block is given, calls the block on every contained element in depth first order.
102
+ # if the block returns :prune, recursion will stop at this point.
103
+ #
104
+ # if no block is given builds and returns a list of all contained elements.
105
+ #
106
+ def eAllContents(&block)
107
+ if block
108
+ if @_contained_elements
109
+ @_contained_elements.each do |e|
110
+ res = block.call(e)
111
+ e.eAllContents(&block) if res != :prune
112
+ end
113
+ end
114
+ nil
115
+ else
116
+ result = []
117
+ if @_contained_elements
118
+ @_contained_elements.each do |e|
119
+ result << e
120
+ result.concat(e.eAllContents)
121
+ end
122
+ end
123
+ result
124
+ end
125
+ end
126
+
127
+ def disconnectContainer
128
+ eContainer.setNilOrRemoveGeneric(eContainingFeature, self) if eContainer
129
+ end
130
+
76
131
  def _set_container(container, containing_feature_name)
132
+ # if a new container is set, make sure to disconnect from the old one.
133
+ # note that _set_container will never be called for the container and the role
134
+ # which are currently set because the accessor methods in BuilderExtensions
135
+ # block setting/adding a value which is already present.
136
+ # (it may be called for the same container with a different role, a different container
137
+ # with the same role and a different container with a different role, though)
138
+ # this ensures, that disconnecting for the current container doesn't break
139
+ # a new connection which has just been set up in the accessor methods.
140
+ disconnectContainer if container
141
+ @_container._remove_contained_element(self) if @_container
142
+ container._add_contained_element(self) if container
77
143
  @_container = container
78
144
  @_containing_feature_name = containing_feature_name
79
145
  end
80
146
 
147
+ def _add_contained_element(element)
148
+ @_contained_elements ||= []
149
+ @_contained_elements << element
150
+ end
151
+
152
+ def _remove_contained_element(element)
153
+ @_contained_elements.delete(element) if @_contained_elements
154
+ end
155
+
81
156
  def _assignmentTypeError(target, value, expected)
82
157
  text = ""
83
158
  if target
@@ -65,6 +65,11 @@ module DataTypes
65
65
  # as possible values.
66
66
  Boolean = Enum.new(:name => "Boolean", :literals => [true, false])
67
67
 
68
+ # Long represents a 64-bit Integer
69
+ # This constant is merely a marker for keeping this information in the Ruby version of the metamodel,
70
+ # values of this type will always be instances of Integer or Bignum;
71
+ # Setting it to a string value ensures that it responds to "to_s" which is used in the metamodel generator
72
+ Long = "Long"
68
73
  end
69
74
 
70
75
  end
@@ -67,6 +67,7 @@ class Attribute < Feature
67
67
  Types = {
68
68
  String => :EString,
69
69
  Integer => :EInt,
70
+ RGen::MetamodelBuilder::DataTypes::Long => :ELong,
70
71
  Float => :EFloat,
71
72
  RGen::MetamodelBuilder::DataTypes::Boolean => :EBoolean,
72
73
  Object => :ERubyObject,
@@ -57,6 +57,7 @@ class XMI20Serializer < XMLSerializer
57
57
  pre = "ecore:EDataType http://www.eclipse.org/emf/2002/Ecore"
58
58
  @referenceStrings[RGen::ECore::EString] = pre+"#//EString"
59
59
  @referenceStrings[RGen::ECore::EInt] = pre+"#//EInt"
60
+ @referenceStrings[RGen::ECore::ELong] = pre+"#//ELong"
60
61
  @referenceStrings[RGen::ECore::EFloat] = pre+"#//EFloat"
61
62
  @referenceStrings[RGen::ECore::EBoolean] = pre+"#//EBoolean"
62
63
  @referenceStrings[RGen::ECore::EJavaObject] = pre+"#//EJavaObject"
@@ -15,6 +15,7 @@ class MetamodelBuilderTest < Test::Unit::TestCase
15
15
  has_attr 'name' # default is String
16
16
  has_attr 'stringWithDefault', String, :defaultValueLiteral => "xtest"
17
17
  has_attr 'integerWithDefault', Integer, :defaultValueLiteral => "123"
18
+ has_attr 'longWithDefault', Long, :defaultValueLiteral => "1234567890"
18
19
  has_attr 'floatWithDefault', Float, :defaultValueLiteral => "0.123"
19
20
  has_attr 'boolWithDefault', Boolean, :defaultValueLiteral => "true"
20
21
  has_attr 'anything', Object
@@ -148,9 +149,17 @@ class MetamodelBuilderTest < Test::Unit::TestCase
148
149
 
149
150
  class ContainerClass < RGen::MetamodelBuilder::MMBase
150
151
  contains_one_uni 'oneChildUni', ContainedClass
152
+ contains_one_uni 'oneChildUni2', ContainedClass
151
153
  contains_one 'oneChild', ContainedClass, 'parentOne'
154
+ contains_one 'oneChild2', ContainedClass, 'parentOne2'
152
155
  contains_many_uni 'manyChildUni', ContainedClass
156
+ contains_many_uni 'manyChildUni2', ContainedClass
153
157
  contains_many 'manyChild', ContainedClass, 'parentMany'
158
+ contains_many 'manyChild2', ContainedClass, 'parentMany2'
159
+ end
160
+
161
+ class NestedContainerClass < ContainedClass
162
+ contains_one_uni 'oneChildUni', ContainedClass
154
163
  end
155
164
 
156
165
  class OppositeRefAssocA < RGen::MetamodelBuilder::MMBase
@@ -183,6 +192,7 @@ class MetamodelBuilderTest < Test::Unit::TestCase
183
192
  assert_equal "xtest", sc.stringWithDefault
184
193
  assert_equal :extended, sc.kindWithDefault
185
194
  assert_equal 123, sc.integerWithDefault
195
+ assert_equal 1234567890, sc.longWithDefault
186
196
  assert_equal 0.123, sc.floatWithDefault
187
197
  assert_equal true, sc.boolWithDefault
188
198
 
@@ -253,6 +263,20 @@ class MetamodelBuilderTest < Test::Unit::TestCase
253
263
  assert sc2.floatWithDefault.is_a?(BigDecimal)
254
264
  assert_equal "123456789012345678.0", sc2.floatWithDefault.to_s("F")
255
265
  end
266
+
267
+ def test_long
268
+ sc = mm::SimpleClass.new
269
+ sc.longWithDefault = 5
270
+ assert_equal 5, sc.longWithDefault
271
+ sc.longWithDefault = 1234567890
272
+ assert_equal 1234567890, sc.longWithDefault
273
+ assert sc.longWithDefault.is_a?(Bignum)
274
+ assert sc.longWithDefault.is_a?(Integer)
275
+ err = assert_raise StandardError do
276
+ sc.longWithDefault = "a string"
277
+ end
278
+ assert_match /In (\w+::)+SimpleClass : Can not use a String where a Integer is expected/, err.message
279
+ end
256
280
 
257
281
  def test_many_attr
258
282
  o = mm::ManyAttrClass.new
@@ -807,6 +831,8 @@ class MetamodelBuilderTest < Test::Unit::TestCase
807
831
  assert_equal [e1], e2.aClasses
808
832
  end
809
833
 
834
+ # Multiplicity agnostic convenience methods
835
+
810
836
  def test_genericAccess
811
837
  e1 = mm::OneClass.new
812
838
  e2 = mm::ManyClass.new
@@ -826,6 +852,40 @@ class MetamodelBuilderTest < Test::Unit::TestCase
826
852
  assert_equal [], e4.getGenericAsArray("oneClass")
827
853
  end
828
854
 
855
+ def test_setNilOrRemoveGeneric
856
+ e1 = mm::OneClass.new
857
+ e2 = mm::ManyClass.new
858
+ e3 = mm::OneClass.new
859
+ # use on "many" feature
860
+ e1.addManyClasses(e2)
861
+ assert_equal [e2], e1.manyClasses
862
+ e1.setNilOrRemoveGeneric("manyClasses", e2)
863
+ assert_equal [], e1.manyClasses
864
+ # use on "one" feature
865
+ e2.oneClass = e3
866
+ assert_equal e3, e2.oneClass
867
+ e2.setNilOrRemoveGeneric("oneClass", e3)
868
+ assert_nil e2.oneClass
869
+ end
870
+
871
+ def test_setNilOrRemoveAllGeneric
872
+ e1 = mm::OneClass.new
873
+ e2 = mm::ManyClass.new
874
+ e3 = mm::OneClass.new
875
+ e4 = mm::ManyClass.new
876
+ # use on "many" feature
877
+ e1.addManyClasses(e2)
878
+ e1.addManyClasses(e4)
879
+ assert_equal [e2, e4], e1.manyClasses
880
+ e1.setNilOrRemoveAllGeneric("manyClasses")
881
+ assert_equal [], e1.manyClasses
882
+ # use on "one" feature
883
+ e2.oneClass = e3
884
+ assert_equal e3, e2.oneClass
885
+ e2.setNilOrRemoveAllGeneric("oneClass")
886
+ assert_nil e2.oneClass
887
+ end
888
+
829
889
  def test_abstract
830
890
  err = assert_raise StandardError do
831
891
  mm::AbstractClass.new
@@ -871,6 +931,11 @@ class MetamodelBuilderTest < Test::Unit::TestCase
871
931
  has_attr 'enumWithDefault', kindType, :defaultValueLiteral => "7"
872
932
  end
873
933
  end
934
+ Test8 = proc do
935
+ class BadClass < RGen::MetamodelBuilder::MMBase
936
+ has_attr 'longWithDefault', Integer, :defaultValueLiteral => "1.1"
937
+ end
938
+ end
874
939
  end
875
940
 
876
941
  def test_bad_default_value_literal
@@ -902,6 +967,10 @@ class MetamodelBuilderTest < Test::Unit::TestCase
902
967
  BadDefaultValueLiteralContainer::Test7.call
903
968
  end
904
969
  assert_equal "Property enumWithDefault can not take value 7, expected one of :simple, :extended", err.message
970
+ err = assert_raise StandardError do
971
+ BadDefaultValueLiteralContainer::Test8.call
972
+ end
973
+ assert_equal "Property longWithDefault can not take value 1.1, expected an Integer", err.message
905
974
  end
906
975
 
907
976
  def test_isset_set_to_nil
@@ -1017,39 +1086,57 @@ class MetamodelBuilderTest < Test::Unit::TestCase
1017
1086
  a = mm::ContainerClass.new
1018
1087
  b = mm::ContainedClass.new
1019
1088
  c = mm::ContainedClass.new
1089
+ assert_equal [], a.eContents
1090
+ assert_equal [], a.eAllContents
1020
1091
  assert_nil b.eContainer
1021
1092
  assert_nil b.eContainingFeature
1022
1093
  a.oneChildUni = b
1023
1094
  assert_equal a, b.eContainer
1024
1095
  assert_equal :oneChildUni, b.eContainingFeature
1096
+ assert_equal [b], a.eContents
1097
+ assert_equal [b], a.eAllContents
1025
1098
  a.oneChildUni = c
1026
1099
  assert_nil b.eContainer
1027
1100
  assert_nil b.eContainingFeature
1028
1101
  assert_equal a, c.eContainer
1029
1102
  assert_equal :oneChildUni, c.eContainingFeature
1103
+ assert_equal [c], a.eContents
1104
+ assert_equal [c], a.eAllContents
1030
1105
  a.oneChildUni = nil
1031
1106
  assert_nil c.eContainer
1032
1107
  assert_nil c.eContainingFeature
1108
+ assert_equal [], a.eContents
1109
+ assert_equal [], a.eAllContents
1033
1110
  end
1034
1111
 
1035
1112
  def test_container_many_uni
1036
1113
  a = mm::ContainerClass.new
1037
1114
  b = mm::ContainedClass.new
1038
1115
  c = mm::ContainedClass.new
1116
+ assert_equal [], a.eContents
1117
+ assert_equal [], a.eAllContents
1039
1118
  a.addManyChildUni(b)
1040
1119
  assert_equal a, b.eContainer
1041
1120
  assert_equal :manyChildUni, b.eContainingFeature
1121
+ assert_equal [b], a.eContents
1122
+ assert_equal [b], a.eAllContents
1042
1123
  a.addManyChildUni(c)
1043
1124
  assert_equal a, c.eContainer
1044
1125
  assert_equal :manyChildUni, c.eContainingFeature
1126
+ assert_equal [b, c], a.eContents
1127
+ assert_equal [b, c], a.eAllContents
1045
1128
  a.removeManyChildUni(b)
1046
1129
  assert_nil b.eContainer
1047
1130
  assert_nil b.eContainingFeature
1048
1131
  assert_equal a, c.eContainer
1049
1132
  assert_equal :manyChildUni, c.eContainingFeature
1133
+ assert_equal [c], a.eContents
1134
+ assert_equal [c], a.eAllContents
1050
1135
  a.removeManyChildUni(c)
1051
1136
  assert_nil c.eContainer
1052
1137
  assert_nil c.eContainingFeature
1138
+ assert_equal [], a.eContents
1139
+ assert_equal [], a.eAllContents
1053
1140
  end
1054
1141
 
1055
1142
  def test_conainer_one_bi
@@ -1060,14 +1147,22 @@ class MetamodelBuilderTest < Test::Unit::TestCase
1060
1147
  a.oneChild = b
1061
1148
  assert_equal a, b.eContainer
1062
1149
  assert_equal :oneChild, b.eContainingFeature
1150
+ assert_equal [b], a.eContents
1151
+ assert_equal [b], a.eAllContents
1063
1152
  c.oneChild = d
1064
1153
  assert_equal c, d.eContainer
1065
1154
  assert_equal :oneChild, d.eContainingFeature
1155
+ assert_equal [d], c.eContents
1156
+ assert_equal [d], c.eAllContents
1066
1157
  a.oneChild = d
1067
1158
  assert_nil b.eContainer
1068
1159
  assert_nil b.eContainingFeature
1069
1160
  assert_equal a, d.eContainer
1070
1161
  assert_equal :oneChild, d.eContainingFeature
1162
+ assert_equal [d], a.eContents
1163
+ assert_equal [d], a.eAllContents
1164
+ assert_equal [], c.eContents
1165
+ assert_equal [], c.eAllContents
1071
1166
  end
1072
1167
 
1073
1168
  def test_conainer_one_bi_rev
@@ -1078,14 +1173,22 @@ class MetamodelBuilderTest < Test::Unit::TestCase
1078
1173
  a.oneChild = b
1079
1174
  assert_equal a, b.eContainer
1080
1175
  assert_equal :oneChild, b.eContainingFeature
1176
+ assert_equal [b], a.eContents
1177
+ assert_equal [b], a.eAllContents
1081
1178
  c.oneChild = d
1082
1179
  assert_equal c, d.eContainer
1083
1180
  assert_equal :oneChild, d.eContainingFeature
1181
+ assert_equal [d], c.eContents
1182
+ assert_equal [d], c.eAllContents
1084
1183
  d.parentOne = a
1085
1184
  assert_nil b.eContainer
1086
1185
  assert_nil b.eContainingFeature
1087
1186
  assert_equal a, d.eContainer
1088
1187
  assert_equal :oneChild, d.eContainingFeature
1188
+ assert_equal [d], a.eContents
1189
+ assert_equal [d], a.eAllContents
1190
+ assert_equal [], c.eContents
1191
+ assert_equal [], c.eAllContents
1089
1192
  end
1090
1193
 
1091
1194
  def test_conainer_one_bi_nil
@@ -1094,9 +1197,13 @@ class MetamodelBuilderTest < Test::Unit::TestCase
1094
1197
  a.oneChild = b
1095
1198
  assert_equal a, b.eContainer
1096
1199
  assert_equal :oneChild, b.eContainingFeature
1200
+ assert_equal [b], a.eContents
1201
+ assert_equal [b], a.eAllContents
1097
1202
  a.oneChild = nil
1098
1203
  assert_nil b.eContainer
1099
1204
  assert_nil b.eContainingFeature
1205
+ assert_equal [], a.eContents
1206
+ assert_equal [], a.eAllContents
1100
1207
  end
1101
1208
 
1102
1209
  def test_conainer_one_bi_nil_rev
@@ -1105,9 +1212,13 @@ class MetamodelBuilderTest < Test::Unit::TestCase
1105
1212
  a.oneChild = b
1106
1213
  assert_equal a, b.eContainer
1107
1214
  assert_equal :oneChild, b.eContainingFeature
1215
+ assert_equal [b], a.eContents
1216
+ assert_equal [b], a.eAllContents
1108
1217
  b.parentOne = nil
1109
1218
  assert_nil b.eContainer
1110
1219
  assert_nil b.eContainingFeature
1220
+ assert_equal [], a.eContents
1221
+ assert_equal [], a.eAllContents
1111
1222
  end
1112
1223
 
1113
1224
  def test_container_many_bi
@@ -1120,9 +1231,13 @@ class MetamodelBuilderTest < Test::Unit::TestCase
1120
1231
  assert_equal :manyChild, b.eContainingFeature
1121
1232
  assert_equal a, c.eContainer
1122
1233
  assert_equal :manyChild, c.eContainingFeature
1234
+ assert_equal [b, c], a.eContents
1235
+ assert_equal [b, c], a.eAllContents
1123
1236
  a.removeManyChild(b)
1124
1237
  assert_nil b.eContainer
1125
1238
  assert_nil b.eContainingFeature
1239
+ assert_equal [c], a.eContents
1240
+ assert_equal [c], a.eAllContents
1126
1241
  end
1127
1242
 
1128
1243
  def test_conainer_many_bi_steal
@@ -1136,12 +1251,18 @@ class MetamodelBuilderTest < Test::Unit::TestCase
1136
1251
  assert_equal :manyChild, b.eContainingFeature
1137
1252
  assert_equal a, c.eContainer
1138
1253
  assert_equal :manyChild, c.eContainingFeature
1254
+ assert_equal [b, c], a.eContents
1255
+ assert_equal [b, c], a.eAllContents
1139
1256
  d.addManyChild(b)
1140
1257
  assert_equal d, b.eContainer
1141
1258
  assert_equal :manyChild, b.eContainingFeature
1259
+ assert_equal [c], a.eContents
1260
+ assert_equal [c], a.eAllContents
1261
+ assert_equal [b], d.eContents
1262
+ assert_equal [b], d.eAllContents
1142
1263
  end
1143
1264
 
1144
- def test_conainer_many_bi_steal_ref
1265
+ def test_conainer_many_bi_steal_rev
1145
1266
  a = mm::ContainerClass.new
1146
1267
  b = mm::ContainedClass.new
1147
1268
  c = mm::ContainedClass.new
@@ -1152,9 +1273,51 @@ class MetamodelBuilderTest < Test::Unit::TestCase
1152
1273
  assert_equal :manyChild, b.eContainingFeature
1153
1274
  assert_equal a, c.eContainer
1154
1275
  assert_equal :manyChild, c.eContainingFeature
1276
+ assert_equal [b, c], a.eContents
1277
+ assert_equal [b, c], a.eAllContents
1155
1278
  b.parentMany = d
1156
1279
  assert_equal d, b.eContainer
1157
1280
  assert_equal :manyChild, b.eContainingFeature
1281
+ assert_equal [c], a.eContents
1282
+ assert_equal [c], a.eAllContents
1283
+ assert_equal [b], d.eContents
1284
+ assert_equal [b], d.eAllContents
1285
+ end
1286
+
1287
+ def test_all_contents
1288
+ a = mm::ContainerClass.new
1289
+ b = mm::NestedContainerClass.new
1290
+ c = mm::ContainedClass.new
1291
+ a.oneChildUni = b
1292
+ b.oneChildUni = c
1293
+ assert_equal [b, c], a.eAllContents
1294
+ end
1295
+
1296
+ def test_all_contents_with_block
1297
+ a = mm::ContainerClass.new
1298
+ b = mm::NestedContainerClass.new
1299
+ c = mm::ContainedClass.new
1300
+ a.oneChildUni = b
1301
+ b.oneChildUni = c
1302
+ yielded = []
1303
+ a.eAllContents do |e|
1304
+ yielded << e
1305
+ end
1306
+ assert_equal [b, c], yielded
1307
+ end
1308
+
1309
+ def test_all_contents_prune
1310
+ a = mm::ContainerClass.new
1311
+ b = mm::NestedContainerClass.new
1312
+ c = mm::ContainedClass.new
1313
+ a.oneChildUni = b
1314
+ b.oneChildUni = c
1315
+ yielded = []
1316
+ a.eAllContents do |e|
1317
+ yielded << e
1318
+ :prune
1319
+ end
1320
+ assert_equal [b], yielded
1158
1321
  end
1159
1322
 
1160
1323
  def test_container_generic
@@ -1198,4 +1361,122 @@ class MetamodelBuilderTest < Test::Unit::TestCase
1198
1361
  assert_equal [], a.manyChildUni
1199
1362
  end
1200
1363
 
1364
+ def test_disconnectContainer_one_uni
1365
+ a = mm::ContainerClass.new
1366
+ b = mm::ContainedClass.new
1367
+ a.oneChildUni = b
1368
+ b.disconnectContainer
1369
+ assert_nil a.oneChildUni
1370
+ end
1371
+
1372
+ def test_disconnectContainer_one
1373
+ a = mm::ContainerClass.new
1374
+ b = mm::ContainedClass.new
1375
+ a.oneChild = b
1376
+ b.disconnectContainer
1377
+ assert_nil a.oneChild
1378
+ assert_nil b.parentOne
1379
+ end
1380
+
1381
+ def test_disconnectContainer_many_uni
1382
+ a = mm::ContainerClass.new
1383
+ b = mm::ContainedClass.new
1384
+ c = mm::ContainedClass.new
1385
+ a.addManyChildUni(b)
1386
+ a.addManyChildUni(c)
1387
+ b.disconnectContainer
1388
+ assert_equal [c], a.manyChildUni
1389
+ end
1390
+
1391
+ def test_disconnectContainer_many
1392
+ a = mm::ContainerClass.new
1393
+ b = mm::ContainedClass.new
1394
+ c = mm::ContainedClass.new
1395
+ a.addManyChild(b)
1396
+ a.addManyChild(c)
1397
+ b.disconnectContainer
1398
+ assert_nil b.parentMany
1399
+ assert_equal [c], a.manyChild
1400
+ end
1401
+
1402
+ # Duplicate Containment Tests
1403
+ #
1404
+ # Testing that no element is contained in two different containers at a time.
1405
+ # This must also work for uni-directional containments as well as
1406
+ # for containments via different roles.
1407
+
1408
+ # here the bi-dir reference disconnects from the previous container
1409
+ def test_duplicate_containment_bidir_samerole_one
1410
+ a1 = mm::ContainerClass.new
1411
+ a2 = mm::ContainerClass.new
1412
+ b = mm::ContainedClass.new
1413
+ a1.oneChild = b
1414
+ a2.oneChild = b
1415
+ assert_nil a1.oneChild
1416
+ end
1417
+
1418
+ # here the bi-dir reference disconnects from the previous container
1419
+ def test_duplicate_containment_bidir_samerole_many
1420
+ a1 = mm::ContainerClass.new
1421
+ a2 = mm::ContainerClass.new
1422
+ b = mm::ContainedClass.new
1423
+ a1.addManyChild(b)
1424
+ a2.addManyChild(b)
1425
+ assert_equal [], a1.manyChild
1426
+ end
1427
+
1428
+ def test_duplicate_containment_unidir_samerole_one
1429
+ a1 = mm::ContainerClass.new
1430
+ a2 = mm::ContainerClass.new
1431
+ b = mm::ContainedClass.new
1432
+ a1.oneChildUni = b
1433
+ a2.oneChildUni = b
1434
+ assert_nil a1.oneChildUni
1435
+ end
1436
+
1437
+ def test_duplicate_containment_unidir_samerole_many
1438
+ a1 = mm::ContainerClass.new
1439
+ a2 = mm::ContainerClass.new
1440
+ b = mm::ContainedClass.new
1441
+ a1.addManyChildUni(b)
1442
+ a2.addManyChildUni(b)
1443
+ assert_equal [], a1.manyChildUni
1444
+ end
1445
+
1446
+ def test_duplicate_containment_bidir_otherrole_one
1447
+ a1 = mm::ContainerClass.new
1448
+ a2 = mm::ContainerClass.new
1449
+ b = mm::ContainedClass.new
1450
+ a1.oneChild = b
1451
+ a2.oneChild2 = b
1452
+ assert_nil a1.oneChild
1453
+ end
1454
+
1455
+ def test_duplicate_containment_bidir_otherrole_many
1456
+ a1 = mm::ContainerClass.new
1457
+ a2 = mm::ContainerClass.new
1458
+ b = mm::ContainedClass.new
1459
+ a1.addManyChild(b)
1460
+ a2.addManyChild2(b)
1461
+ assert_equal [], a1.manyChild
1462
+ end
1463
+
1464
+ def test_duplicate_containment_unidir_otherrole_one
1465
+ a1 = mm::ContainerClass.new
1466
+ a2 = mm::ContainerClass.new
1467
+ b = mm::ContainedClass.new
1468
+ a1.oneChildUni = b
1469
+ a2.oneChildUni2 = b
1470
+ assert_nil a1.oneChildUni
1471
+ end
1472
+
1473
+ def test_duplicate_containment_unidir_otherrole_many
1474
+ a1 = mm::ContainerClass.new
1475
+ a2 = mm::ContainerClass.new
1476
+ b = mm::ContainedClass.new
1477
+ a1.addManyChildUni(b)
1478
+ a2.addManyChildUni2(b)
1479
+ assert_equal [], a1.manyChildUni
1480
+ end
1481
+
1201
1482
  end