rgen 0.2.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.
- data/CHANGELOG +9 -0
- data/MIT-LICENSE +20 -0
- data/README +73 -0
- data/lib/ea/xmi_class_instantiator.rb +45 -0
- data/lib/ea/xmi_helper.rb +26 -0
- data/lib/ea/xmi_metamodel.rb +19 -0
- data/lib/ea/xmi_object_instantiator.rb +42 -0
- data/lib/ea/xmi_to_classmodel.rb +78 -0
- data/lib/ea/xmi_to_objectmodel.rb +89 -0
- data/lib/mmgen/metamodel_generator.rb +19 -0
- data/lib/mmgen/mm_ext/uml_classmodel_ext.rb +71 -0
- data/lib/mmgen/mmgen.rb +21 -0
- data/lib/mmgen/templates/uml_classmodel.tpl +63 -0
- data/lib/rgen/array_extensions.rb +23 -0
- data/lib/rgen/auto_class_creator.rb +56 -0
- data/lib/rgen/environment.rb +57 -0
- data/lib/rgen/metamodel_builder.rb +102 -0
- data/lib/rgen/metamodel_builder/build_helper.rb +29 -0
- data/lib/rgen/metamodel_builder/builder_extensions.rb +191 -0
- data/lib/rgen/metamodel_builder/builder_runtime.rb +67 -0
- data/lib/rgen/name_helper.rb +18 -0
- data/lib/rgen/template_language.rb +169 -0
- data/lib/rgen/template_language/directory_template_container.rb +51 -0
- data/lib/rgen/template_language/output_handler.rb +84 -0
- data/lib/rgen/template_language/template_container.rb +153 -0
- data/lib/rgen/template_language/template_helper.rb +26 -0
- data/lib/rgen/transformer.rb +316 -0
- data/lib/rgen/xml_instantiator/dependency_resolver.rb +23 -0
- data/lib/rgen/xml_instantiator/xml_instantiator.rb +78 -0
- data/lib/rgen/xml_instantiator/xml_parser.rb +39 -0
- data/lib/uml/objectmodel_instantiator.rb +53 -0
- data/lib/uml/uml_classmodel.rb +92 -0
- data/lib/uml/uml_objectmodel.rb +65 -0
- data/test/array_extensions_test.rb +54 -0
- data/test/environment_test.rb +47 -0
- data/test/metamodel_builder_test.rb +175 -0
- data/test/metamodel_generator_test.rb +45 -0
- data/test/metamodel_generator_test/TestModel.rb +40 -0
- data/test/metamodel_generator_test/expected_result.txt +40 -0
- data/test/output_handler_test.rb +40 -0
- data/test/rgen_test.rb +13 -0
- data/test/template_language_test.rb +46 -0
- data/test/template_language_test/expected_result.txt +10 -0
- data/test/template_language_test/templates/content/chapter.tpl +5 -0
- data/test/template_language_test/templates/index/c/cmod.tpl +1 -0
- data/test/template_language_test/templates/index/chapter.tpl +3 -0
- data/test/template_language_test/templates/root.tpl +22 -0
- data/test/template_language_test/testout.txt +10 -0
- data/test/transformer_test.rb +176 -0
- data/test/xmi_class_instantiator_test.rb +107 -0
- data/test/xmi_instantiator_test/testmodel.eap +0 -0
- data/test/xmi_instantiator_test/testmodel.xml +962 -0
- data/test/xmi_object_instantiator_test.rb +65 -0
- metadata +117 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
module ObjectmodelInstantiator
|
2
|
+
|
3
|
+
def instantiateObjectModel(env_in, env_out, metamodel)
|
4
|
+
objectMap = {}
|
5
|
+
env_in.find(:class => UMLObjectModel::UMLObject).each do |o_in|
|
6
|
+
o_out = env_out.new metamodel.const_get(o_in.classname)
|
7
|
+
objectMap[o_in] = o_out
|
8
|
+
o_out.name = o_in.name
|
9
|
+
o_in.attributeSettings.each { |as|
|
10
|
+
conversions = ["to_s", "to_i", "to_f"]
|
11
|
+
conv = conversions.first
|
12
|
+
begin
|
13
|
+
o_out.send(as.name+"=",as.value.send(conv))
|
14
|
+
rescue StandardError
|
15
|
+
conv = conversions[conversions.index(conv)+1]
|
16
|
+
retry if conv
|
17
|
+
raise
|
18
|
+
end
|
19
|
+
}
|
20
|
+
end
|
21
|
+
env_in.find(:class => UMLObjectModel::UMLAssociation).each do |a_in|
|
22
|
+
begin
|
23
|
+
if a_in.roleA
|
24
|
+
begin
|
25
|
+
o_out = objectMap[a_in.objectB]
|
26
|
+
es = o_out.send(a_in.roleA)
|
27
|
+
rescue NoMethodError
|
28
|
+
raise StandardError.new("In #{o_out.class.name}(#{o_out.name}): method not found #{a_in.roleA}")
|
29
|
+
end
|
30
|
+
if es.is_a? RGen::MetamodelBuilder::ElementSet
|
31
|
+
es << objectMap[a_in.objectA]
|
32
|
+
else
|
33
|
+
objectMap[a_in.objectB].send(a_in.roleA+"=", objectMap[a_in.objectA])
|
34
|
+
end
|
35
|
+
elsif a_in.roleB
|
36
|
+
begin
|
37
|
+
o_out = objectMap[a_in.objectA]
|
38
|
+
es = o_out.send(a_in.roleB)
|
39
|
+
rescue NoMethodError
|
40
|
+
raise StandardError.new("In #{o_out.class.name}(#{o_out.name}): method not found #{a_in.roleB}")
|
41
|
+
end
|
42
|
+
if es.is_a? RGen::MetamodelBuilder::ElementSet
|
43
|
+
es << objectMap[a_in.objectB]
|
44
|
+
else
|
45
|
+
objectMap[a_in.objectA].send(a_in.roleB+"=", objectMap[a_in.objectB])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
rescue StandardError => e
|
49
|
+
puts e.message
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'rgen/metamodel_builder'
|
2
|
+
|
3
|
+
module UMLClassModel
|
4
|
+
|
5
|
+
include RGen::MetamodelBuilder
|
6
|
+
|
7
|
+
class UMLPackage < MMBase
|
8
|
+
has_one 'name', String
|
9
|
+
def allClasses
|
10
|
+
subpackages.inject(classes) {|r,p| r.concat(p.allClasses) }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class UMLClass < MMBase
|
15
|
+
has_one 'name', String
|
16
|
+
has_many 'stereotypes', String
|
17
|
+
def remoteNavigableEnds
|
18
|
+
assocEnds.otherEnd.select{|e| e.navigable}
|
19
|
+
end
|
20
|
+
def localNavigableEnds
|
21
|
+
assocEnds.select{|e| e.navigable}
|
22
|
+
end
|
23
|
+
def localCompositeEnds
|
24
|
+
assocEnds.select{|e| e.composite}
|
25
|
+
end
|
26
|
+
def remoteCompositeEnds
|
27
|
+
assocEnds.otherEnd.select{|e| e.composite}
|
28
|
+
# put constraint check here and return the container directly ?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class UMLOperation < MMBase
|
33
|
+
has_one 'name', String
|
34
|
+
end
|
35
|
+
|
36
|
+
class UMLAttribute < MMBase
|
37
|
+
has_one 'name', String
|
38
|
+
has_one 'type', String
|
39
|
+
end
|
40
|
+
|
41
|
+
class UMLTaggedValue < MMBase
|
42
|
+
has_one 'tag'
|
43
|
+
has_one 'value'
|
44
|
+
end
|
45
|
+
|
46
|
+
class UMLAssociation < MMBase
|
47
|
+
end
|
48
|
+
|
49
|
+
class UMLAggregation < UMLAssociation
|
50
|
+
end
|
51
|
+
|
52
|
+
class UMLAssociationEnd < MMBase
|
53
|
+
has_one 'multiplicity', String
|
54
|
+
has_one 'navigable' # boolean
|
55
|
+
has_one 'composite' # boolean
|
56
|
+
has_one 'role', String
|
57
|
+
def assoc
|
58
|
+
assocA || assocB
|
59
|
+
end
|
60
|
+
def otherEnd
|
61
|
+
return unless assoc
|
62
|
+
assoc.endA == self ? assoc.endB : assoc.endA
|
63
|
+
end
|
64
|
+
def lowerMult
|
65
|
+
return unless multiplicity
|
66
|
+
stringToMult(multiplicity.split("..")[0])
|
67
|
+
end
|
68
|
+
def upperMult
|
69
|
+
return unless multiplicity
|
70
|
+
ma = multiplicity.split("..")
|
71
|
+
stringToMult(ma[1] || ma[0])
|
72
|
+
end
|
73
|
+
private
|
74
|
+
def stringToMult(s)
|
75
|
+
return :many if s == "*"
|
76
|
+
return s.to_i
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
UMLPackage.one_to_many 'subpackages', UMLPackage, 'superpackage'
|
81
|
+
UMLPackage.one_to_many 'classes', UMLClass, 'package'
|
82
|
+
|
83
|
+
UMLClass.many_to_many 'superclasses', UMLClass, 'subclasses'
|
84
|
+
UMLClass.one_to_many 'assocEnds', UMLAssociationEnd, 'clazz'
|
85
|
+
UMLClass.one_to_many 'attributes', UMLAttribute, 'clazz'
|
86
|
+
UMLClass.one_to_many 'operations', UMLOperation, 'clazz'
|
87
|
+
UMLClass.one_to_many 'taggedvalues', UMLTaggedValue, 'clazz'
|
88
|
+
|
89
|
+
UMLAssociation.one_to_one 'endA', UMLAssociationEnd, 'assocA'
|
90
|
+
UMLAssociation.one_to_one 'endB', UMLAssociationEnd, 'assocB'
|
91
|
+
|
92
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'rgen/metamodel_builder'
|
2
|
+
|
3
|
+
module UMLObjectModel
|
4
|
+
|
5
|
+
include RGen::MetamodelBuilder
|
6
|
+
|
7
|
+
class UMLPackage < MMBase
|
8
|
+
has_one 'name', String
|
9
|
+
def allObjects
|
10
|
+
subpackages.inject(objects) {|r,p| r.concat(p.allObjects) }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class UMLObject < MMBase
|
15
|
+
has_one 'name', String
|
16
|
+
has_one 'classname', String
|
17
|
+
def remoteNavigableEnds
|
18
|
+
assocEnds.otherEnd.select{|e| e.navigable}
|
19
|
+
end
|
20
|
+
def localNavigableEnds
|
21
|
+
assocEnds.select{|e| e.navigable}
|
22
|
+
end
|
23
|
+
def localCompositeEnds
|
24
|
+
assocEnds.select{|e| e.composite}
|
25
|
+
end
|
26
|
+
def remoteCompositeEnds
|
27
|
+
assocEnds.otherEnd.select{|e| e.composite}
|
28
|
+
# put constraint check here and return the container directly ?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class UMLAttributeSetting < MMBase
|
33
|
+
has_one 'name', String
|
34
|
+
has_one 'value', String
|
35
|
+
end
|
36
|
+
|
37
|
+
class UMLAssociation < MMBase
|
38
|
+
end
|
39
|
+
|
40
|
+
class UMLAggregation < UMLAssociation
|
41
|
+
end
|
42
|
+
|
43
|
+
class UMLAssociationEnd < MMBase
|
44
|
+
has_one 'navigable' # boolean
|
45
|
+
has_one 'composite' # boolean
|
46
|
+
has_one 'role', String
|
47
|
+
def assoc
|
48
|
+
assocA || assocB
|
49
|
+
end
|
50
|
+
def otherEnd
|
51
|
+
return unless assoc
|
52
|
+
assoc.endA == self ? assoc.endB : assoc.endA
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
UMLPackage.one_to_many 'subpackages', UMLPackage, 'superpackage'
|
57
|
+
UMLPackage.one_to_many 'objects', UMLObject, 'package'
|
58
|
+
|
59
|
+
UMLObject.one_to_many 'assocEnds', UMLAssociationEnd, 'object'
|
60
|
+
UMLObject.one_to_many 'attributeSettings', UMLAttributeSetting, 'object'
|
61
|
+
|
62
|
+
UMLAssociation.one_to_one 'endA', UMLAssociationEnd, 'assocA'
|
63
|
+
UMLAssociation.one_to_one 'endB', UMLAssociationEnd, 'assocB'
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),"..","lib")
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rgen/array_extensions'
|
5
|
+
|
6
|
+
class ArrayExtensionsTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def test_element_methods
|
9
|
+
c = Struct.new("SomeClass",:name,:age)
|
10
|
+
a = []
|
11
|
+
a << c.new('MyName',33)
|
12
|
+
a << c.new('YourName',22)
|
13
|
+
assert_equal ["MyName", "YourName"], a >> :name
|
14
|
+
assert_raise NoMethodError do
|
15
|
+
a.name
|
16
|
+
end
|
17
|
+
assert_equal [33, 22], a>>:age
|
18
|
+
assert_raise NoMethodError do
|
19
|
+
a.age
|
20
|
+
end
|
21
|
+
# unfortunately, any method can be called on an empty array
|
22
|
+
assert_equal [], [].age
|
23
|
+
end
|
24
|
+
|
25
|
+
class MMBaseClass < RGen::MetamodelBuilder::MMBase
|
26
|
+
has_one 'name'
|
27
|
+
has_one 'age'
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_with_mmbase
|
31
|
+
e1 = MMBaseClass.new
|
32
|
+
e1.name = "MyName"
|
33
|
+
e1.age = 33
|
34
|
+
e2 = MMBaseClass.new
|
35
|
+
e2.name = "YourName"
|
36
|
+
e2.age = 22
|
37
|
+
a = [e1, e2]
|
38
|
+
assert_equal ["MyName", "YourName"], a >> :name
|
39
|
+
assert_equal ["MyName", "YourName"], a.name
|
40
|
+
assert_equal [33, 22], a>>:age
|
41
|
+
assert_equal [33, 22], a.age
|
42
|
+
# put something into the array that is not an MMBase
|
43
|
+
a << "not a MMBase"
|
44
|
+
# the dot operator will tell that there is something not a MMBase
|
45
|
+
assert_raise StandardError do
|
46
|
+
a.age
|
47
|
+
end
|
48
|
+
# the >> operator will try to call the method anyway
|
49
|
+
assert_raise NoMethodError do
|
50
|
+
a >> :age
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),"..","lib")
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rgen/environment'
|
5
|
+
|
6
|
+
class EnvironmentTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
class Model
|
9
|
+
attr_accessor :name
|
10
|
+
end
|
11
|
+
|
12
|
+
class ModelSub < Model
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_find
|
16
|
+
m1 = Model.new
|
17
|
+
m1.name = "M1"
|
18
|
+
m2 = ModelSub.new
|
19
|
+
m2.name = "M2"
|
20
|
+
m3 = "justAString"
|
21
|
+
env_in = RGen::Environment.new << m1 << m2 << m3
|
22
|
+
|
23
|
+
result = env_in.find(:class => Model, :name => "M1")
|
24
|
+
assert result.is_a?(Array)
|
25
|
+
assert_equal 1, result.size
|
26
|
+
assert_equal m1, result.first
|
27
|
+
|
28
|
+
result = env_in.find(:class => Model)
|
29
|
+
assert result.is_a?(Array)
|
30
|
+
assert_equal 2, result.size
|
31
|
+
assert_equal m1, result[0]
|
32
|
+
assert_equal m2, result[1]
|
33
|
+
|
34
|
+
result = env_in.find(:name => "M2")
|
35
|
+
assert result.is_a?(Array)
|
36
|
+
assert_equal 1, result.size
|
37
|
+
assert_equal m2, result[0]
|
38
|
+
|
39
|
+
result = env_in.find(:class => [Model, String])
|
40
|
+
assert result.is_a?(Array)
|
41
|
+
assert_equal 3, result.size
|
42
|
+
assert_equal m1, result[0]
|
43
|
+
assert_equal m2, result[1]
|
44
|
+
assert_equal m3, result[2]
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),"..","lib")
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rgen/metamodel_builder'
|
5
|
+
|
6
|
+
class MetamodelBuilderTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
class HasOneTestClass < RGen::MetamodelBuilder::MMBase
|
9
|
+
has_one 'name'
|
10
|
+
has_one 'an_array', Array
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_has_one
|
14
|
+
sc = HasOneTestClass.new
|
15
|
+
assert_respond_to sc, :name
|
16
|
+
assert_respond_to sc, :name=
|
17
|
+
sc.name = 'SomeName'
|
18
|
+
assert_equal 'SomeName', sc.name
|
19
|
+
sc.name = nil
|
20
|
+
assert_equal nil, sc.name
|
21
|
+
|
22
|
+
assert_respond_to sc, :an_array
|
23
|
+
assert_respond_to sc, :an_array=
|
24
|
+
aa = Array.new
|
25
|
+
sc.an_array = aa
|
26
|
+
assert_equal aa, sc.an_array
|
27
|
+
|
28
|
+
assert_raise StandardError do
|
29
|
+
sc.an_array = "a string"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class HasManyTestClass < RGen::MetamodelBuilder::MMBase
|
34
|
+
has_many 'string', String
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_has_many
|
38
|
+
o = HasManyTestClass.new
|
39
|
+
o.addString("s1")
|
40
|
+
o.addString("s2")
|
41
|
+
assert_equal ["s1","s2"], o.string
|
42
|
+
# make sure we get a copy
|
43
|
+
o.string.clear
|
44
|
+
assert_equal ["s1","s2"], o.string
|
45
|
+
o.removeString("s3")
|
46
|
+
assert_equal ["s1","s2"], o.string
|
47
|
+
o.removeString("s2")
|
48
|
+
assert_equal ["s1"], o.string
|
49
|
+
assert_raise StandardError do
|
50
|
+
o.addString(:notastring)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class OneClass < RGen::MetamodelBuilder::MMBase
|
55
|
+
end
|
56
|
+
class ManyClass < RGen::MetamodelBuilder::MMBase
|
57
|
+
end
|
58
|
+
OneClass.one_to_many 'manyClasses', ManyClass, 'oneClass'
|
59
|
+
|
60
|
+
def test_one_to_many
|
61
|
+
oc = OneClass.new
|
62
|
+
assert_respond_to oc, :manyClasses
|
63
|
+
assert oc.manyClasses.empty?
|
64
|
+
|
65
|
+
mc = ManyClass.new
|
66
|
+
assert_respond_to mc, :oneClass
|
67
|
+
assert_respond_to mc, :oneClass=
|
68
|
+
assert_nil mc.oneClass
|
69
|
+
|
70
|
+
# put the OneClass into the ManyClass
|
71
|
+
mc.oneClass = oc
|
72
|
+
assert_equal oc, mc.oneClass
|
73
|
+
assert oc.manyClasses.include?(mc)
|
74
|
+
|
75
|
+
# remove the OneClass from the ManyClass
|
76
|
+
mc.oneClass = nil
|
77
|
+
assert_equal nil, mc.oneClass
|
78
|
+
assert !oc.manyClasses.include?(mc)
|
79
|
+
|
80
|
+
# put the ManyClass into the OneClass
|
81
|
+
oc.addManyClasses mc
|
82
|
+
assert oc.manyClasses.include?(mc)
|
83
|
+
assert_equal oc, mc.oneClass
|
84
|
+
|
85
|
+
# remove the ManyClass from the OneClass
|
86
|
+
oc.removeManyClasses mc
|
87
|
+
assert !oc.manyClasses.include?(mc)
|
88
|
+
assert_equal nil, mc.oneClass
|
89
|
+
end
|
90
|
+
|
91
|
+
class AClassOO < RGen::MetamodelBuilder::MMBase
|
92
|
+
end
|
93
|
+
class BClassOO < RGen::MetamodelBuilder::MMBase
|
94
|
+
end
|
95
|
+
AClassOO.one_to_one 'bClass', BClassOO, 'aClass'
|
96
|
+
|
97
|
+
def test_one_to_one
|
98
|
+
ac = AClassOO.new
|
99
|
+
assert_respond_to ac, :bClass
|
100
|
+
assert_respond_to ac, :bClass=
|
101
|
+
assert_nil ac.bClass
|
102
|
+
|
103
|
+
bc = BClassOO.new
|
104
|
+
assert_respond_to bc, :aClass
|
105
|
+
assert_respond_to bc, :aClass=
|
106
|
+
assert_nil bc.aClass
|
107
|
+
|
108
|
+
# put the AClass into the BClass
|
109
|
+
bc.aClass = ac
|
110
|
+
assert_equal ac, bc.aClass
|
111
|
+
assert_equal bc, ac.bClass
|
112
|
+
|
113
|
+
# remove the AClass from the BClass
|
114
|
+
bc.aClass = nil
|
115
|
+
assert_equal nil, bc.aClass
|
116
|
+
assert_equal nil, ac.bClass
|
117
|
+
|
118
|
+
# put the BClass into the AClass
|
119
|
+
ac.bClass = bc
|
120
|
+
assert_equal bc, ac.bClass
|
121
|
+
assert_equal ac, bc.aClass
|
122
|
+
|
123
|
+
# remove the BClass from the AClass
|
124
|
+
ac.bClass = nil
|
125
|
+
assert_equal nil, ac.bClass
|
126
|
+
assert_equal nil, bc.aClass
|
127
|
+
end
|
128
|
+
|
129
|
+
class AClassMM < RGen::MetamodelBuilder::MMBase
|
130
|
+
end
|
131
|
+
class BClassMM < RGen::MetamodelBuilder::MMBase
|
132
|
+
end
|
133
|
+
AClassMM.many_to_many 'bClasses', BClassMM, 'aClasses'
|
134
|
+
|
135
|
+
def test_many_to_many
|
136
|
+
|
137
|
+
ac = AClassMM.new
|
138
|
+
assert_respond_to ac, :bClasses
|
139
|
+
assert ac.bClasses.empty?
|
140
|
+
|
141
|
+
bc = BClassMM.new
|
142
|
+
assert_respond_to bc, :aClasses
|
143
|
+
assert bc.aClasses.empty?
|
144
|
+
|
145
|
+
# put the AClass into the BClass
|
146
|
+
bc.addAClasses ac
|
147
|
+
assert bc.aClasses.include?(ac)
|
148
|
+
assert ac.bClasses.include?(bc)
|
149
|
+
|
150
|
+
# put something else into the BClass
|
151
|
+
assert_raise StandardError do
|
152
|
+
bc.addAClasses :notaaclass
|
153
|
+
end
|
154
|
+
|
155
|
+
# remove the AClass from the BClass
|
156
|
+
bc.removeAClasses ac
|
157
|
+
assert !bc.aClasses.include?(ac)
|
158
|
+
assert !ac.bClasses.include?(bc)
|
159
|
+
|
160
|
+
# put the BClass into the AClass
|
161
|
+
ac.addBClasses bc
|
162
|
+
assert ac.bClasses.include?(bc)
|
163
|
+
assert bc.aClasses.include?(ac)
|
164
|
+
|
165
|
+
# put something else into the AClass
|
166
|
+
assert_raise StandardError do
|
167
|
+
ac.addBClasses :notabclass
|
168
|
+
end
|
169
|
+
|
170
|
+
# remove the BClass from the AClass
|
171
|
+
ac.removeBClasses bc
|
172
|
+
assert !ac.bClasses.include?(bc)
|
173
|
+
assert !bc.aClasses.include?(ac)
|
174
|
+
end
|
175
|
+
end
|