rtext 0.8.0 → 0.9.1

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.
@@ -1,1004 +1,1023 @@
1
- $:.unshift File.join(File.dirname(__FILE__),"..","lib")
2
-
3
- require 'test/unit'
4
- require 'bigdecimal'
5
- require 'fileutils'
6
- require 'stringio'
7
- require 'rgen/environment'
8
- require 'rgen/metamodel_builder'
9
- require 'rtext/serializer'
10
- require 'rtext/language'
11
-
12
- class SerializerTest < Test::Unit::TestCase
13
- TestOutputFile = ".serializer_test_file"
14
-
15
- def teardown
16
- FileUtils.rm_f TestOutputFile
17
- end
18
-
19
- class StringWriter < String
20
- alias write concat
21
- end
22
-
23
- module TestMM
24
- extend RGen::MetamodelBuilder::ModuleExtension
25
- SomeEnum = RGen::MetamodelBuilder::DataTypes::Enum.new(
26
- :name => "SomeEnum", :literals => [:A, :B, :'non-word*chars', :'2you'])
27
- class TestNode < RGen::MetamodelBuilder::MMBase
28
- has_attr 'text', String
29
- has_many_attr 'texts', String
30
- has_many_attr 'more_texts', String
31
- has_attr 'unlabled', String
32
- has_attr 'unquoted', String
33
- has_attr 'both', String
34
- has_attr 'none', String
35
- has_attr 'comment', String
36
- has_attr 'integer', Integer
37
- has_attr 'float', Float
38
- has_attr 'enum', SomeEnum
39
- has_attr 'boolean', Boolean
40
- contains_many 'childs', TestNode, 'parent'
41
- end
42
- end
43
-
44
- def test_simple
45
- testModel = TestMM::TestNode.new(:text => "some text", :childs => [
46
- TestMM::TestNode.new(:text => "child")])
47
-
48
- output = StringWriter.new
49
- serialize(testModel, TestMM, output)
50
-
51
- assert_equal %Q(\
52
- TestNode text: "some text" {
53
- TestNode text: "child"
54
- }
55
- ), output
56
- end
57
-
58
- def test_many_attr
59
- testModel = TestMM::TestNode.new(:texts => ["a", "b", "c"])
60
-
61
- output = StringWriter.new
62
- serialize(testModel, TestMM, output)
63
-
64
- assert_equal %Q(\
65
- TestNode texts: ["a", "b", "c"]
66
- ), output
67
- end
68
-
69
- module TestMMFeatureProvider
70
- extend RGen::MetamodelBuilder::ModuleExtension
71
- class TestNode < RGen::MetamodelBuilder::MMBase
72
- has_attr 'attr1', String
73
- has_attr 'attr2', String
74
- has_attr 'attr3', String
75
- contains_many 'childs1', TestNode, 'parent1'
76
- contains_many 'childs2', TestNode, 'parent2'
77
- contains_many 'childs3', TestNode, 'parent3'
78
- end
79
- end
80
-
81
- def test_feature_provider
82
- testModel = TestMMFeatureProvider::TestNode.new(
83
- :attr1 => "attr1",
84
- :attr2 => "attr2",
85
- :attr3 => "attr3",
86
- :childs1 => [TestMMFeatureProvider::TestNode.new(:attr1 => "child1")],
87
- :childs2 => [TestMMFeatureProvider::TestNode.new(:attr1 => "child2")],
88
- :childs3 => [TestMMFeatureProvider::TestNode.new(:attr1 => "child3")])
89
-
90
- output = StringWriter.new
91
- serialize(testModel, TestMMFeatureProvider, output,
92
- :feature_provider => proc {|clazz|
93
- clazz.eAllStructuralFeatures.reject{|f| f.name =~ /parent|2$/}.reverse})
94
-
95
- assert_equal %Q(\
96
- TestNode attr3: "attr3", attr1: "attr1" {
97
- childs3:
98
- TestNode attr1: "child3"
99
- childs1:
100
- TestNode attr1: "child1"
101
- }
102
- ), output
103
- end
104
-
105
- module TestMMUnlabledUnquoted
106
- extend RGen::MetamodelBuilder::ModuleExtension
107
- class TestNode < RGen::MetamodelBuilder::MMBase
108
- has_attr 'unlabled', String
109
- has_attr 'unquoted', String
110
- has_attr 'both', String
111
- has_attr 'none', String
112
- end
113
- end
114
-
115
- def test_unlabled_unquoted
116
- testModel = [
117
- TestMMUnlabledUnquoted::TestNode.new(:unlabled => "unlabled", :unquoted => "unquoted", :both => "both", :none => "none"),
118
- TestMMUnlabledUnquoted::TestNode.new(:unquoted => "no identifier"),
119
- TestMMUnlabledUnquoted::TestNode.new(:unquoted => "true"),
120
- TestMMUnlabledUnquoted::TestNode.new(:unquoted => "333"),
121
- TestMMUnlabledUnquoted::TestNode.new(:unquoted => "33.3"),
122
- TestMMUnlabledUnquoted::TestNode.new(:unquoted => "5x"),
123
- TestMMUnlabledUnquoted::TestNode.new(:unquoted => "//")
124
- ]
125
-
126
- output = StringWriter.new
127
- serialize(testModel, TestMMUnlabledUnquoted, output,
128
- :unlabled_arguments => proc {|clazz| ["unlabled", "both"]},
129
- :unquoted_arguments => proc {|clazz| ["unquoted", "both"]}
130
- )
131
-
132
- assert_equal %Q(\
133
- TestNode "unlabled", both, unquoted: unquoted, none: "none"
134
- TestNode unquoted: "no identifier"
135
- TestNode unquoted: "true"
136
- TestNode unquoted: "333"
137
- TestNode unquoted: "33.3"
138
- TestNode unquoted: "5x"
139
- TestNode unquoted: "//"
140
- ), output
141
- end
142
-
143
- module TestMMComment
144
- extend RGen::MetamodelBuilder::ModuleExtension
145
- class TestNode < RGen::MetamodelBuilder::MMBase
146
- has_attr 'comment', String
147
- contains_many 'childs', TestNode, 'parent'
148
- end
149
- end
150
-
151
- def test_comment_provider
152
- testModel = TestMMComment::TestNode.new(
153
- :comment => "this is a comment",
154
- :childs => [
155
- TestMMComment::TestNode.new(:comment => "\n\ncomment of a child node\n multiline\n\n\nanother\n\n\n"),
156
- TestMMComment::TestNode.new(:comment => "don't show"),
157
- TestMMComment::TestNode.new(:comment => "")])
158
-
159
- output = StringWriter.new
160
- serialize(testModel, TestMMComment, output,
161
- :comment_provider => proc { |e|
162
- if e.comment != "don't show"
163
- c = e.comment
164
- e.comment = nil
165
- c
166
- else
167
- nil
168
- end
169
- })
170
-
171
- assert_equal %Q(\
172
- #this is a comment
173
- TestNode {
174
- #
175
- #
176
- #comment of a child node
177
- # multiline
178
- #
179
- #
180
- #another
181
- TestNode
182
- TestNode comment: "don't show"
183
- TestNode
184
- }
185
- ), output
186
- end
187
-
188
- module TestMMAnnotation
189
- extend RGen::MetamodelBuilder::ModuleExtension
190
- class TestNode < RGen::MetamodelBuilder::MMBase
191
- has_attr 'annotation', String
192
- contains_many 'childs', TestNode, 'parent'
193
- end
194
- end
195
-
196
- def test_annotation_provider
197
- testModel = TestMMAnnotation::TestNode.new(
198
- :annotation => "this is an annotation",
199
- :childs => [
200
- TestMMAnnotation::TestNode.new(:annotation => "annotation of a child node\n multiline"),
201
- TestMMAnnotation::TestNode.new(:annotation => "don't show")])
202
-
203
- output = StringWriter.new
204
- serialize(testModel, TestMMAnnotation, output,
205
- :annotation_provider => proc { |e|
206
- if e.annotation != "don't show"
207
- a = e.annotation
208
- e.annotation = nil
209
- a
210
- else
211
- nil
212
- end
213
- })
214
-
215
- assert_equal %Q(\
216
- @this is an annotation
217
- TestNode {
218
- @annotation of a child node
219
- @ multiline
220
- TestNode
221
- TestNode annotation: "don't show"
222
- }
223
- ), output
224
- end
225
-
226
- def test_indent_string
227
- testModel = TestMM::TestNode.new(:childs => [
228
- TestMM::TestNode.new(:text => "child")])
229
-
230
- output = StringWriter.new
231
- serialize(testModel, TestMM, output, :indent_string => "____")
232
-
233
- assert_equal %Q(\
234
- TestNode {
235
- ____TestNode text: "child"
236
- }
237
- ), output
238
- end
239
-
240
- module TestMMRef
241
- extend RGen::MetamodelBuilder::ModuleExtension
242
- class TestNode < RGen::MetamodelBuilder::MMBase
243
- has_attr 'name', String
244
- contains_many 'childs', TestNode, 'parent'
245
- has_many 'refMany', TestNode
246
- has_one 'refOne', TestNode
247
- one_to_many 'refManyBi', TestNode, 'refManyBack'
248
- one_to_one 'refOneBi', TestNode, 'refOneBack'
249
- many_to_many 'refManyMany', TestNode, 'refManyManyBack'
250
- end
251
- end
252
-
253
- def test_identifier_provider
254
- testModel = [
255
- TestMMRef::TestNode.new(:name => "Source"),
256
- TestMMRef::TestNode.new(:name => "Target")]
257
- testModel[0].refOne = testModel[1]
258
-
259
- output = StringWriter.new
260
- serialize(testModel, TestMMRef, output,
261
- :identifier_provider => proc{|e, context, feature, index|
262
- assert_equal testModel[0], context
263
- assert_equal "refOne", feature.name
264
- assert_equal 0, index
265
- "/target/ref"
266
- }
267
- )
268
-
269
- assert_equal %Q(\
270
- TestNode name: "Source", refOne: /target/ref
271
- TestNode name: "Target"
272
- ),output
273
- end
274
-
275
- def test_identifier_provider_many
276
- testModel = [
277
- TestMMRef::TestNode.new(:name => "Source"),
278
- TestMMRef::TestNode.new(:name => "Target1"),
279
- TestMMRef::TestNode.new(:name => "Target2")]
280
- testModel[0].addRefMany(testModel[1])
281
- testModel[0].addRefMany(testModel[2])
282
-
283
- output = StringWriter.new
284
- call_index = 0
285
- serialize(testModel, TestMMRef, output,
286
- :identifier_provider => proc{|e, context, feature, index|
287
- assert_equal testModel[0], context
288
- assert_equal "refMany", feature.name
289
- if call_index == 0
290
- call_index += 1
291
- assert_equal 0, index
292
- "/target/ref1"
293
- else
294
- assert_equal 1, index
295
- "/target/ref2"
296
- end
297
- }
298
- )
299
- assert_equal %Q(\
300
- TestNode name: "Source", refMany: [/target/ref1, /target/ref2]
301
- TestNode name: "Target1"
302
- TestNode name: "Target2"
303
- ),output
304
- end
305
-
306
- def test_identifier_provider_nil
307
- testModel = [
308
- TestMMRef::TestNode.new(:name => "Source"),
309
- TestMMRef::TestNode.new(:name => "Target")]
310
- testModel[0].refOne = testModel[1]
311
-
312
- output = StringWriter.new
313
- serialize(testModel, TestMMRef, output,
314
- :identifier_provider => proc{|e, context, feature, index|
315
- nil
316
- }
317
- )
318
-
319
- assert_equal %Q(\
320
- TestNode name: "Source"
321
- TestNode name: "Target"
322
- ),output
323
- end
324
-
325
- def test_references
326
- testModel = [
327
- TestMMRef::TestNode.new(:name => "Source"),
328
- TestMMRef::TestNode.new(:name => "Target",
329
- :childs => [
330
- TestMMRef::TestNode.new(:name => "A",
331
- :childs => [
332
- TestMMRef::TestNode.new(:name => "A1")
333
- ]),
334
- TestMMRef::TestNode.new(:name => "B"),
335
- ])
336
- ]
337
- testModel[0].refOne = testModel[1].childs[0].childs[0]
338
- testModel[0].refOneBi = testModel[1].childs[0].childs[0]
339
- testModel[0].refMany = [testModel[1].childs[0], testModel[1].childs[1]]
340
- testModel[0].refManyBi = [testModel[1].childs[0], testModel[1].childs[1]]
341
- testModel[0].refManyMany = [testModel[1].childs[0], testModel[1].childs[1]]
342
- testModel[0].addRefMany(RGen::MetamodelBuilder::MMProxy.new("/some/ref"))
343
-
344
- output = StringWriter.new
345
- serialize(testModel, TestMMRef, output)
346
-
347
- assert_equal %Q(\
348
- TestNode name: "Source", refMany: [/Target/A, /Target/B, /some/ref], refOne: /Target/A/A1, refOneBi: /Target/A/A1
349
- TestNode name: "Target" {
350
- TestNode name: "A", refManyBack: /Source, refManyManyBack: /Source {
351
- TestNode name: "A1"
352
- }
353
- TestNode name: "B", refManyBack: /Source, refManyManyBack: /Source
354
- }
355
- ), output
356
- end
357
-
358
- module TestMMChildRole
359
- extend RGen::MetamodelBuilder::ModuleExtension
360
- class TestNodeA < RGen::MetamodelBuilder::MMBase
361
- has_attr 'text', String
362
- end
363
- class TestNodeB < RGen::MetamodelBuilder::MMBase
364
- has_attr 'text', String
365
- end
366
- class TestNodeC < RGen::MetamodelBuilder::MMBase
367
- has_attr 'text', String
368
- end
369
- class TestNodeD < RGen::MetamodelBuilder::MMBase
370
- has_attr 'text3', String
371
- end
372
- class TestNodeE < RGen::MetamodelBuilder::MMMultiple(TestNodeC, TestNodeD)
373
- has_attr 'text2', String
374
- end
375
- class TestNode < RGen::MetamodelBuilder::MMBase
376
- has_attr 'text', String
377
- has_many_attr 'texts', String
378
- contains_one 'child1', TestNode, 'parent1'
379
- contains_many 'childs2', TestNode, 'parent2'
380
- contains_one 'child3', TestNodeA, 'parent3'
381
- contains_many 'childs4', TestNodeB, 'parent4'
382
- contains_one 'child5', TestNodeC, 'parent5'
383
- contains_many 'childs6', TestNodeD, 'parent6'
384
- contains_one 'child7', TestNodeE, 'parent7'
385
- end
386
- end
387
-
388
- def test_child_role
389
- testModel = TestMMChildRole::TestNode.new(
390
- :child1 => TestMMChildRole::TestNode.new(:text => "child1"),
391
- :childs2 => [
392
- TestMMChildRole::TestNode.new(:text => "child2a"),
393
- TestMMChildRole::TestNode.new(:text => "child2b")
394
- ],
395
- :child3 => TestMMChildRole::TestNodeA.new(:text => "child3"),
396
- :childs4 => [TestMMChildRole::TestNodeB.new(:text => "child4")],
397
- :child5 => TestMMChildRole::TestNodeC.new(:text => "child5"),
398
- :childs6 => [TestMMChildRole::TestNodeD.new(:text3 => "child6"), TestMMChildRole::TestNodeE.new(:text => "child6.1")],
399
- :child7 => TestMMChildRole::TestNodeE.new(:text2 => "child7")
400
- )
401
-
402
- output = StringWriter.new
403
- serialize(testModel, TestMMChildRole, output)
404
-
405
- assert_equal %Q(\
406
- TestNode {
407
- child1:
408
- TestNode text: "child1"
409
- childs2: [
410
- TestNode text: "child2a"
411
- TestNode text: "child2b"
412
- ]
413
- TestNodeA text: "child3"
414
- TestNodeB text: "child4"
415
- TestNodeC text: "child5"
416
- childs6: [
417
- TestNodeD text3: "child6"
418
- TestNodeE text: "child6.1"
419
- ]
420
- child7:
421
- TestNodeE text2: "child7"
422
- }
423
- ), output
424
- end
425
-
426
- module TestMMLabeledContainment
427
- extend RGen::MetamodelBuilder::ModuleExtension
428
- class TestNode < RGen::MetamodelBuilder::MMBase
429
- abstract
430
- has_attr 'text', String
431
- contains_many 'childs', TestNode, 'parent'
432
- end
433
- class TestNode1 < TestNode
434
- end
435
- class TestNode2 < TestNode
436
- end
437
- end
438
-
439
- def test_labeled_containment
440
- testModel = TestMMLabeledContainment::TestNode1.new(:text => "some text", :childs => [
441
- TestMMLabeledContainment::TestNode2.new(:text => "child", :childs => [
442
- TestMMLabeledContainment::TestNode1.new(:text => "nested child")
443
- ])])
444
-
445
- output = StringWriter.new
446
- serialize(testModel, TestMMLabeledContainment, output, :labeled_containments => proc {|c|
447
- if c == TestMMLabeledContainment::TestNode2.ecore
448
- ["childs"]
449
- else
450
- []
451
- end
452
- })
453
-
454
- assert_equal %Q(\
455
- TestNode1 text: "some text" {
456
- TestNode2 text: "child" {
457
- childs:
458
- TestNode1 text: "nested child"
459
- }
460
- }
461
- ), output
462
- end
463
-
464
- def test_escapes
465
- testModel = TestMM::TestNode.new(:text => %Q(some " \\ \\" text \r xx \n xx \r\n xx \t xx \b xx \f))
466
- output = StringWriter.new
467
- serialize(testModel, TestMM, output)
468
-
469
- assert_equal %q(TestNode text: "some \" \\\\ \\\\\" text \r xx \n xx \r\n xx \t xx \b xx \f")+"\n", output
470
- end
471
-
472
- def test_integer
473
- testModel = TestMM::TestNode.new(:integer => 7)
474
- output = StringWriter.new
475
- serialize(testModel, TestMM, output)
476
- assert_equal %q(TestNode integer: 7)+"\n", output
477
- end
478
-
479
- def test_integer_big
480
- testModel = TestMM::TestNode.new(:integer => 12345678901234567890)
481
- output = StringWriter.new
482
- serialize(testModel, TestMM, output)
483
- assert_equal %q(TestNode integer: 12345678901234567890)+"\n", output
484
- end
485
-
486
- def test_integer_format_spec
487
- testModel = TestMM::TestNode.new(:integer => 10)
488
- output = StringWriter.new
489
- serialize(testModel, TestMM, output, :argument_format_provider => proc {|a|
490
- if a.name == "integer"
491
- "0x%02X"
492
- else
493
- nil
494
- end})
495
- assert_equal %q(TestNode integer: 0x0A)+"\n", output
496
- end
497
-
498
- def test_integer_format_spec_big
499
- testModel = TestMM::TestNode.new(:integer => 0xabcdefabcdefabcdef)
500
- output = StringWriter.new
501
- serialize(testModel, TestMM, output, :argument_format_provider => proc {|a|
502
- if a.name == "integer"
503
- "0x%x"
504
- else
505
- nil
506
- end})
507
- assert_equal %q(TestNode integer: 0xabcdefabcdefabcdef)+"\n", output
508
- end
509
-
510
- def test_float
511
- testModel = TestMM::TestNode.new(:float => 1.23)
512
- output = StringWriter.new
513
- serialize(testModel, TestMM, output)
514
- assert_equal %q(TestNode float: 1.23)+"\n", output
515
- end
516
-
517
- def test_float2
518
- testModel = TestMM::TestNode.new(:float => 1.23e-08)
519
- output = StringWriter.new
520
- serialize(testModel, TestMM, output)
521
- assert output =~ /TestNode float: 1.23e-0?08\n/
522
- end
523
-
524
- def test_float_format_spec
525
- testModel = TestMM::TestNode.new(:float => 1.23)
526
- output = StringWriter.new
527
- serialize(testModel, TestMM, output, :argument_format_provider => proc {|a|
528
- if a.name == "float"
529
- "%1.1f"
530
- else
531
- nil
532
- end})
533
- assert_equal %q(TestNode float: 1.2)+"\n", output
534
- end
535
-
536
- def test_float_big_decimal
537
- begin
538
- testModel = TestMM::TestNode.new(:float => BigDecimal.new("1234567890.123456789"))
539
- rescue StandardError
540
- return
541
- end
542
- output = StringWriter.new
543
- serialize(testModel, TestMM, output)
544
- assert_equal %q(TestNode float: 1234567890.123456789)+"\n", output
545
- end
546
-
547
- def test_enum
548
- testModel = [
549
- TestMM::TestNode.new(:enum => :A),
550
- TestMM::TestNode.new(:enum => :B),
551
- TestMM::TestNode.new(:enum => :'non-word*chars'),
552
- TestMM::TestNode.new(:enum => :'2you')
553
- ]
554
- output = StringWriter.new
555
- serialize(testModel, TestMM, output)
556
- assert_equal %Q(\
557
- TestNode enum: A
558
- TestNode enum: B
559
- TestNode enum: "non-word*chars"
560
- TestNode enum: "2you"
561
- ), output
562
- end
563
-
564
- def test_generic
565
- testModel = [
566
- TestMM::TestNode.new(:text => RText::Generic.new("some text angel >bracket")),
567
- TestMM::TestNode.new(:text => RText::Generic.new("some text percent angel %>bracket")),
568
- TestMM::TestNode.new(:text => RText::Generic.new("some text > percent angel%>bracket")),
569
- TestMM::TestNode.new(:integer => RText::Generic.new("a number: 1")),
570
- TestMM::TestNode.new(:float => RText::Generic.new("precision")),
571
- TestMM::TestNode.new(:enum => RText::Generic.new("an option")),
572
- TestMM::TestNode.new(:boolean => RText::Generic.new("falsy"))
573
- ]
574
- output = StringWriter.new
575
- serialize(testModel, TestMM, output)
576
- assert_equal %Q(\
577
- TestNode text: <%some text angel >bracket%>
578
- TestNode text: <some text percent angel >
579
- TestNode text: <%some text > percent angel%>
580
- TestNode integer: <a number: 1>
581
- TestNode float: <precision>
582
- TestNode enum: <an option>
583
- TestNode boolean: <falsy>
584
- ), output
585
- end
586
-
587
- module TestMMData
588
- extend RGen::MetamodelBuilder::ModuleExtension
589
- # class "Data" exists in the standard Ruby namespace
590
- class Data < RGen::MetamodelBuilder::MMBase
591
- has_attr 'notTheBuiltin', String
592
- end
593
- end
594
-
595
- module TestMMSubpackage
596
- extend RGen::MetamodelBuilder::ModuleExtension
597
- module SubPackage
598
- extend RGen::MetamodelBuilder::ModuleExtension
599
- class Data < RGen::MetamodelBuilder::MMBase
600
- has_attr 'notTheBuiltin', String
601
- end
602
- class Data2 < RGen::MetamodelBuilder::MMBase
603
- has_attr 'data2', String
604
- end
605
- end
606
- end
607
-
608
- def test_subpackage
609
- testModel = TestMMSubpackage::SubPackage::Data2.new(:data2 => "xxx")
610
- output = StringWriter.new
611
- serialize(testModel, TestMMSubpackage, output)
612
- assert_equal %q(Data2 data2: "xxx")+"\n", output
613
- end
614
-
615
- def test_command_name_provider
616
- testModel = TestMM::TestNode.new(:text => "some text", :childs => [
617
- TestMM::TestNode.new(:text => "child")])
618
-
619
- output = StringWriter.new
620
- serialize(testModel, TestMM, output, :command_name_provider => proc do |c|
621
- c.name + "X"
622
- end)
623
-
624
- assert_equal %Q(\
625
- TestNodeX text: "some text" {
626
- TestNodeX text: "child"
627
- }
628
- ), output
629
- end
630
-
631
- def test_file_output
632
- testModel = TestMM::TestNode.new(:text => "some text")
633
-
634
- File.open(TestOutputFile, "w") do |f|
635
- serialize(testModel, TestMM, f)
636
- end
637
-
638
- assert_equal %Q(\
639
- TestNode text: "some text"
640
- ), File.read(TestOutputFile)
641
- end
642
-
643
- def test_stringio_output
644
- testModel = TestMM::TestNode.new(:text => "some text")
645
-
646
- output = StringIO.new
647
- serialize(testModel, TestMM, output)
648
-
649
- assert_equal %Q(\
650
- TestNode text: "some text"
651
- ), output.string
652
- end
653
-
654
- #
655
- # line breaks
656
- #
657
- All_features = proc {|clazz|
658
- res = []
659
- clazz.eAllStructuralFeatures.reject{|f| f.name =~ /parent|2$/}.each{|f| res << f.name}
660
- res
661
- }
662
-
663
- def test_linebreak
664
- testModel = TestMM::TestNode.new(
665
- :text => "some text",
666
- :texts => ["some more text", "some more text", "some more text"])
667
-
668
- output = StringWriter.new
669
- serialize(testModel, TestMM, output,
670
- :newline_arguments => All_features,
671
- :newline_arrays => All_features)
672
-
673
- assert_equal %Q(\
674
- TestNode \\
675
- text: "some text",
676
- texts: [
677
- "some more text",
678
- "some more text",
679
- "some more text"
680
- ]
681
- ), output
682
- end
683
-
684
- def test_linebreak_child
685
- testModel1 = TestMM::TestNode.new(
686
- :text => "some text1",
687
- :texts => ["some more text", "some more text", "some more text"])
688
- testModel0 = TestMM::TestNode.new(
689
- :text => "some text0",
690
- :integer => 10,
691
- :childs => [testModel1])
692
-
693
- output = StringWriter.new
694
- serialize(testModel0, TestMM, output,
695
- :newline_arguments => All_features,
696
- :newline_arrays => All_features)
697
-
698
- assert_equal %Q(\
699
- TestNode \\
700
- text: "some text0",
701
- integer: 10 {
702
- TestNode \\
703
- text: "some text1",
704
- texts: [
705
- "some more text",
706
- "some more text",
707
- "some more text"
708
- ]
709
- }
710
- ), output
711
- end
712
-
713
- def test_linebreak_child_no_arguments
714
- testModel1 = TestMM::TestNode.new(
715
- :text => "some text1",
716
- :texts => ["some more text", "some more text", "some more text"])
717
- testModel0 = TestMM::TestNode.new(:childs => [testModel1])
718
-
719
- output = StringWriter.new
720
- serialize(testModel0, TestMM, output,
721
- :newline_arguments => All_features,
722
- :newline_arrays => All_features)
723
-
724
- assert_equal %Q(\
725
- TestNode {
726
- TestNode \\
727
- text: "some text1",
728
- texts: [
729
- "some more text",
730
- "some more text",
731
- "some more text"
732
- ]
733
- }
734
- ), output
735
- end
736
-
737
- def test_linebreak_unlabled_array_arguments
738
- testModel = TestMM::TestNode.new(
739
- :none => "some text",
740
- :texts => ["some more text", "some more text", "some more text"])
741
-
742
- output = StringWriter.new
743
- serialize(testModel, TestMM, output,
744
- :unlabled_arguments => proc {|clazz| ["texts"]},
745
- :newline_arguments => proc {|clazz| All_features.call(clazz) - ["texts"]},
746
- :newline_arrays => All_features)
747
-
748
- assert_equal %Q(\
749
- TestNode [
750
- "some more text",
751
- "some more text",
752
- "some more text"
753
- ],
754
- none: "some text"
755
- ), output
756
- end
757
-
758
- def test_linebreak_unlabled_array_arguments_sameline
759
- testModel = TestMM::TestNode.new(
760
- :none => "some text",
761
- :texts => ["some more text", "some more text", "some more text"])
762
-
763
- output = StringWriter.new
764
- serialize(testModel, TestMM, output,
765
- :unlabled_arguments => proc {|clazz| ["texts"]},
766
- :newline_arguments => proc {|clazz| All_features.call(clazz) - ["texts"]},
767
- :newline_arrays => proc {|clazz| All_features.call(clazz) - ["texts"]})
768
-
769
- assert_equal %Q(\
770
- TestNode ["some more text", "some more text", "some more text"],
771
- none: "some text"
772
- ), output
773
- end
774
-
775
- def test_linebreak_unlabled_both_arguments_and_child
776
- testModel1 = TestMM::TestNode.new(
777
- :texts => ["some more text", "some more text", "some more text"])
778
- testModel0 = TestMM::TestNode.new(
779
- :unlabled => "unlabled",
780
- :both => "both",
781
- :childs => [testModel1])
782
-
783
- output = StringWriter.new
784
- serialize(testModel0, TestMM, output,
785
- :unlabled_arguments => proc {|clazz| ["unlabled", "both"]},
786
- :unquoted_arguments => proc {|clazz| ["both"]},
787
- :newline_arguments => proc {|clazz| All_features.call(clazz) - ["unlabled"]},
788
- :newline_arrays => All_features)
789
-
790
- assert_equal %Q(\
791
- TestNode "unlabled",
792
- both {
793
- TestNode \\
794
- texts: [
795
- "some more text",
796
- "some more text",
797
- "some more text"
798
- ]
799
- }
800
- ), output
801
- end
802
-
803
- def test_linebreak_child_two_attributes
804
- testModel1 = TestMM::TestNode.new(
805
- :text => "some text1",
806
- :texts => ["some more text", "some more text", "some more text"],
807
- :more_texts => ["even more text", "even more text"])
808
- testModel0 = TestMM::TestNode.new(:text => "some text0", :childs => [testModel1])
809
-
810
- output = StringWriter.new
811
- serialize(testModel0, TestMM, output,
812
- :newline_arguments => proc {|clazz| All_features.call(clazz) - ["text"]},
813
- :newline_arrays => proc {|clazz| All_features.call(clazz) - ["text"]})
814
-
815
- assert_equal %Q(\
816
- TestNode text: "some text0" {
817
- TestNode text: "some text1",
818
- texts: [
819
- "some more text",
820
- "some more text",
821
- "some more text"
822
- ],
823
- more_texts: [
824
- "even more text",
825
- "even more text"
826
- ]
827
- }
828
- ), output
829
- end
830
-
831
- def test_linebreak_child_two_attributes_one_sameline
832
- testModel1 = TestMM::TestNode.new(
833
- :text => "some text1",
834
- :texts => ["some more text", "some more text", "some more text"],
835
- :more_texts => ["even more text", "even more text"])
836
- testModel0 = TestMM::TestNode.new(:text => "some text0", :childs => [testModel1])
837
-
838
- output = StringWriter.new
839
- serialize(testModel0, TestMM, output,
840
- :newline_arguments => proc {|clazz| All_features.call(clazz) - ["more_texts"]},
841
- :newline_arrays => proc {|clazz| All_features.call(clazz) - ["more_texts"]})
842
-
843
- assert_equal %Q(\
844
- TestNode \\
845
- text: "some text0" {
846
- TestNode \\
847
- text: "some text1",
848
- texts: [
849
- "some more text",
850
- "some more text",
851
- "some more text"
852
- ], more_texts: ["even more text", "even more text"]
853
- }
854
- ), output
855
- end
856
-
857
- def test_linebreak_two_children
858
- testModel2 = TestMM::TestNode.new(:text => "some text2", :texts => ["some more text"])
859
- testModel1 = TestMM::TestNode.new(:text => "some text1", :texts => ["some more text", "some more text", "some more text"])
860
- testModel0 = TestMM::TestNode.new(:text => "some text0", :childs => [testModel1, testModel2])
861
-
862
- output = StringWriter.new
863
- serialize(testModel0, TestMM, output,
864
- :newline_arguments => proc {|clazz| All_features.call(clazz) - ["text"]},
865
- :newline_arrays => All_features)
866
-
867
- assert_equal %Q(\
868
- TestNode text: "some text0" {
869
- TestNode text: "some text1",
870
- texts: [
871
- "some more text",
872
- "some more text",
873
- "some more text"
874
- ]
875
- TestNode text: "some text2",
876
- texts: "some more text"
877
- }
878
- ), output
879
- end
880
-
881
- def test_linebreak_nested_children
882
- testModel2 = TestMM::TestNode.new(
883
- :text => "some text2",
884
- :texts => ["some more text", "some more text", "some more text"])
885
- testModel1 = TestMM::TestNode.new(
886
- :text => "some text1",
887
- :childs => [testModel2])
888
- testModel0 = TestMM::TestNode.new(
889
- :text => "some text0",
890
- :integer => 10,
891
- :childs => [testModel1])
892
-
893
- output = StringWriter.new
894
- serialize(testModel0, TestMM, output,
895
- :newline_arguments => All_features,
896
- :newline_arrays => All_features)
897
-
898
- assert_equal %Q(\
899
- TestNode \\
900
- text: "some text0",
901
- integer: 10 {
902
- TestNode \\
903
- text: "some text1" {
904
- TestNode \\
905
- text: "some text2",
906
- texts: [
907
- "some more text",
908
- "some more text",
909
- "some more text"
910
- ]
911
- }
912
- }
913
- ), output
914
- end
915
-
916
- def test_linebreak_no_break
917
- testModel = TestMM::TestNode.new(:text => "some text", :texts => ["some more text", "some more text", "some more text"])
918
-
919
- output = StringWriter.new
920
- serialize(testModel, TestMM, output)
921
-
922
- assert_equal %Q(\
923
- TestNode text: "some text", texts: ["some more text", "some more text", "some more text"]
924
- ), output
925
- end
926
-
927
- def test_linebreak_child_role
928
- testModel = TestMMChildRole::TestNode.new(
929
- :child1 => TestMMChildRole::TestNode.new(:text => "child1"),
930
- :childs2 => [
931
- TestMMChildRole::TestNode.new(
932
- :text => "child2a",
933
- :texts => ["some more text", "some more text"]),
934
- TestMMChildRole::TestNode.new(
935
- :text => "child2b",
936
- :texts => ["some more text", "some more text"])
937
- ])
938
-
939
- output = StringWriter.new
940
- serialize(testModel, TestMMChildRole, output,
941
- :newline_arguments => proc {|clazz| All_features.call(clazz) - ["text"]},
942
- :newline_arrays => proc {|clazz| All_features.call(clazz) - ["text"]})
943
-
944
- assert_equal %Q(\
945
- TestNode {
946
- child1:
947
- TestNode text: "child1"
948
- childs2: [
949
- TestNode text: "child2a",
950
- texts: [
951
- "some more text",
952
- "some more text"
953
- ]
954
- TestNode text: "child2b",
955
- texts: [
956
- "some more text",
957
- "some more text"
958
- ]
959
- ]
960
- }
961
- ), output
962
- end
963
-
964
- def test_linebreak_comment
965
- testModel = TestMM::TestNode.new(
966
- :text => "some text",
967
- :comment => "this is a comment",
968
- :childs => [
969
- TestMM::TestNode.new(:comment => "\n\ncomment of a child node\n multiline\n\n\nanother\n\n\n")
970
- ])
971
-
972
- output = StringWriter.new
973
- serialize(testModel, TestMM, output,
974
- :newline_arguments => All_features,
975
- :comment_provider => proc { |e|
976
- c = e.comment
977
- e.comment = nil
978
- c
979
- })
980
-
981
- assert_equal %Q(\
982
- #this is a comment
983
- TestNode \\
984
- text: "some text" {
985
- #
986
- #
987
- #comment of a child node
988
- # multiline
989
- #
990
- #
991
- #another
992
- TestNode
993
- }
994
- ), output
995
- end
996
-
997
- def serialize(model, mm, output, options={})
998
- lang = RText::Language.new(mm.ecore, options)
999
- ser = RText::Serializer.new(lang)
1000
- ser.serialize(model, output)
1001
- end
1002
-
1003
- end
1004
-
1
+ $:.unshift File.join(File.dirname(__FILE__),"..","lib")
2
+
3
+ require 'minitest/autorun'
4
+ require 'bigdecimal'
5
+ require 'fileutils'
6
+ require 'stringio'
7
+ require 'rgen/environment'
8
+ require 'rgen/metamodel_builder'
9
+ require 'rtext/serializer'
10
+ require 'rtext/language'
11
+
12
+ class SerializerTest < MiniTest::Test
13
+ TestOutputFile = ".serializer_test_file"
14
+
15
+ def teardown
16
+ FileUtils.rm_f TestOutputFile
17
+ end
18
+
19
+ class StringWriter < String
20
+ alias write concat
21
+ end
22
+
23
+ module TestMM
24
+ extend RGen::MetamodelBuilder::ModuleExtension
25
+ SomeEnum = RGen::MetamodelBuilder::DataTypes::Enum.new(
26
+ :name => "SomeEnum", :literals => [:A, :B, :'non-word*chars', :'2you'])
27
+ class TestNode < RGen::MetamodelBuilder::MMBase
28
+ has_attr 'text', String
29
+ has_many_attr 'texts', String
30
+ has_many_attr 'more_texts', String
31
+ has_attr 'unlabled', String
32
+ has_attr 'unquoted', String
33
+ has_attr 'both', String
34
+ has_attr 'none', String
35
+ has_attr 'comment', String
36
+ has_attr 'integer', Integer
37
+ has_attr 'float', Float
38
+ has_attr 'enum', SomeEnum
39
+ has_attr 'boolean', Boolean
40
+ contains_many 'childs', TestNode, 'parent'
41
+ end
42
+ end
43
+
44
+ def test_simple
45
+ testModel = TestMM::TestNode.new(:text => "some text", :childs => [
46
+ TestMM::TestNode.new(:text => "child")])
47
+
48
+ output = StringWriter.new
49
+ serialize(testModel, TestMM, output)
50
+
51
+ assert_equal %Q(\
52
+ TestNode text: "some text" {
53
+ TestNode text: "child"
54
+ }
55
+ ), output
56
+ end
57
+
58
+ def test_many_attr
59
+ testModel = TestMM::TestNode.new(:texts => ["a", "b", "c"])
60
+
61
+ output = StringWriter.new
62
+ serialize(testModel, TestMM, output)
63
+
64
+ assert_equal %Q(\
65
+ TestNode texts: ["a", "b", "c"]
66
+ ), output
67
+ end
68
+
69
+ module TestMMFeatureProvider
70
+ extend RGen::MetamodelBuilder::ModuleExtension
71
+ class TestNode < RGen::MetamodelBuilder::MMBase
72
+ has_attr 'attr1', String
73
+ has_attr 'attr2', String
74
+ has_attr 'attr3', String
75
+ contains_many 'childs1', TestNode, 'parent1'
76
+ contains_many 'childs2', TestNode, 'parent2'
77
+ contains_many 'childs3', TestNode, 'parent3'
78
+ end
79
+ end
80
+
81
+ def test_feature_provider
82
+ testModel = TestMMFeatureProvider::TestNode.new(
83
+ :attr1 => "attr1",
84
+ :attr2 => "attr2",
85
+ :attr3 => "attr3",
86
+ :childs1 => [TestMMFeatureProvider::TestNode.new(:attr1 => "child1")],
87
+ :childs2 => [TestMMFeatureProvider::TestNode.new(:attr1 => "child2")],
88
+ :childs3 => [TestMMFeatureProvider::TestNode.new(:attr1 => "child3")])
89
+
90
+ output = StringWriter.new
91
+ serialize(testModel, TestMMFeatureProvider, output,
92
+ :feature_provider => proc {|clazz|
93
+ clazz.eAllStructuralFeatures.reject{|f| f.name =~ /parent|2$/}.reverse})
94
+
95
+ assert_equal %Q(\
96
+ TestNode attr3: "attr3", attr1: "attr1" {
97
+ childs3:
98
+ TestNode attr1: "child3"
99
+ childs1:
100
+ TestNode attr1: "child1"
101
+ }
102
+ ), output
103
+ end
104
+
105
+ module TestMMUnlabledUnquoted
106
+ extend RGen::MetamodelBuilder::ModuleExtension
107
+ class TestNode < RGen::MetamodelBuilder::MMBase
108
+ has_attr 'unlabled', String
109
+ has_attr 'unquoted', String
110
+ has_attr 'both', String
111
+ has_attr 'none', String
112
+ end
113
+ end
114
+
115
+ def test_unlabled_unquoted
116
+ testModel = [
117
+ TestMMUnlabledUnquoted::TestNode.new(:unlabled => "unlabled", :unquoted => "unquoted", :both => "both", :none => "none"),
118
+ TestMMUnlabledUnquoted::TestNode.new(:unquoted => "no identifier"),
119
+ TestMMUnlabledUnquoted::TestNode.new(:unquoted => "true"),
120
+ TestMMUnlabledUnquoted::TestNode.new(:unquoted => "333"),
121
+ TestMMUnlabledUnquoted::TestNode.new(:unquoted => "33.3"),
122
+ TestMMUnlabledUnquoted::TestNode.new(:unquoted => "5x"),
123
+ TestMMUnlabledUnquoted::TestNode.new(:unquoted => "//")
124
+ ]
125
+
126
+ output = StringWriter.new
127
+ serialize(testModel, TestMMUnlabledUnquoted, output,
128
+ :unlabled_arguments => proc {|clazz| ["unlabled", "both"]},
129
+ :unquoted_arguments => proc {|clazz| ["unquoted", "both"]}
130
+ )
131
+
132
+ assert_equal %Q(\
133
+ TestNode "unlabled", both, unquoted: unquoted, none: "none"
134
+ TestNode unquoted: "no identifier"
135
+ TestNode unquoted: "true"
136
+ TestNode unquoted: "333"
137
+ TestNode unquoted: "33.3"
138
+ TestNode unquoted: "5x"
139
+ TestNode unquoted: "//"
140
+ ), output
141
+ end
142
+
143
+ module TestMMComment
144
+ extend RGen::MetamodelBuilder::ModuleExtension
145
+ class TestNode < RGen::MetamodelBuilder::MMBase
146
+ has_attr 'comment', String
147
+ contains_many 'childs', TestNode, 'parent'
148
+ end
149
+ end
150
+
151
+ def test_comment_provider
152
+ testModel = TestMMComment::TestNode.new(
153
+ :comment => "this is a comment",
154
+ :childs => [
155
+ TestMMComment::TestNode.new(:comment => "\n\ncomment of a child node\n multiline\n\n\nanother\n\n\n"),
156
+ TestMMComment::TestNode.new(:comment => "don't show"),
157
+ TestMMComment::TestNode.new(:comment => "")])
158
+
159
+ output = StringWriter.new
160
+ serialize(testModel, TestMMComment, output,
161
+ :comment_provider => proc { |e|
162
+ if e.comment != "don't show"
163
+ c = e.comment
164
+ e.comment = nil
165
+ c
166
+ else
167
+ nil
168
+ end
169
+ })
170
+
171
+ assert_equal %Q(\
172
+ #this is a comment
173
+ TestNode {
174
+ #
175
+ #
176
+ #comment of a child node
177
+ # multiline
178
+ #
179
+ #
180
+ #another
181
+ TestNode
182
+ TestNode comment: "don't show"
183
+ TestNode
184
+ }
185
+ ), output
186
+ end
187
+
188
+ module TestMMAnnotation
189
+ extend RGen::MetamodelBuilder::ModuleExtension
190
+ class TestNode < RGen::MetamodelBuilder::MMBase
191
+ has_attr 'annotation', String
192
+ contains_many 'childs', TestNode, 'parent'
193
+ end
194
+ end
195
+
196
+ def test_annotation_provider
197
+ testModel = TestMMAnnotation::TestNode.new(
198
+ :annotation => "this is an annotation",
199
+ :childs => [
200
+ TestMMAnnotation::TestNode.new(:annotation => "annotation of a child node\n multiline"),
201
+ TestMMAnnotation::TestNode.new(:annotation => "don't show")])
202
+
203
+ output = StringWriter.new
204
+ serialize(testModel, TestMMAnnotation, output,
205
+ :annotation_provider => proc { |e|
206
+ if e.annotation != "don't show"
207
+ a = e.annotation
208
+ e.annotation = nil
209
+ a
210
+ else
211
+ nil
212
+ end
213
+ })
214
+
215
+ assert_equal %Q(\
216
+ @this is an annotation
217
+ TestNode {
218
+ @annotation of a child node
219
+ @ multiline
220
+ TestNode
221
+ TestNode annotation: "don't show"
222
+ }
223
+ ), output
224
+ end
225
+
226
+ def test_indent_string
227
+ testModel = TestMM::TestNode.new(:childs => [
228
+ TestMM::TestNode.new(:text => "child")])
229
+
230
+ output = StringWriter.new
231
+ serialize(testModel, TestMM, output, :indent_string => "____")
232
+
233
+ assert_equal %Q(\
234
+ TestNode {
235
+ ____TestNode text: "child"
236
+ }
237
+ ), output
238
+ end
239
+
240
+ module TestMMRef
241
+ extend RGen::MetamodelBuilder::ModuleExtension
242
+ class TestNode < RGen::MetamodelBuilder::MMBase
243
+ has_attr 'name', String
244
+ contains_many 'childs', TestNode, 'parent'
245
+ has_many 'refMany', TestNode
246
+ has_one 'refOne', TestNode
247
+ one_to_many 'refManyBi', TestNode, 'refManyBack'
248
+ one_to_one 'refOneBi', TestNode, 'refOneBack'
249
+ many_to_many 'refManyMany', TestNode, 'refManyManyBack'
250
+ end
251
+ end
252
+
253
+ def test_identifier_provider
254
+ testModel = [
255
+ TestMMRef::TestNode.new(:name => "Source"),
256
+ TestMMRef::TestNode.new(:name => "Target")]
257
+ testModel[0].refOne = testModel[1]
258
+
259
+ output = StringWriter.new
260
+ serialize(testModel, TestMMRef, output,
261
+ :identifier_provider => proc{|e, context, feature, index|
262
+ assert_equal testModel[0], context
263
+ assert_equal "refOne", feature.name
264
+ assert_equal 0, index
265
+ "/target/ref"
266
+ }
267
+ )
268
+
269
+ assert_equal %Q(\
270
+ TestNode name: "Source", refOne: /target/ref
271
+ TestNode name: "Target"
272
+ ),output
273
+ end
274
+
275
+ def test_identifier_provider_many
276
+ testModel = [
277
+ TestMMRef::TestNode.new(:name => "Source"),
278
+ TestMMRef::TestNode.new(:name => "Target1"),
279
+ TestMMRef::TestNode.new(:name => "Target2")]
280
+ testModel[0].addRefMany(testModel[1])
281
+ testModel[0].addRefMany(testModel[2])
282
+
283
+ output = StringWriter.new
284
+ call_index = 0
285
+ serialize(testModel, TestMMRef, output,
286
+ :identifier_provider => proc{|e, context, feature, index|
287
+ assert_equal testModel[0], context
288
+ assert_equal "refMany", feature.name
289
+ if call_index == 0
290
+ call_index += 1
291
+ assert_equal 0, index
292
+ "/target/ref1"
293
+ else
294
+ assert_equal 1, index
295
+ "/target/ref2"
296
+ end
297
+ }
298
+ )
299
+ assert_equal %Q(\
300
+ TestNode name: "Source", refMany: [/target/ref1, /target/ref2]
301
+ TestNode name: "Target1"
302
+ TestNode name: "Target2"
303
+ ),output
304
+ end
305
+
306
+ def test_identifier_provider_nil
307
+ testModel = [
308
+ TestMMRef::TestNode.new(:name => "Source"),
309
+ TestMMRef::TestNode.new(:name => "Target")]
310
+ testModel[0].refOne = testModel[1]
311
+
312
+ output = StringWriter.new
313
+ serialize(testModel, TestMMRef, output,
314
+ :identifier_provider => proc{|e, context, feature, index|
315
+ nil
316
+ }
317
+ )
318
+
319
+ assert_equal %Q(\
320
+ TestNode name: "Source"
321
+ TestNode name: "Target"
322
+ ),output
323
+ end
324
+
325
+ def test_references
326
+ testModel = [
327
+ TestMMRef::TestNode.new(:name => "Source"),
328
+ TestMMRef::TestNode.new(:name => "Target",
329
+ :childs => [
330
+ TestMMRef::TestNode.new(:name => "A",
331
+ :childs => [
332
+ TestMMRef::TestNode.new(:name => "A1")
333
+ ]),
334
+ TestMMRef::TestNode.new(:name => "B"),
335
+ ])
336
+ ]
337
+ testModel[0].refOne = testModel[1].childs[0].childs[0]
338
+ testModel[0].refOneBi = testModel[1].childs[0].childs[0]
339
+ testModel[0].refMany = [testModel[1].childs[0], testModel[1].childs[1]]
340
+ testModel[0].refManyBi = [testModel[1].childs[0], testModel[1].childs[1]]
341
+ testModel[0].refManyMany = [testModel[1].childs[0], testModel[1].childs[1]]
342
+ testModel[0].addRefMany(RGen::MetamodelBuilder::MMProxy.new("/some/ref"))
343
+
344
+ output = StringWriter.new
345
+ serialize(testModel, TestMMRef, output)
346
+
347
+ assert_equal %Q(\
348
+ TestNode name: "Source", refMany: [/Target/A, /Target/B, /some/ref], refOne: /Target/A/A1, refOneBi: /Target/A/A1
349
+ TestNode name: "Target" {
350
+ TestNode name: "A", refManyBack: /Source, refManyManyBack: /Source {
351
+ TestNode name: "A1"
352
+ }
353
+ TestNode name: "B", refManyBack: /Source, refManyManyBack: /Source
354
+ }
355
+ ), output
356
+ end
357
+
358
+ module TestMMChildRole
359
+ extend RGen::MetamodelBuilder::ModuleExtension
360
+ class TestNodeA < RGen::MetamodelBuilder::MMBase
361
+ has_attr 'text', String
362
+ end
363
+ class TestNodeB < RGen::MetamodelBuilder::MMBase
364
+ has_attr 'text', String
365
+ end
366
+ class TestNodeC < RGen::MetamodelBuilder::MMBase
367
+ has_attr 'text', String
368
+ end
369
+ class TestNodeD < RGen::MetamodelBuilder::MMBase
370
+ has_attr 'text3', String
371
+ end
372
+ class TestNodeE < RGen::MetamodelBuilder::MMMultiple(TestNodeC, TestNodeD)
373
+ has_attr 'text2', String
374
+ end
375
+ class TestNode < RGen::MetamodelBuilder::MMBase
376
+ has_attr 'text', String
377
+ has_many_attr 'texts', String
378
+ contains_one 'child1', TestNode, 'parent1'
379
+ contains_many 'childs2', TestNode, 'parent2'
380
+ contains_one 'child3', TestNodeA, 'parent3'
381
+ contains_many 'childs4', TestNodeB, 'parent4'
382
+ contains_one 'child5', TestNodeC, 'parent5'
383
+ contains_many 'childs6', TestNodeD, 'parent6'
384
+ contains_one 'child7', TestNodeE, 'parent7'
385
+ end
386
+ end
387
+
388
+ def test_child_role
389
+ testModel = TestMMChildRole::TestNode.new(
390
+ :child1 => TestMMChildRole::TestNode.new(:text => "child1"),
391
+ :childs2 => [
392
+ TestMMChildRole::TestNode.new(:text => "child2a"),
393
+ TestMMChildRole::TestNode.new(:text => "child2b")
394
+ ],
395
+ :child3 => TestMMChildRole::TestNodeA.new(:text => "child3"),
396
+ :childs4 => [TestMMChildRole::TestNodeB.new(:text => "child4")],
397
+ :child5 => TestMMChildRole::TestNodeC.new(:text => "child5"),
398
+ :childs6 => [TestMMChildRole::TestNodeD.new(:text3 => "child6"), TestMMChildRole::TestNodeE.new(:text => "child6.1")],
399
+ :child7 => TestMMChildRole::TestNodeE.new(:text2 => "child7")
400
+ )
401
+
402
+ output = StringWriter.new
403
+ serialize(testModel, TestMMChildRole, output)
404
+
405
+ assert_equal %Q(\
406
+ TestNode {
407
+ child1:
408
+ TestNode text: "child1"
409
+ childs2: [
410
+ TestNode text: "child2a"
411
+ TestNode text: "child2b"
412
+ ]
413
+ TestNodeA text: "child3"
414
+ TestNodeB text: "child4"
415
+ TestNodeC text: "child5"
416
+ childs6: [
417
+ TestNodeD text3: "child6"
418
+ TestNodeE text: "child6.1"
419
+ ]
420
+ child7:
421
+ TestNodeE text2: "child7"
422
+ }
423
+ ), output
424
+ end
425
+
426
+ module TestMMLabeledContainment
427
+ extend RGen::MetamodelBuilder::ModuleExtension
428
+ class TestNode < RGen::MetamodelBuilder::MMBase
429
+ abstract
430
+ has_attr 'text', String
431
+ contains_many 'childs', TestNode, 'parent'
432
+ end
433
+ class TestNode1 < TestNode
434
+ end
435
+ class TestNode2 < TestNode
436
+ end
437
+ end
438
+
439
+ def test_labeled_containment
440
+ testModel = TestMMLabeledContainment::TestNode1.new(:text => "some text", :childs => [
441
+ TestMMLabeledContainment::TestNode2.new(:text => "child", :childs => [
442
+ TestMMLabeledContainment::TestNode1.new(:text => "nested child")
443
+ ])])
444
+
445
+ output = StringWriter.new
446
+ serialize(testModel, TestMMLabeledContainment, output, :labeled_containments => proc {|c|
447
+ if c == TestMMLabeledContainment::TestNode2.ecore
448
+ ["childs"]
449
+ else
450
+ []
451
+ end
452
+ })
453
+
454
+ assert_equal %Q(\
455
+ TestNode1 text: "some text" {
456
+ TestNode2 text: "child" {
457
+ childs:
458
+ TestNode1 text: "nested child"
459
+ }
460
+ }
461
+ ), output
462
+ end
463
+
464
+ def test_escapes
465
+ testModel = TestMM::TestNode.new(:text => %Q(some " \\ \\" text \r xx \n xx \r\n xx \t xx \b xx \f))
466
+ output = StringWriter.new
467
+ serialize(testModel, TestMM, output)
468
+
469
+ assert_equal %q(TestNode text: "some \" \\\\ \\\\\" text \r xx \n xx \r\n xx \t xx \b xx \f")+"\n", output
470
+ end
471
+
472
+ def test_integer
473
+ testModel = TestMM::TestNode.new(:integer => 7)
474
+ output = StringWriter.new
475
+ serialize(testModel, TestMM, output)
476
+ assert_equal %q(TestNode integer: 7)+"\n", output
477
+ end
478
+
479
+ def test_integer_big
480
+ testModel = TestMM::TestNode.new(:integer => 12345678901234567890)
481
+ output = StringWriter.new
482
+ serialize(testModel, TestMM, output)
483
+ assert_equal %q(TestNode integer: 12345678901234567890)+"\n", output
484
+ end
485
+
486
+ def test_integer_format_spec
487
+ testModel = TestMM::TestNode.new(:integer => 10)
488
+ output = StringWriter.new
489
+ serialize(testModel, TestMM, output, :argument_format_provider => proc {|a|
490
+ if a.name == "integer"
491
+ "0x%02X"
492
+ else
493
+ nil
494
+ end})
495
+ assert_equal %q(TestNode integer: 0x0A)+"\n", output
496
+ end
497
+
498
+ def test_integer_format_spec_big
499
+ testModel = TestMM::TestNode.new(:integer => 0xabcdefabcdefabcdef)
500
+ output = StringWriter.new
501
+ serialize(testModel, TestMM, output, :argument_format_provider => proc {|a|
502
+ if a.name == "integer"
503
+ "0x%x"
504
+ else
505
+ nil
506
+ end})
507
+ assert_equal %q(TestNode integer: 0xabcdefabcdefabcdef)+"\n", output
508
+ end
509
+
510
+ def test_float
511
+ testModel = TestMM::TestNode.new(:float => 1.23)
512
+ output = StringWriter.new
513
+ serialize(testModel, TestMM, output)
514
+ assert_equal %q(TestNode float: 1.23)+"\n", output
515
+ end
516
+
517
+ def test_float2
518
+ testModel = TestMM::TestNode.new(:float => 1.23e-08)
519
+ output = StringWriter.new
520
+ serialize(testModel, TestMM, output)
521
+ assert output =~ /TestNode float: 1.23e-0?08\n/
522
+ end
523
+
524
+ def test_float_format_spec
525
+ testModel = TestMM::TestNode.new(:float => 1.23)
526
+ output = StringWriter.new
527
+ serialize(testModel, TestMM, output, :argument_format_provider => proc {|a|
528
+ if a.name == "float"
529
+ "%1.1f"
530
+ else
531
+ nil
532
+ end})
533
+ assert_equal %q(TestNode float: 1.2)+"\n", output
534
+ end
535
+
536
+ def test_float_big_decimal
537
+ begin
538
+ testModel = TestMM::TestNode.new(:float => BigDecimal.new("1234567890.123456789"))
539
+ rescue StandardError
540
+ return
541
+ end
542
+ output = StringWriter.new
543
+ serialize(testModel, TestMM, output)
544
+ assert_equal %q(TestNode float: 1234567890.123456789)+"\n", output
545
+ end
546
+
547
+ def test_enum
548
+ testModel = [
549
+ TestMM::TestNode.new(:enum => :A),
550
+ TestMM::TestNode.new(:enum => :B),
551
+ TestMM::TestNode.new(:enum => :'non-word*chars'),
552
+ TestMM::TestNode.new(:enum => :'2you')
553
+ ]
554
+ output = StringWriter.new
555
+ serialize(testModel, TestMM, output)
556
+ assert_equal %Q(\
557
+ TestNode enum: A
558
+ TestNode enum: B
559
+ TestNode enum: "non-word*chars"
560
+ TestNode enum: "2you"
561
+ ), output
562
+ end
563
+
564
+ def test_generic
565
+ testModel = [
566
+ TestMM::TestNode.new(:text => RText::Generic.new("some text angel >bracket")),
567
+ TestMM::TestNode.new(:text => RText::Generic.new("some text percent angel %>bracket")),
568
+ TestMM::TestNode.new(:text => RText::Generic.new("some text > percent angel%>bracket")),
569
+ TestMM::TestNode.new(:integer => RText::Generic.new("a number: 1")),
570
+ TestMM::TestNode.new(:float => RText::Generic.new("precision")),
571
+ TestMM::TestNode.new(:enum => RText::Generic.new("an option")),
572
+ TestMM::TestNode.new(:boolean => RText::Generic.new("falsy"))
573
+ ]
574
+ output = StringWriter.new
575
+ serialize(testModel, TestMM, output)
576
+ assert_equal %Q(\
577
+ TestNode text: <%some text angel >bracket%>
578
+ TestNode text: <some text percent angel >
579
+ TestNode text: <%some text > percent angel%>
580
+ TestNode integer: <a number: 1>
581
+ TestNode float: <precision>
582
+ TestNode enum: <an option>
583
+ TestNode boolean: <falsy>
584
+ ), output
585
+ end
586
+
587
+ module TestMMData
588
+ extend RGen::MetamodelBuilder::ModuleExtension
589
+ # class "Data" exists in the standard Ruby namespace
590
+ class Data < RGen::MetamodelBuilder::MMBase
591
+ has_attr 'notTheBuiltin', String
592
+ end
593
+ end
594
+
595
+ module TestMMSubpackage
596
+ extend RGen::MetamodelBuilder::ModuleExtension
597
+ module SubPackage
598
+ extend RGen::MetamodelBuilder::ModuleExtension
599
+ class Data < RGen::MetamodelBuilder::MMBase
600
+ has_attr 'notTheBuiltin', String
601
+ end
602
+ class Data2 < RGen::MetamodelBuilder::MMBase
603
+ has_attr 'data2', String
604
+ end
605
+ end
606
+ end
607
+
608
+ def test_subpackage
609
+ testModel = TestMMSubpackage::SubPackage::Data2.new(:data2 => "xxx")
610
+ output = StringWriter.new
611
+ serialize(testModel, TestMMSubpackage, output)
612
+ assert_equal %q(Data2 data2: "xxx")+"\n", output
613
+ end
614
+
615
+ def test_command_name_provider
616
+ testModel = TestMM::TestNode.new(:text => "some text", :childs => [
617
+ TestMM::TestNode.new(:text => "child")])
618
+
619
+ output = StringWriter.new
620
+ serialize(testModel, TestMM, output, :command_name_provider => proc do |c|
621
+ c.name + "X"
622
+ end)
623
+
624
+ assert_equal %Q(\
625
+ TestNodeX text: "some text" {
626
+ TestNodeX text: "child"
627
+ }
628
+ ), output
629
+ end
630
+
631
+ def test_file_output
632
+ testModel = TestMM::TestNode.new(:text => "some text")
633
+
634
+ File.open(TestOutputFile, "w") do |f|
635
+ serialize(testModel, TestMM, f)
636
+ end
637
+
638
+ assert_equal %Q(\
639
+ TestNode text: "some text"
640
+ ), File.read(TestOutputFile)
641
+ end
642
+
643
+ def test_stringio_output
644
+ testModel = TestMM::TestNode.new(:text => "some text")
645
+
646
+ output = StringIO.new
647
+ serialize(testModel, TestMM, output)
648
+
649
+ assert_equal %Q(\
650
+ TestNode text: "some text"
651
+ ), output.string
652
+ end
653
+
654
+ #
655
+ # line breaks
656
+ #
657
+ All_features = proc {|clazz|
658
+ res = []
659
+ clazz.eAllStructuralFeatures.reject{|f| f.name =~ /parent|2$/}.each{|f| res << f.name}
660
+ res
661
+ }
662
+
663
+ def test_linebreak
664
+ testModel = TestMM::TestNode.new(
665
+ :text => "some text",
666
+ :texts => ["some more text", "some more text", "some more text"])
667
+
668
+ output = StringWriter.new
669
+ serialize(testModel, TestMM, output,
670
+ :newline_arguments => All_features,
671
+ :newline_arrays => All_features)
672
+
673
+ assert_equal %Q(\
674
+ TestNode \\
675
+ text: "some text",
676
+ texts: [
677
+ "some more text",
678
+ "some more text",
679
+ "some more text"
680
+ ]
681
+ ), output
682
+ end
683
+
684
+ def test_linebreak_child
685
+ testModel1 = TestMM::TestNode.new(
686
+ :text => "some text1",
687
+ :texts => ["some more text", "some more text", "some more text"])
688
+ testModel0 = TestMM::TestNode.new(
689
+ :text => "some text0",
690
+ :integer => 10,
691
+ :childs => [testModel1])
692
+
693
+ output = StringWriter.new
694
+ serialize(testModel0, TestMM, output,
695
+ :newline_arguments => All_features,
696
+ :newline_arrays => All_features)
697
+
698
+ assert_equal %Q(\
699
+ TestNode \\
700
+ text: "some text0",
701
+ integer: 10 {
702
+ TestNode \\
703
+ text: "some text1",
704
+ texts: [
705
+ "some more text",
706
+ "some more text",
707
+ "some more text"
708
+ ]
709
+ }
710
+ ), output
711
+ end
712
+
713
+ def test_linebreak_child_no_arguments
714
+ testModel1 = TestMM::TestNode.new(
715
+ :text => "some text1",
716
+ :texts => ["some more text", "some more text", "some more text"])
717
+ testModel0 = TestMM::TestNode.new(:childs => [testModel1])
718
+
719
+ output = StringWriter.new
720
+ serialize(testModel0, TestMM, output,
721
+ :newline_arguments => All_features,
722
+ :newline_arrays => All_features)
723
+
724
+ assert_equal %Q(\
725
+ TestNode {
726
+ TestNode \\
727
+ text: "some text1",
728
+ texts: [
729
+ "some more text",
730
+ "some more text",
731
+ "some more text"
732
+ ]
733
+ }
734
+ ), output
735
+ end
736
+
737
+ def test_linebreak_unlabled_array_arguments
738
+ testModel = TestMM::TestNode.new(
739
+ :none => "some text",
740
+ :texts => ["some more text", "some more text", "some more text"])
741
+
742
+ output = StringWriter.new
743
+ serialize(testModel, TestMM, output,
744
+ :unlabled_arguments => proc {|clazz| ["texts"]},
745
+ :newline_arguments => proc {|clazz| All_features.call(clazz) - ["texts"]},
746
+ :newline_arrays => All_features)
747
+
748
+ assert_equal %Q(\
749
+ TestNode [
750
+ "some more text",
751
+ "some more text",
752
+ "some more text"
753
+ ],
754
+ none: "some text"
755
+ ), output
756
+ end
757
+
758
+ def test_linebreak_unlabled_array_arguments_sameline
759
+ testModel = TestMM::TestNode.new(
760
+ :none => "some text",
761
+ :texts => ["some more text", "some more text", "some more text"])
762
+
763
+ output = StringWriter.new
764
+ serialize(testModel, TestMM, output,
765
+ :unlabled_arguments => proc {|clazz| ["texts"]},
766
+ :newline_arguments => proc {|clazz| All_features.call(clazz) - ["texts"]},
767
+ :newline_arrays => proc {|clazz| All_features.call(clazz) - ["texts"]})
768
+
769
+ assert_equal %Q(\
770
+ TestNode ["some more text", "some more text", "some more text"],
771
+ none: "some text"
772
+ ), output
773
+ end
774
+
775
+ def test_linebreak_unlabled_both_arguments_and_child
776
+ testModel1 = TestMM::TestNode.new(
777
+ :texts => ["some more text", "some more text", "some more text"])
778
+ testModel0 = TestMM::TestNode.new(
779
+ :unlabled => "unlabled",
780
+ :both => "both",
781
+ :childs => [testModel1])
782
+
783
+ output = StringWriter.new
784
+ serialize(testModel0, TestMM, output,
785
+ :unlabled_arguments => proc {|clazz| ["unlabled", "both"]},
786
+ :unquoted_arguments => proc {|clazz| ["both"]},
787
+ :newline_arguments => proc {|clazz| All_features.call(clazz) - ["unlabled"]},
788
+ :newline_arrays => All_features)
789
+
790
+ assert_equal %Q(\
791
+ TestNode "unlabled",
792
+ both {
793
+ TestNode \\
794
+ texts: [
795
+ "some more text",
796
+ "some more text",
797
+ "some more text"
798
+ ]
799
+ }
800
+ ), output
801
+ end
802
+
803
+ def test_linebreak_child_two_attributes
804
+ testModel1 = TestMM::TestNode.new(
805
+ :text => "some text1",
806
+ :texts => ["some more text", "some more text", "some more text"],
807
+ :more_texts => ["even more text", "even more text"])
808
+ testModel0 = TestMM::TestNode.new(:text => "some text0", :childs => [testModel1])
809
+
810
+ output = StringWriter.new
811
+ serialize(testModel0, TestMM, output,
812
+ :newline_arguments => proc {|clazz| All_features.call(clazz) - ["text"]},
813
+ :newline_arrays => proc {|clazz| All_features.call(clazz) - ["text"]})
814
+
815
+ assert_equal %Q(\
816
+ TestNode text: "some text0" {
817
+ TestNode text: "some text1",
818
+ texts: [
819
+ "some more text",
820
+ "some more text",
821
+ "some more text"
822
+ ],
823
+ more_texts: [
824
+ "even more text",
825
+ "even more text"
826
+ ]
827
+ }
828
+ ), output
829
+ end
830
+
831
+ def test_linebreak_child_two_attributes_one_sameline
832
+ testModel1 = TestMM::TestNode.new(
833
+ :text => "some text1",
834
+ :texts => ["some more text", "some more text", "some more text"],
835
+ :more_texts => ["even more text", "even more text"])
836
+ testModel0 = TestMM::TestNode.new(:text => "some text0", :childs => [testModel1])
837
+
838
+ output = StringWriter.new
839
+ serialize(testModel0, TestMM, output,
840
+ :newline_arguments => proc {|clazz| All_features.call(clazz) - ["more_texts"]},
841
+ :newline_arrays => proc {|clazz| All_features.call(clazz) - ["more_texts"]})
842
+
843
+ assert_equal %Q(\
844
+ TestNode \\
845
+ text: "some text0" {
846
+ TestNode \\
847
+ text: "some text1",
848
+ texts: [
849
+ "some more text",
850
+ "some more text",
851
+ "some more text"
852
+ ], more_texts: ["even more text", "even more text"]
853
+ }
854
+ ), output
855
+ end
856
+
857
+ def test_linebreak_two_children
858
+ testModel2 = TestMM::TestNode.new(:text => "some text2", :texts => ["some more text"])
859
+ testModel1 = TestMM::TestNode.new(:text => "some text1", :texts => ["some more text", "some more text", "some more text"])
860
+ testModel0 = TestMM::TestNode.new(:text => "some text0", :childs => [testModel1, testModel2])
861
+
862
+ output = StringWriter.new
863
+ serialize(testModel0, TestMM, output,
864
+ :newline_arguments => proc {|clazz| All_features.call(clazz) - ["text"]},
865
+ :newline_arrays => All_features)
866
+
867
+ assert_equal %Q(\
868
+ TestNode text: "some text0" {
869
+ TestNode text: "some text1",
870
+ texts: [
871
+ "some more text",
872
+ "some more text",
873
+ "some more text"
874
+ ]
875
+ TestNode text: "some text2",
876
+ texts: "some more text"
877
+ }
878
+ ), output
879
+ end
880
+
881
+ def test_linebreak_nested_children
882
+ testModel2 = TestMM::TestNode.new(
883
+ :text => "some text2",
884
+ :texts => ["some more text", "some more text", "some more text"])
885
+ testModel1 = TestMM::TestNode.new(
886
+ :text => "some text1",
887
+ :childs => [testModel2])
888
+ testModel0 = TestMM::TestNode.new(
889
+ :text => "some text0",
890
+ :integer => 10,
891
+ :childs => [testModel1])
892
+
893
+ output = StringWriter.new
894
+ serialize(testModel0, TestMM, output,
895
+ :newline_arguments => All_features,
896
+ :newline_arrays => All_features)
897
+
898
+ assert_equal %Q(\
899
+ TestNode \\
900
+ text: "some text0",
901
+ integer: 10 {
902
+ TestNode \\
903
+ text: "some text1" {
904
+ TestNode \\
905
+ text: "some text2",
906
+ texts: [
907
+ "some more text",
908
+ "some more text",
909
+ "some more text"
910
+ ]
911
+ }
912
+ }
913
+ ), output
914
+ end
915
+
916
+ def test_linebreak_no_break
917
+ testModel = TestMM::TestNode.new(:text => "some text", :texts => ["some more text", "some more text", "some more text"])
918
+
919
+ output = StringWriter.new
920
+ serialize(testModel, TestMM, output)
921
+
922
+ assert_equal %Q(\
923
+ TestNode text: "some text", texts: ["some more text", "some more text", "some more text"]
924
+ ), output
925
+ end
926
+
927
+ def test_linebreak_child_role
928
+ testModel = TestMMChildRole::TestNode.new(
929
+ :child1 => TestMMChildRole::TestNode.new(:text => "child1"),
930
+ :childs2 => [
931
+ TestMMChildRole::TestNode.new(
932
+ :text => "child2a",
933
+ :texts => ["some more text", "some more text"]),
934
+ TestMMChildRole::TestNode.new(
935
+ :text => "child2b",
936
+ :texts => ["some more text", "some more text"])
937
+ ])
938
+
939
+ output = StringWriter.new
940
+ serialize(testModel, TestMMChildRole, output,
941
+ :newline_arguments => proc {|clazz| All_features.call(clazz) - ["text"]},
942
+ :newline_arrays => proc {|clazz| All_features.call(clazz) - ["text"]})
943
+
944
+ assert_equal %Q(\
945
+ TestNode {
946
+ child1:
947
+ TestNode text: "child1"
948
+ childs2: [
949
+ TestNode text: "child2a",
950
+ texts: [
951
+ "some more text",
952
+ "some more text"
953
+ ]
954
+ TestNode text: "child2b",
955
+ texts: [
956
+ "some more text",
957
+ "some more text"
958
+ ]
959
+ ]
960
+ }
961
+ ), output
962
+ end
963
+
964
+ def test_linebreak_comment
965
+ testModel = TestMM::TestNode.new(
966
+ :text => "some text",
967
+ :comment => "this is a comment",
968
+ :childs => [
969
+ TestMM::TestNode.new(:comment => "\n\ncomment of a child node\n multiline\n\n\nanother\n\n\n")
970
+ ])
971
+
972
+ output = StringWriter.new
973
+ serialize(testModel, TestMM, output,
974
+ :newline_arguments => All_features,
975
+ :comment_provider => proc { |e|
976
+ c = e.comment
977
+ e.comment = nil
978
+ c
979
+ })
980
+
981
+ assert_equal %Q(\
982
+ #this is a comment
983
+ TestNode \\
984
+ text: "some text" {
985
+ #
986
+ #
987
+ #comment of a child node
988
+ # multiline
989
+ #
990
+ #
991
+ #another
992
+ TestNode
993
+ }
994
+ ), output
995
+ end
996
+
997
+ module TestMMObjectAttribute
998
+ extend RGen::MetamodelBuilder::ModuleExtension
999
+ class TestNode < RGen::MetamodelBuilder::MMBase
1000
+ has_many_attr 'objs', Object
1001
+ end
1002
+ end
1003
+
1004
+ def test_object_attribute
1005
+ testModel = TestMMObjectAttribute::TestNode.new(
1006
+ :objs => ['some text', -123, :someSymbol, true, false, -0.097, :'some other symbol'])
1007
+
1008
+ output = StringWriter.new
1009
+ serialize(testModel, TestMMObjectAttribute, output)
1010
+
1011
+ assert_equal %Q(\
1012
+ TestNode objs: ["some text", -123, someSymbol, true, false, -0.097, "some other symbol"]
1013
+ ), output
1014
+ end
1015
+
1016
+ def serialize(model, mm, output, options={})
1017
+ lang = RText::Language.new(mm.ecore, options)
1018
+ ser = RText::Serializer.new(lang)
1019
+ ser.serialize(model, output)
1020
+ end
1021
+
1022
+ end
1023
+