rtext 0.8.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+