rtext 0.4.0 → 0.5.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.
Files changed (48) hide show
  1. data/CHANGELOG +20 -0
  2. data/{README → README.rdoc} +5 -1
  3. data/RText_Protocol +444 -0
  4. data/Rakefile +10 -10
  5. data/lib/rtext/completer.rb +32 -26
  6. data/lib/rtext/context_builder.rb +113 -59
  7. data/lib/rtext/default_loader.rb +73 -8
  8. data/lib/rtext/default_service_provider.rb +30 -14
  9. data/lib/rtext/frontend/config.rb +58 -0
  10. data/lib/rtext/frontend/connector.rb +233 -0
  11. data/lib/rtext/frontend/connector_manager.rb +81 -0
  12. data/lib/rtext/frontend/context.rb +56 -0
  13. data/lib/rtext/generic.rb +13 -0
  14. data/lib/rtext/instantiator.rb +30 -7
  15. data/lib/rtext/language.rb +54 -27
  16. data/lib/rtext/link_detector.rb +57 -0
  17. data/lib/rtext/message_helper.rb +77 -0
  18. data/lib/rtext/parser.rb +19 -68
  19. data/lib/rtext/serializer.rb +18 -3
  20. data/lib/rtext/service.rb +182 -118
  21. data/lib/rtext/tokenizer.rb +102 -0
  22. data/test/completer_test.rb +327 -70
  23. data/test/context_builder_test.rb +671 -91
  24. data/test/instantiator_test.rb +153 -0
  25. data/test/integration/backend.out +10 -0
  26. data/test/integration/crash_on_request_editor.rb +12 -0
  27. data/test/integration/ecore_editor.rb +50 -0
  28. data/test/integration/frontend.log +25138 -0
  29. data/test/integration/model/invalid_encoding.invenc +2 -0
  30. data/test/integration/model/test.crash_on_request +18 -0
  31. data/test/integration/model/test.crashing_backend +18 -0
  32. data/test/integration/model/test.dont_open_socket +0 -0
  33. data/test/integration/model/test.invalid_cmd_line +0 -0
  34. data/test/integration/model/test.not_in_rtext +0 -0
  35. data/test/integration/model/test_large_with_errors.ect3 +43523 -0
  36. data/test/integration/model/test_metamodel.ect +18 -0
  37. data/test/integration/model/test_metamodel2.ect +5 -0
  38. data/test/integration/model/test_metamodel_error.ect2 +3 -0
  39. data/test/integration/model/test_metamodel_ok.ect2 +18 -0
  40. data/test/integration/test.rb +684 -0
  41. data/test/link_detector_test.rb +276 -0
  42. data/test/message_helper_test.rb +118 -0
  43. data/test/rtext_test.rb +4 -1
  44. data/test/serializer_test.rb +96 -1
  45. data/test/tokenizer_test.rb +125 -0
  46. metadata +36 -10
  47. data/RText_Plugin_Implementation_Guide +0 -268
  48. data/lib/rtext_plugin/connection_manager.rb +0 -59
@@ -0,0 +1,276 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),"..","lib")
2
+
3
+ require 'test/unit'
4
+ require 'rgen/metamodel_builder'
5
+ require 'rtext/language'
6
+ require 'rtext/link_detector'
7
+
8
+ class LinkDetectorTest < Test::Unit::TestCase
9
+
10
+ module TestMM
11
+ extend RGen::MetamodelBuilder::ModuleExtension
12
+ class TestNode2 < RGen::MetamodelBuilder::MMBase
13
+ has_attr 'name', String
14
+ end
15
+ class TestNode < RGen::MetamodelBuilder::MMBase
16
+ has_attr 'name', String
17
+ has_attr 'id', Integer
18
+ has_one 'related', TestNode
19
+ has_many 'others', TestNode
20
+ contains_many 'children', TestNode2, 'parent'
21
+ end
22
+ end
23
+
24
+ def test_before_command
25
+ ld = build_link_desc TestMM, <<-END
26
+ |TestNode SomeNode, id: 1234, related: /Other/Node, others: [/NodeA, /Node/B]
27
+ END
28
+ assert_link_desc ld, :element => "TestNode", :feature => nil, :backward => true, :value => "TestNode", :scol => 1, :ecol => 8
29
+ end
30
+
31
+ def test_in_command
32
+ ld = build_link_desc TestMM, <<-END
33
+ Test|Node SomeNode, id: 1234, related: /Other/Node, others: [/NodeA, /Node/B]
34
+ END
35
+ assert_link_desc ld, :element => "TestNode", :feature => nil, :backward => true, :value => "TestNode", :scol => 1, :ecol => 8
36
+ end
37
+
38
+ def test_end_of_command
39
+ ld = build_link_desc TestMM, <<-END
40
+ TestNod|e SomeNode, id: 1234, related: /Other/Node, others: [/NodeA, /Node/B]
41
+ END
42
+ assert_link_desc ld, :element => "TestNode", :feature => nil, :backward => true, :value => "TestNode", :scol => 1, :ecol => 8
43
+ end
44
+
45
+ def test_after_command
46
+ ld = build_link_desc TestMM, <<-END
47
+ TestNode| SomeNode, id: 1234, related: /Other/Node, others: [/NodeA, /Node/B]
48
+ END
49
+ assert_nil ld
50
+ end
51
+
52
+ def test_in_name
53
+ ld = build_link_desc TestMM, <<-END
54
+ TestNode So|meNode, id: 1234, related: /Other/Node, others: [/NodeA, /Node/B]
55
+ END
56
+ assert_link_desc ld, :element => "TestNode", :feature => "name", :index => 0, :backward => false, :value => "SomeNode", :scol => 10, :ecol => 17
57
+ end
58
+
59
+ def test_in_name_with_quotes
60
+ ld = build_link_desc TestMM, <<-END
61
+ TestNode "So|meNode", id: 1234, related: /Other/Node, others: [/NodeA, /Node/B]
62
+ END
63
+ assert_link_desc ld, :element => "TestNode", :feature => "name", :index => 0, :backward => false, :value => "SomeNode", :scol => 10, :ecol => 19
64
+ end
65
+
66
+ def test_after_comma
67
+ ld = build_link_desc TestMM, <<-END
68
+ TestNode SomeNode,| id: 1234, related: /Other/Node, others: [/NodeA, /Node/B]
69
+ END
70
+ assert_nil ld
71
+ end
72
+
73
+ def test_after_label
74
+ ld = build_link_desc TestMM, <<-END
75
+ TestNode SomeNode, id:| 1234, related: /Other/Node, others: [/NodeA, /Node/B]
76
+ END
77
+ assert_nil ld
78
+ end
79
+
80
+ def test_beginning_of_labled_argument
81
+ ld = build_link_desc TestMM, <<-END
82
+ TestNode SomeNode, id: |1234, related: /Other/Node, others: [/NodeA, /Node/B]
83
+ END
84
+ assert_link_desc ld, :element => "TestNode", :feature => "id", :index => 0, :backward => false, :value => 1234, :scol => 24, :ecol => 27
85
+ end
86
+
87
+ def test_in_labled_argument
88
+ ld = build_link_desc TestMM, <<-END
89
+ TestNode SomeNode, id: 123|4, related: /Other/Node, others: [/NodeA, /Node/B]
90
+ END
91
+ assert_link_desc ld, :element => "TestNode", :feature => "id", :index => 0, :backward => false, :value => 1234, :scol => 24, :ecol => 27
92
+ end
93
+
94
+ def test_after_labled_argument
95
+ ld = build_link_desc TestMM, <<-END
96
+ TestNode SomeNode, id: 1234|, related: /Other/Node, others: [/NodeA, /Node/B]
97
+ END
98
+ assert_nil ld
99
+ end
100
+
101
+ def test_in_label
102
+ ld = build_link_desc TestMM, <<-END
103
+ TestNode SomeNode, id: 1234, re|lated: /Other/Node, others: [/NodeA, /Node/B]
104
+ END
105
+ assert_nil ld
106
+ end
107
+
108
+ def test_in_reference
109
+ ld = build_link_desc TestMM, <<-END
110
+ TestNode SomeNode, id: 1234, related: /O|ther/Node, others: [/NodeA, /Node/B]
111
+ END
112
+ assert_link_desc ld, :element => "TestNode", :feature => "related", :index => 0, :backward => false, :value => "/Other/Node", :scol => 39, :ecol => 49
113
+ end
114
+
115
+ def test_before_array
116
+ ld = build_link_desc TestMM, <<-END
117
+ TestNode SomeNode, id: 1234, related: /Other/Node, others: |[/NodeA, /Node/B]
118
+ END
119
+ assert_nil ld
120
+ end
121
+
122
+ def test_ref_in_array
123
+ ld = build_link_desc TestMM, <<-END
124
+ TestNode SomeNode, id: 1234, related: /Other/Node, others: [|/NodeA, /Node/B]
125
+ END
126
+ assert_link_desc ld, :element => "TestNode", :feature => "others", :index => 0, :backward => false, :value => "/NodeA", :scol => 61, :ecol => 66
127
+ end
128
+
129
+ def test_second_ref_in_array
130
+ ld = build_link_desc TestMM, <<-END
131
+ TestNode SomeNode, id: 1234, related: /Other/Node, others: [/NodeA, /Node/|B]
132
+ END
133
+ assert_link_desc ld, :element => "TestNode", :feature => "others", :index => 1, :backward => false, :value => "/Node/B", :scol => 69, :ecol => 75
134
+ end
135
+
136
+ def test_backward_ref_name_in_command
137
+ ld = build_link_desc(TestMM, {:backward_ref => "name"}, <<-END
138
+ |TestNode SomeNode, id: 1234, related: /Other/Node, others: [/NodeA, /Node/B]
139
+ END
140
+ )
141
+ assert_link_desc ld, :element => "TestNode", :feature => nil, :backward => false, :value => "TestNode", :scol => 1, :ecol => 8
142
+ end
143
+
144
+ def test_backward_ref_name_in_name
145
+ ld = build_link_desc(TestMM, {:backward_ref => "name"}, <<-END
146
+ TestNode Som|eNode, id: 1234, related: /Other/Node, others: [/NodeA, /Node/B]
147
+ END
148
+ )
149
+ assert_link_desc ld, :element => "TestNode", :feature => "name", :index => 0, :backward => true, :value => "SomeNode", :scol => 10, :ecol => 17
150
+ end
151
+
152
+ def test_backward_ref_name_with_quotes
153
+ ld = build_link_desc(TestMM, {:backward_ref => "name"}, <<-END
154
+ TestNode "Som|eNode", id: 1234, related: /Other/Node, others: [/NodeA, /Node/B]
155
+ END
156
+ )
157
+ assert_link_desc ld, :element => "TestNode", :feature => "name", :index => 0, :backward => true, :value => "SomeNode", :scol => 10, :ecol => 19
158
+ end
159
+
160
+ def test_backward_ref_id_in_id
161
+ ld = build_link_desc(TestMM, {:backward_ref => "id"}, <<-END
162
+ TestNode SomeNode, id: |1234, related: /Other/Node, others: [/NodeA, /Node/B]
163
+ END
164
+ )
165
+ assert_link_desc ld, :element => "TestNode", :feature => "id", :index => 0, :backward => true, :value => 1234, :scol => 24, :ecol => 27
166
+ end
167
+
168
+ def test_command_only
169
+ ld = build_link_desc(TestMM, <<-END
170
+ Tes|tNode
171
+ END
172
+ )
173
+ assert_link_desc ld, :element => "TestNode", :feature => nil, :backward => true, :value => "TestNode", :scol => 1, :ecol => 8
174
+ end
175
+
176
+ def test_command_and_name_only
177
+ ld = build_link_desc(TestMM, <<-END
178
+ TestNode |SomeNode
179
+ END
180
+ )
181
+ assert_link_desc ld, :element => "TestNode", :feature => "name", :index => 0, :backward => false, :value => "SomeNode", :scol => 10, :ecol => 17
182
+ end
183
+
184
+ def test_command_and_name_only_backward_ref_name
185
+ ld = build_link_desc(TestMM, {:backward_ref => "name"}, <<-END
186
+ TestNode |SomeNode
187
+ END
188
+ )
189
+ assert_link_desc ld, :element => "TestNode", :feature => "name", :index => 0, :backward => true, :value => "SomeNode", :scol => 10, :ecol => 17
190
+ end
191
+
192
+ def test_child_within_command
193
+ ld = build_link_desc(TestMM, {:backward_ref => "name"}, <<-END
194
+ TestNode SomeNode {
195
+ Test|Node2 SomeOtherNode
196
+ END
197
+ )
198
+ assert_link_desc ld, :element => "TestNode2", :feature => nil, :backward => false, :value => "TestNode2", :scol => 3, :ecol => 11
199
+ end
200
+
201
+ def test_child_with_label_after_command
202
+ ld = build_link_desc(TestMM, {:backward_ref => "name"}, <<-END
203
+ TestNode SomeNode {
204
+ children:
205
+ TestNode2 |SomeOtherNode
206
+ END
207
+ )
208
+ assert_link_desc ld, :element => "TestNode2", :feature => "name", :index => 0, :backward => true, :value => "SomeOtherNode", :scol => 15, :ecol => 27
209
+ end
210
+
211
+ def test_child_with_label_within_command
212
+ ld = build_link_desc(TestMM, {:backward_ref => "name"}, <<-END
213
+ TestNode SomeNode {
214
+ children:
215
+ Test|Node2 SomeOtherNode
216
+ END
217
+ )
218
+ assert_link_desc ld, :element => "TestNode2", :feature => nil, :backward => false, :value => "TestNode2", :scol => 5, :ecol => 13
219
+ end
220
+
221
+ def test_child_with_label_within_command_square_brackets
222
+ ld = build_link_desc(TestMM, {:backward_ref => "name"}, <<-END
223
+ TestNode SomeNode {
224
+ children: [
225
+ Test|Node2 SomeOtherNode
226
+ END
227
+ )
228
+ assert_link_desc ld, :element => "TestNode2", :feature => nil, :backward => false, :value => "TestNode2", :scol => 5, :ecol => 13
229
+ end
230
+
231
+ def build_link_desc(mm, text, text2=nil)
232
+ if text.is_a?(Hash)
233
+ options = text
234
+ context_lines = text2.split("\n")
235
+ else
236
+ options = {}
237
+ context_lines = text.split("\n")
238
+ end
239
+ pos_in_line = context_lines.last.index("|")+1
240
+ context_lines.last.sub!("|", "")
241
+ lang = RText::Language.new(mm.ecore,
242
+ :unlabled_arguments => proc {|c| ["name"]},
243
+ :backward_ref_attribute => proc {|c|
244
+ if options[:backward_ref]
245
+ options[:backward_ref]
246
+ else
247
+ nil
248
+ end
249
+ })
250
+ RText::LinkDetector.new(lang).detect(context_lines, pos_in_line)
251
+ end
252
+
253
+ def assert_link_desc(ld, options)
254
+ if options[:element]
255
+ assert_equal options[:element], ld.element.class.ecore.name
256
+ else
257
+ assert_nil ld.element
258
+ end
259
+ if options[:feature]
260
+ assert_equal options[:feature], ld.feature.name
261
+ else
262
+ assert_nil ld.feature
263
+ end
264
+ if options[:index]
265
+ assert_equal options[:index], ld.index
266
+ else
267
+ assert_nil ld.index
268
+ end
269
+ assert_equal options[:backward], ld.backward
270
+ assert_equal options[:value], ld.value
271
+ assert_equal options[:scol], ld.scol
272
+ assert_equal options[:ecol], ld.ecol
273
+ end
274
+
275
+ end
276
+
@@ -0,0 +1,118 @@
1
+ $:.unshift File.join(File.dirname(__FILE__),"..","lib")
2
+
3
+ require 'test/unit'
4
+ require 'rtext/message_helper'
5
+
6
+ class MessageHelperTest < Test::Unit::TestCase
7
+ include RText::MessageHelper
8
+
9
+ def test_serialize
10
+ str = serialize_message({"key" => 1})
11
+ assert_equal '9{"key":1}', str
12
+ str = serialize_message({"key" => true})
13
+ assert_equal '12{"key":true}', str
14
+ str = serialize_message({"key" => "value"})
15
+ assert_equal '15{"key":"value"}', str
16
+ str = serialize_message({"key" => {"nested" => "value"}})
17
+ assert_equal '26{"key":{"nested":"value"}}', str
18
+ str = serialize_message({"key" => ["value1", "value2"]})
19
+ assert_equal '27{"key":["value1","value2"]}', str
20
+
21
+ # a iso-8859-1 '�'
22
+ str = serialize_message({"key" => "umlaut\xe4".force_encoding("binary")})
23
+ assert_equal '19{"key":"umlaut%e4"}', str
24
+ str = serialize_message({"key" => "umlaut\xe4".force_encoding("iso-8859-1")})
25
+ assert_equal '19{"key":"umlaut%e4"}', str
26
+ str = serialize_message({"key" => "umlaut\xe4".force_encoding("cp850")})
27
+ assert_equal '19{"key":"umlaut%e4"}', str
28
+ str = serialize_message({"key" => "umlaut\xe4".force_encoding("utf-8")})
29
+ assert_equal '19{"key":"umlaut%e4"}', str
30
+
31
+ # a utf-8 '�'
32
+ str = serialize_message({"key" => "umlaut\xc3\xa4".force_encoding("binary")})
33
+ assert_equal '22{"key":"umlaut%c3%a4"}', str
34
+ str = serialize_message({"key" => "umlaut\xc3\xa4".force_encoding("iso-8859-1")})
35
+ assert_equal '22{"key":"umlaut%c3%a4"}', str
36
+ str = serialize_message({"key" => "umlaut\xc3\xa4".force_encoding("cp850")})
37
+ assert_equal '22{"key":"umlaut%c3%a4"}', str
38
+ str = serialize_message({"key" => "umlaut\xc3\xa4".force_encoding("utf-8")})
39
+ assert_equal '22{"key":"umlaut%c3%a4"}', str
40
+
41
+ # %
42
+ str = serialize_message({"key" => "%"})
43
+ assert_equal '13{"key":"%25"}', str
44
+ end
45
+
46
+ def test_extract
47
+ # specified length too short
48
+ assert_raise JSON::ParserError do
49
+ extract_message('8{"key":1}')
50
+ end
51
+ # specified length too long
52
+ assert_raise JSON::ParserError do
53
+ extract_message('10{"key":1}x')
54
+ end
55
+ # message data shorter than length specifie, waits for more data
56
+ assert_nothing_raised do
57
+ extract_message('10{"key":1}')
58
+ end
59
+
60
+ obj = extract_message('9{"key":1}')
61
+ assert_equal({"key" => 1}, obj)
62
+ obj = extract_message('12{"key":true}')
63
+ assert_equal({"key" => true}, obj)
64
+ obj = extract_message('15{"key":"value"}')
65
+ assert_equal({"key" => "value"}, obj)
66
+ obj = extract_message('26{"key":{"nested":"value"}}')
67
+ assert_equal({"key" => {"nested" => "value"}}, obj)
68
+ obj = extract_message('27{"key":["value1","value2"]}')
69
+ assert_equal({"key" => ["value1", "value2"]}, obj)
70
+
71
+ # a iso-8859-1 '�'
72
+ obj = extract_message('19{"key":"umlaut%e4"}'.force_encoding("binary"))
73
+ assert_equal "ASCII-8BIT", obj["key"].encoding.name
74
+ assert_equal "umlaut\xe4", obj["key"]
75
+ obj = extract_message('19{"key":"umlaut%e4"}'.force_encoding("utf-8"))
76
+ assert_equal "ASCII-8BIT", obj["key"].encoding.name
77
+ assert_equal "umlaut\xe4", obj["key"]
78
+
79
+ # a utf-8 '�'
80
+ obj = extract_message('22{"key":"umlaut%c3%a4"}'.force_encoding("binary"))
81
+ assert_equal "ASCII-8BIT", obj["key"].encoding.name
82
+ assert_equal "umlaut\xc3\xa4", obj["key"]
83
+ obj = extract_message('22{"key":"umlaut%c3%a4"}'.force_encoding("utf-8"))
84
+ assert_equal "ASCII-8BIT", obj["key"].encoding.name
85
+ assert_equal "umlaut\xc3\xa4", obj["key"]
86
+
87
+ # %
88
+ obj = extract_message('13{"key":"%25"}')
89
+ assert_equal "ASCII-8BIT", obj["key"].encoding.name
90
+ assert_equal "%", obj["key"]
91
+
92
+ # invalid escape sequence
93
+ obj = extract_message('11{"key":"%"}')
94
+ assert_equal "ASCII-8BIT", obj["key"].encoding.name
95
+ assert_equal "%", obj["key"]
96
+ obj = extract_message('13{"key":"%xx"}')
97
+ assert_equal "ASCII-8BIT", obj["key"].encoding.name
98
+ assert_equal "%xx", obj["key"]
99
+ obj = extract_message('14{"key":"%%25"}')
100
+ assert_equal "ASCII-8BIT", obj["key"].encoding.name
101
+ assert_equal "%%", obj["key"]
102
+
103
+ # invalid characters (protocol should use 7-bit ascii only)
104
+ obj = extract_message(%Q(14{"key":"\xe4345"}).force_encoding("binary"))
105
+ assert_equal "ASCII-8BIT", obj["key"].encoding.name
106
+ assert_equal "?345", obj["key"]
107
+ end
108
+
109
+ def test_roundtrip
110
+ value = (0..255).collect{|b| b.chr("binary")}.join
111
+ str = serialize_message({"key" => value})
112
+ obj = extract_message(str)
113
+ assert_equal "ASCII-8BIT", obj["key"].encoding.name
114
+ assert_equal (0..255).collect{|i| i}, obj["key"].bytes.to_a
115
+ end
116
+
117
+ end
118
+
@@ -4,4 +4,7 @@ require 'serializer_test'
4
4
  require 'instantiator_test'
5
5
  require 'context_builder_test'
6
6
  require 'completer_test'
7
-
7
+ require 'tokenizer_test'
8
+ require 'link_detector_test'
9
+ require 'integration/test'
10
+ require 'message_helper_test'
@@ -21,6 +21,7 @@ class SerializerTest < Test::Unit::TestCase
21
21
  has_attr 'integer', Integer
22
22
  has_attr 'float', Float
23
23
  has_attr 'enum', SomeEnum
24
+ has_attr 'boolean', Boolean
24
25
  contains_many 'childs', TestNode, 'parent'
25
26
  end
26
27
  end
@@ -151,6 +152,44 @@ TestNode {
151
152
  ), output
152
153
  end
153
154
 
155
+ module TestMMAnnotation
156
+ extend RGen::MetamodelBuilder::ModuleExtension
157
+ class TestNode < RGen::MetamodelBuilder::MMBase
158
+ has_attr 'annotation', String
159
+ contains_many 'childs', TestNode, 'parent'
160
+ end
161
+ end
162
+
163
+ def test_annotation_provider
164
+ testModel = TestMMAnnotation::TestNode.new(
165
+ :annotation => "this is an annotation",
166
+ :childs => [
167
+ TestMMAnnotation::TestNode.new(:annotation => "annotation of a child node\n multiline"),
168
+ TestMMAnnotation::TestNode.new(:annotation => "don't show")])
169
+
170
+ output = StringWriter.new
171
+ serialize(testModel, TestMMAnnotation, output,
172
+ :annotation_provider => proc { |e|
173
+ if e.annotation != "don't show"
174
+ a = e.annotation
175
+ e.annotation = nil
176
+ a
177
+ else
178
+ nil
179
+ end
180
+ })
181
+
182
+ assert_equal %Q(\
183
+ @this is an annotation
184
+ TestNode {
185
+ @annotation of a child node
186
+ @ multiline
187
+ TestNode
188
+ TestNode annotation: "don't show"
189
+ }
190
+ ), output
191
+ end
192
+
154
193
  def test_indent_string
155
194
  testModel = TestMM::TestNode.new(:childs => [
156
195
  TestMM::TestNode.new(:text => "child")])
@@ -186,8 +225,10 @@ ____TestNode text: "child"
186
225
 
187
226
  output = StringWriter.new
188
227
  serialize(testModel, TestMMRef, output,
189
- :identifier_provider => proc{|e, context|
228
+ :identifier_provider => proc{|e, context, feature, index|
190
229
  assert_equal testModel[0], context
230
+ assert_equal "refOne", feature.name
231
+ assert_equal 0, index
191
232
  "/target/ref"
192
233
  }
193
234
  )
@@ -198,6 +239,37 @@ TestNode name: "Target"
198
239
  ),output
199
240
  end
200
241
 
242
+ def test_identifier_provider_many
243
+ testModel = [
244
+ TestMMRef::TestNode.new(:name => "Source"),
245
+ TestMMRef::TestNode.new(:name => "Target1"),
246
+ TestMMRef::TestNode.new(:name => "Target2")]
247
+ testModel[0].addRefMany(testModel[1])
248
+ testModel[0].addRefMany(testModel[2])
249
+
250
+ output = StringWriter.new
251
+ call_index = 0
252
+ serialize(testModel, TestMMRef, output,
253
+ :identifier_provider => proc{|e, context, feature, index|
254
+ assert_equal testModel[0], context
255
+ assert_equal "refMany", feature.name
256
+ if call_index == 0
257
+ call_index += 1
258
+ assert_equal 0, index
259
+ "/target/ref1"
260
+ else
261
+ assert_equal 1, index
262
+ "/target/ref2"
263
+ end
264
+ }
265
+ )
266
+ assert_equal %Q(\
267
+ TestNode name: "Source", refMany: [/target/ref1, /target/ref2]
268
+ TestNode name: "Target1"
269
+ TestNode name: "Target2"
270
+ ),output
271
+ end
272
+
201
273
  def test_references
202
274
  testModel = [
203
275
  TestMMRef::TestNode.new(:name => "Source"),
@@ -368,6 +440,29 @@ TestNode enum: "2you"
368
440
  ), output
369
441
  end
370
442
 
443
+ def test_generic
444
+ testModel = [
445
+ TestMM::TestNode.new(:text => RText::Generic.new("some text angel >bracket")),
446
+ TestMM::TestNode.new(:text => RText::Generic.new("some text percent angel %>bracket")),
447
+ TestMM::TestNode.new(:text => RText::Generic.new("some text > percent angel%>bracket")),
448
+ TestMM::TestNode.new(:integer => RText::Generic.new("a number: 1")),
449
+ TestMM::TestNode.new(:float => RText::Generic.new("precision")),
450
+ TestMM::TestNode.new(:enum => RText::Generic.new("an option")),
451
+ TestMM::TestNode.new(:boolean => RText::Generic.new("falsy"))
452
+ ]
453
+ output = StringWriter.new
454
+ serialize(testModel, TestMM, output)
455
+ assert_equal %Q(\
456
+ TestNode text: <%some text angel >bracket%>
457
+ TestNode text: <some text percent angel >
458
+ TestNode text: <%some text > percent angel%>
459
+ TestNode integer: <a number: 1>
460
+ TestNode float: <precision>
461
+ TestNode enum: <an option>
462
+ TestNode boolean: <falsy>
463
+ ), output
464
+ end
465
+
371
466
  module TestMMData
372
467
  extend RGen::MetamodelBuilder::ModuleExtension
373
468
  # class "Data" exists in the standard Ruby namespace