rtext 0.9.0 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,1733 +1,1773 @@
1
- # coding: binary
2
- $:.unshift File.join(File.dirname(__FILE__),"..","lib")
3
-
4
- gem 'minitest'
5
- require 'minitest/autorun'
6
- require 'bigdecimal'
7
- require 'rgen/environment'
8
- require 'rgen/metamodel_builder'
9
- require 'rtext/instantiator'
10
- require 'rtext/language'
11
-
12
- class InstantiatorTest < MiniTest::Test
13
-
14
- module TestMM
15
- extend RGen::MetamodelBuilder::ModuleExtension
16
- class TestNode < RGen::MetamodelBuilder::MMBase
17
- SomeEnum = RGen::MetamodelBuilder::DataTypes::Enum.new([:A, :B, :'non-word*chars', :'2you'])
18
- has_attr 'text', String
19
- has_attr 'integer', Integer
20
- has_attr 'boolean', Boolean
21
- has_attr 'enum', SomeEnum
22
- has_many_attr 'nums', Integer
23
- has_attr 'float', Float
24
- has_one 'related', TestNode
25
- has_many 'others', TestNode
26
- contains_many 'childs', TestNode, 'parent'
27
- end
28
- class SubNode < TestNode
29
- end
30
- end
31
-
32
- module TestMM2
33
- extend RGen::MetamodelBuilder::ModuleExtension
34
- class TestNode < RGen::MetamodelBuilder::MMBase
35
- contains_one 'singleChild', TestNode, 'parent'
36
- end
37
- class TestNode2 < RGen::MetamodelBuilder::MMBase
38
- end
39
- class TestNode3 < RGen::MetamodelBuilder::MMBase
40
- end
41
- class TestNode4 < TestNode
42
- end
43
- TestNode.contains_one 'singleChild2a', TestNode2, 'parentA'
44
- TestNode.contains_one 'singleChild2b', TestNode2, 'parentB'
45
- end
46
-
47
- module TestMMLinenoFilenameFragment
48
- extend RGen::MetamodelBuilder::ModuleExtension
49
- class TestNode < RGen::MetamodelBuilder::MMBase
50
- has_attr 'text', String
51
- has_attr 'lineno', Integer
52
- has_attr 'filename', String
53
- has_attr 'fragmentr', String
54
- contains_many 'childs', TestNode, 'parent'
55
- end
56
- end
57
-
58
- module TestMMAbstract
59
- extend RGen::MetamodelBuilder::ModuleExtension
60
- class TestNode < RGen::MetamodelBuilder::MMBase
61
- abstract
62
- end
63
- end
64
-
65
- module TestMMData
66
- extend RGen::MetamodelBuilder::ModuleExtension
67
- # class "Data" exists in the standard Ruby namespace
68
- class Data < RGen::MetamodelBuilder::MMBase
69
- has_attr 'notTheBuiltin', String
70
- end
71
- end
72
-
73
- module TestMMSubpackage
74
- extend RGen::MetamodelBuilder::ModuleExtension
75
- module SubPackage
76
- extend RGen::MetamodelBuilder::ModuleExtension
77
- class TestNodeSub < RGen::MetamodelBuilder::MMBase
78
- has_attr 'text', String
79
- end
80
- class Data < RGen::MetamodelBuilder::MMBase
81
- has_attr 'notTheBuiltin', String
82
- end
83
- end
84
- end
85
-
86
- module TestMMNonRootClass
87
- extend RGen::MetamodelBuilder::ModuleExtension
88
- class NonRootClass < RGen::MetamodelBuilder::MMBase
89
- end
90
- end
91
-
92
- module TestMMContextSensitiveCommands
93
- extend RGen::MetamodelBuilder::ModuleExtension
94
- module SubPackage2
95
- extend RGen::MetamodelBuilder::ModuleExtension
96
- class Command < RGen::MetamodelBuilder::MMBase
97
- end
98
- end
99
- module SubPackage1
100
- extend RGen::MetamodelBuilder::ModuleExtension
101
- class Command < RGen::MetamodelBuilder::MMBase
102
- contains_one 'command', SubPackage2::Command, 'super'
103
- end
104
- end
105
- class TestNode < RGen::MetamodelBuilder::MMBase
106
- contains_one 'command', SubPackage1::Command, 'testNode'
107
- end
108
- end
109
-
110
- def test_simple
111
- env, problems = instantiate(%Q(
112
- TestNode text: "some text", nums: [1,2] {
113
- TestNode text: "child"
114
- TestNode text: "child2"
115
- }
116
- ), TestMM)
117
- assert_no_problems(problems)
118
- assert_model_simple(env, :with_nums)
119
- end
120
-
121
- def test_multiple_roots
122
- env, problems = instantiate(%Q(
123
- TestNode
124
- TestNode
125
- ), TestMM)
126
- assert_no_problems(problems)
127
- assert_equal 2, env.elements.size
128
- end
129
-
130
- def test_comment
131
- env, problems = instantiate(%Q(
132
- # comment 1
133
- TestNode text: "some text" {# comment 1.1
134
- childs: [ # comment 1.2
135
- # comment 2
136
- TestNode text: "child" # comment 2.1
137
- # comment 3
138
- TestNode text: "child2" #comment 3.1
139
- # unassociated
140
- ] # comment 1.3
141
- # unassociated
142
- } # comment 1.4
143
- #comment 1
144
- TestNode { #comment 1.1
145
- childs: # comment 1.2
146
- TestNode text: "child" #comment2
147
- # unassociated
148
- }# comment 1.3
149
- # unassociated
150
- ), TestMM)
151
- assert_no_problems(problems)
152
- assert_model_simple(env)
153
- end
154
-
155
- def test_comment_only
156
- env, problems = instantiate(%Q(
157
- # comment 1
158
- ), TestMM)
159
- assert_no_problems(problems)
160
- end
161
-
162
- def test_empty
163
- env, problems = instantiate("", TestMM)
164
- assert_no_problems(problems)
165
- end
166
-
167
- #
168
- # options
169
- #
170
-
171
- def test_line_number_setter
172
- env, problems = instantiate(%q(
173
- TestNode text: "node1" {
174
- TestNode text: "node2"
175
-
176
- #some comment
177
- TestNode text: "node3"
178
- }
179
- TestNode text: "node4"
180
- ), TestMMLinenoFilenameFragment, :line_number_attribute => "lineno")
181
- assert_no_problems(problems)
182
- assert_equal 2, env.find(:text => "node1").first.lineno
183
- assert_equal 3, env.find(:text => "node2").first.lineno
184
- assert_equal 6, env.find(:text => "node3").first.lineno
185
- assert_equal 8, env.find(:text => "node4").first.lineno
186
- end
187
-
188
- def test_missing_line_number_setter
189
- env, problems = instantiate(%Q(
190
- TestNode text: A
191
- ), TestMMLinenoFilenameFragment, :line_number_attribute => "wrong_attribute_name")
192
- assert_no_problems(problems)
193
- assert_nil env.elements.first.lineno
194
- end
195
-
196
- def test_root_elements
197
- root_elements = []
198
- env, problems = instantiate(%Q(
199
- TestNode text: A
200
- TestNode text: B
201
- TestNode text: C
202
- ), TestMM, :root_elements => root_elements)
203
- assert_no_problems(problems)
204
- assert_equal ["A", "B", "C"], root_elements.text
205
- end
206
-
207
- def test_file_name_option
208
- env, problems = instantiate(%Q(
209
- TestNode text: A
210
- TestNode text: B
211
- TestNode a problem here
212
- ), TestMM, :file_name => "some_file")
213
- assert_equal "some_file", problems.first.file
214
- end
215
-
216
- def test_file_name_setter
217
- env, problems = instantiate(%Q(
218
- TestNode text: A
219
- ), TestMMLinenoFilenameFragment, :file_name => "some_file", :file_name_attribute => "filename")
220
- assert_equal "some_file", env.elements.first.filename
221
- end
222
-
223
- def test_missing_file_name_setter
224
- env, problems = instantiate(%Q(
225
- TestNode text: A
226
- ), TestMMLinenoFilenameFragment, :file_name => "some_file", :file_name_attribute => "wrong_attribute_name")
227
- assert_nil env.elements.first.filename
228
- end
229
-
230
- def test_fragment_ref_setter
231
- the_ref = "is a string here but would normally be an RGen fragment"
232
- env, problems = instantiate(%Q(
233
- TestNode text: A
234
- ), TestMMLinenoFilenameFragment, :fragment_ref => the_ref, :fragment_ref_attribute => "fragmentr")
235
- assert_equal the_ref.object_id, env.elements.first.fragmentr.object_id
236
- end
237
-
238
- def test_missing_fragment_ref_setter
239
- the_ref = "is a string here but would normally be an RGen fragment"
240
- env, problems = instantiate(%Q(
241
- TestNode text: A
242
- ), TestMMLinenoFilenameFragment, :fragment_ref => the_ref, :fragment_ref_attribute => "wrong_attribute_name")
243
- assert_nil env.elements.first.fragmentr
244
- end
245
-
246
- #
247
- # children with role
248
- #
249
-
250
- def test_child_role
251
- env, problems = instantiate(%Q(
252
- TestNode text: "some text" {
253
- TestNode text: "child"
254
- childs:
255
- TestNode text: "child2"
256
- }
257
- ), TestMM)
258
- assert_no_problems(problems)
259
- assert_model_simple(env)
260
- end
261
-
262
- def test_child_role2
263
- env, problems = instantiate(%Q(
264
- TestNode text: "some text" {
265
- childs: [
266
- TestNode text: "child"
267
- TestNode text: "child2"
268
- ]
269
- }
270
- ), TestMM)
271
- assert_no_problems(problems)
272
- assert_model_simple(env)
273
- end
274
-
275
- def test_child_role3
276
- env, problems = instantiate(%Q(
277
- TestNode text: "some text" {
278
- childs:
279
- TestNode text: "child"
280
- childs:
281
- TestNode text: "child2"
282
- }
283
- ), TestMM)
284
- assert_no_problems(problems)
285
- assert_model_simple(env)
286
- end
287
-
288
- def test_child_role4
289
- env, problems = instantiate(%Q(
290
- TestNode text: "some text" {
291
- childs: [
292
- TestNode text: "child"
293
- ]
294
- childs: [
295
- TestNode text: "child2"
296
- ]
297
- }
298
- ), TestMM)
299
- assert_no_problems(problems)
300
- assert_model_simple(env)
301
- end
302
-
303
- def test_child_role_empty
304
- env, problems = instantiate(%Q(
305
- TestNode {
306
- childs: [
307
- ]
308
- }
309
- ), TestMM)
310
- assert_no_problems(problems)
311
- end
312
-
313
-
314
- #
315
- # whitespace
316
- #
317
-
318
- def test_whitespace1
319
- env, problems = instantiate(%Q(
320
- TestNode text: "some text" , nums: [ 1 , 2 ] {
321
-
322
- # comment
323
-
324
- TestNode text: "child"
325
-
326
- TestNode text: "child2"
327
-
328
- }
329
- ), TestMM)
330
- assert_no_problems(problems)
331
- assert_model_simple(env, :with_nums)
332
- end
333
-
334
- def test_whitespace2
335
- env, problems = instantiate(%Q(
336
- # comment1
337
-
338
- # comment2
339
-
340
- TestNode text: "some text" {
341
-
342
- childs:
343
-
344
- # comment
345
-
346
- TestNode text: "child"
347
-
348
- childs: [
349
-
350
- TestNode text: "child2"
351
-
352
- ]
353
-
354
- }
355
- ), TestMM)
356
- assert_no_problems(problems)
357
- assert_model_simple(env)
358
- end
359
-
360
- def test_no_newline_at_eof
361
- env, problems = instantiate(%Q(
362
- TestNode), TestMM)
363
- assert_no_problems(problems)
364
- end
365
-
366
- def test_no_newline_at_eof2
367
- env, problems = instantiate(%Q(
368
- TestNode {
369
- }), TestMM)
370
- assert_no_problems(problems)
371
- end
372
-
373
- #
374
- # references
375
- #
376
-
377
- def test_references
378
- unresolved_refs = []
379
- env, problems = instantiate(%Q(
380
- TestNode text: "root" {
381
- TestNode related: /
382
- TestNode related: //
383
- TestNode related: /some
384
- TestNode related: //some
385
- TestNode related: /some/
386
- TestNode related: some/
387
- TestNode related: some//
388
- TestNode related: some
389
- TestNode related: /some/reference
390
- TestNode related: /some/reference/
391
- TestNode related: some/reference/
392
- TestNode related: some/reference
393
- }
394
- ), TestMM, :unresolved_refs => unresolved_refs)
395
- assert_no_problems(problems)
396
- ref_targets = [
397
- "/",
398
- "//",
399
- "/some",
400
- "//some",
401
- "/some/",
402
- "some/",
403
- "some//",
404
- "some",
405
- "/some/reference",
406
- "/some/reference/",
407
- "some/reference/",
408
- "some/reference"
409
- ]
410
- assert_equal ref_targets, env.find(:text => "root").first.childs.collect{|c| c.related.targetIdentifier}
411
- assert_equal ref_targets, unresolved_refs.collect{|ur| ur.proxy.targetIdentifier}
412
- assert unresolved_refs.all?{|ur| ur.feature_name == "related"}
413
- end
414
-
415
- def test_references_many
416
- env, problems = instantiate(%Q(
417
- TestNode text: "root" {
418
- TestNode others: /other
419
- TestNode others: [ /other ]
420
- TestNode others: [ /other1, /other2 ]
421
- }
422
- ), TestMM)
423
- assert_no_problems(problems)
424
- assert_equal [
425
- [ "/other" ],
426
- [ "/other" ],
427
- [ "/other1", "/other2" ],
428
- ], env.find(:text => "root").first.childs.collect{|c| c.others.collect{|p| p.targetIdentifier}}
429
- end
430
-
431
- def test_reference_regexp
432
- env, problems = instantiate(%Q(
433
- TestNode text: "root" {
434
- TestNode related: some
435
- TestNode related: ::some
436
- TestNode related: some::reference
437
- TestNode related: ::some::reference
438
- }
439
- ), TestMM, :reference_regexp => /\A\w*(::\w*)+/)
440
- assert_no_problems(problems)
441
- assert_equal [
442
- "some",
443
- "::some",
444
- "some::reference",
445
- "::some::reference"
446
- ], env.find(:text => "root").first.childs.collect{|c| c.related.targetIdentifier}
447
- end
448
-
449
- #
450
- # unlabled arguments
451
- #
452
-
453
- def test_unlabled_arguments
454
- env, problems = instantiate(%Q(
455
- TestNode "some text", [1,2] {
456
- TestNode "child"
457
- TestNode "child2"
458
- }
459
- ), TestMM, :unlabled_arguments => proc {|clazz| ["text", "nums"]})
460
- assert_no_problems(problems)
461
- assert_model_simple(env, :with_nums)
462
- end
463
-
464
- def test_unlabled_arguments_not_in_front
465
- env, problems = instantiate(%Q(
466
- TestNode nums: [1,2], "some text" {
467
- TestNode "child"
468
- TestNode "child2"
469
- }
470
- ), TestMM, :unlabled_arguments => proc {|clazz| ["text", "nums"]})
471
- assert_no_problems(problems)
472
- assert_model_simple(env, :with_nums)
473
- end
474
-
475
- def test_unlabled_arguments_using_labled
476
- env, problems = instantiate(%Q(
477
- TestNode text: "some text", nums: [1,2] {
478
- TestNode text: "child"
479
- TestNode text: "child2"
480
- }
481
- ), TestMM, :unlabled_arguments => proc {|clazz| ["text", "nums"]})
482
- assert_no_problems(problems)
483
- assert_model_simple(env, :with_nums)
484
- end
485
-
486
- def test_unlabled_arguments_subclass
487
- env, problems = instantiate(%Q(
488
- SubNode "some text", [1, 2] {
489
- TestNode text: "child"
490
- TestNode text: "child2"
491
- }
492
- ), TestMM, :unlabled_arguments => proc {|clazz| ["text", "nums"]})
493
- assert_no_problems(problems)
494
- assert_model_simple(env, :with_nums)
495
- end
496
-
497
- #
498
- # context sensitive commands
499
- #
500
-
501
- def test_context_sensitive
502
- env, problems = instantiate(%Q(
503
- TestNode {
504
- Command {
505
- Command
506
- }
507
- }
508
- ), TestMMContextSensitiveCommands)
509
- assert_no_problems(problems)
510
- root = env.find(:class => TestMMContextSensitiveCommands::TestNode).first
511
- assert root != nil
512
- assert(root.command.is_a?(TestMMContextSensitiveCommands::SubPackage1::Command))
513
- assert(root.command.command.is_a?(TestMMContextSensitiveCommands::SubPackage2::Command))
514
- end
515
-
516
- def test_context_sensitive_command_name_mapping
517
- env, problems = instantiate(%Q(
518
- Command {
519
- Command {
520
- Command
521
- }
522
- }
523
- ), TestMMContextSensitiveCommands, :command_name_provider => lambda do |c|
524
- "Command" end)
525
- assert_no_problems(problems)
526
- root = env.find(:class => TestMMContextSensitiveCommands::TestNode).first
527
- assert root != nil
528
- assert(root.command.is_a?(TestMMContextSensitiveCommands::SubPackage1::Command))
529
- assert(root.command.command.is_a?(TestMMContextSensitiveCommands::SubPackage2::Command))
530
- end
531
-
532
- #
533
- # problems
534
- #
535
-
536
- def test_unexpected_end_of_file
537
- env, problems = instantiate(%Q(
538
- TestNode text: "some text" {
539
- ), TestMM)
540
- assert_problems([[/unexpected end of file, expected \}/i, 2]], problems)
541
- end
542
-
543
- def test_unknown_command
544
- env, problems = instantiate(%Q(
545
- NotDefined
546
- ), TestMM)
547
- assert_problems([[/unknown command 'NotDefined'/i, 2]], problems)
548
- end
549
-
550
- def test_unknown_command_abstract
551
- env, problems = instantiate(%Q(
552
- TestNode
553
- ), TestMMAbstract)
554
- assert_problems([[/unknown command 'TestNode'/i, 2]], problems)
555
- end
556
-
557
- def test_unexpected_unlabled_argument
558
- env, problems = instantiate(%Q(
559
- TestNode "more text"
560
- ), TestMM)
561
- assert_problems([[/unexpected unlabled argument, 0 unlabled arguments expected/i, 2]], problems)
562
- end
563
-
564
- def test_unknown_child_role
565
- env, problems = instantiate(%Q(
566
- TestNode {
567
- notdefined:
568
- TestNode
569
- }
570
- ), TestMM)
571
- assert_problems([[/unknown child role 'notdefined'/i, 3]], problems)
572
- end
573
-
574
- def test_not_a_child_role
575
- env, problems = instantiate(%Q(
576
- TestNode {
577
- text:
578
- TestNode
579
- others:
580
- TestNode
581
- }
582
- ), TestMM)
583
- assert_problems([
584
- [/role 'text' can not take child elements/i, 3],
585
- [/role 'others' can not take child elements/i, 5]
586
- ], problems)
587
- end
588
-
589
- def test_not_a_single_child
590
- env, problems = instantiate(%Q(
591
- TestNode {
592
- singleChild: [
593
- TestNode
594
- TestNode
595
- ]
596
- }
597
- ), TestMM2)
598
- assert_problems([
599
- [/only one child allowed in role 'singleChild'/i, 5]
600
- ], problems)
601
- end
602
-
603
- def test_not_a_single_child2
604
- env, problems = instantiate(%Q(
605
- TestNode {
606
- singleChild:
607
- TestNode
608
- singleChild: [
609
- ]
610
- singleChild:
611
- TestNode
612
- }
613
- ), TestMM2)
614
- assert_problems([
615
- [/only one child allowed in role 'singleChild'/i, 8]
616
- ], problems)
617
- end
618
-
619
- def test_wrong_child_role
620
- env, problems = instantiate(%Q(
621
- TestNode {
622
- singleChild:
623
- TestNode2
624
- }
625
- ), TestMM2)
626
- assert_problems([
627
- [/role 'singleChild' can not take a TestNode2, expected TestNode/i, 4]
628
- ], problems)
629
- end
630
-
631
- def test_child_role_without_child
632
- env, problems = instantiate(%Q(
633
- TestNode {
634
- singleChild:
635
- }
636
- ), TestMM2)
637
- assert_problems([
638
- [/unexpected \}, expected identifier/i, 4]
639
- ], problems)
640
- end
641
-
642
- def test_wrong_child
643
- env, problems = instantiate(%Q(
644
- TestNode {
645
- TestNode3
646
- }
647
- ), TestMM2)
648
- assert_problems([
649
- [/command 'TestNode3' can not be used in this context/i, 3]
650
- ], problems)
651
- end
652
-
653
- def test_ambiguous_child_role
654
- env, problems = instantiate(%Q(
655
- TestNode {
656
- TestNode2
657
- }
658
- ), TestMM2)
659
- assert_problems([
660
- [/role of element is ambiguous, use a role label/i, 3]
661
- ], problems)
662
- end
663
-
664
- def test_non_ambiguous_child_role_subclass
665
- env, problems = instantiate(%Q(
666
- TestNode {
667
- TestNode4
668
- }
669
- ), TestMM2)
670
- assert_no_problems(problems)
671
- end
672
-
673
- def test_not_a_single_child3
674
- env, problems = instantiate(%Q(
675
- TestNode {
676
- TestNode
677
- TestNode
678
- }
679
- ), TestMM2)
680
- assert_problems([
681
- [/only one child allowed in role 'singleChild'/i, 4]
682
- ], problems)
683
- end
684
-
685
- def test_unknown_argument
686
- env, problems = instantiate(%Q(
687
- TestNode unknown: "some text"
688
- ), TestMM)
689
- assert_problems([[/unknown argument 'unknown'/i, 2]], problems)
690
- end
691
-
692
- def test_attribute_in_child_reference
693
- env, problems = instantiate(%Q(
694
- TestNode singleChild: "some text"
695
- ), TestMM2)
696
- assert_problems([[/argument 'singleChild' can only take child elements/i, 2]], problems)
697
- end
698
-
699
- def test_arguments_duplicate
700
- env, problems = instantiate(%Q(
701
- TestNode text: "some text", text: "more text"
702
- ), TestMM)
703
- assert_problems([[/argument 'text' already defined/i, 2]], problems)
704
- end
705
-
706
- def test_unlabled_arguments_duplicate
707
- env, problems = instantiate(%Q(
708
- TestNode text: "some text", "more text"
709
- ), TestMM, :unlabled_arguments => proc {|c| ["text"]})
710
- assert_problems([[/argument 'text' already defined/i, 2]], problems)
711
- end
712
-
713
- def test_multiple_arguments_in_non_many_attribute
714
- env, problems = instantiate(%Q(
715
- TestNode text: ["text1", "text2"]
716
- ), TestMM)
717
- assert_problems([[/argument 'text' can take only one value/i, 2]], problems)
718
- end
719
-
720
- def test_wrong_argument_type
721
- env, problems = instantiate(%Q(
722
- TestNode text: 1
723
- TestNode integer: "text"
724
- TestNode integer: true
725
- TestNode integer: 1.2
726
- TestNode integer: a
727
- TestNode integer: /a
728
- TestNode enum: 1
729
- TestNode enum: x
730
- TestNode related: 1
731
- ), TestMM)
732
- assert_problems([
733
- [/argument 'text' can not take a integer, expected string/i, 2],
734
- [/argument 'integer' can not take a string, expected integer/i, 3],
735
- [/argument 'integer' can not take a boolean, expected integer/i, 4],
736
- [/argument 'integer' can not take a float, expected integer/i, 5],
737
- [/argument 'integer' can not take a identifier, expected integer/i, 6],
738
- [/argument 'integer' can not take a reference, expected integer/i, 7],
739
- [/argument 'enum' can not take a integer, expected identifier/i, 8],
740
- [/argument 'enum' can not take value x, expected A, B/i, 9],
741
- [/argument 'related' can not take a integer, expected reference, identifier/i, 10]
742
- ], problems)
743
- end
744
-
745
- def test_missing_opening_brace
746
- env, problems = instantiate(%Q(
747
- TestNode
748
- }
749
- ), TestMM)
750
- assert_problems([[/unexpected \}, expected identifier/i, 3]], problems)
751
- end
752
-
753
- def test_invalid_root
754
- env, problems = instantiate(%Q(
755
- NonRootClass
756
- ), TestMMNonRootClass)
757
- assert_problems([[/command 'NonRootClass' can not be used on root level/i, 2]], problems)
758
- end
759
-
760
- def test_invalid_root_label
761
- root_elements = []
762
- env, problems = instantiate(%Q(
763
- TestNode text : A
764
- ), TestMM, :root_elements => root_elements)
765
- assert_problems([
766
- [/Unexpected unlabled argument, 0 unlabled arguments expected/i, 2],
767
- [/Unexpected :, expected newline/i, 2]
768
- ], problems)
769
- end
770
-
771
- #
772
- # problem recovery
773
- #
774
-
775
- def test_missing_value
776
- root_elements = []
777
- env, problems = instantiate(%Q(
778
- TestNode nums: 1, text:
779
- TestNode nums: 2, text: {
780
- SubNode
781
- }
782
- TestNode text: ,nums: 3 {
783
- SubNode
784
- }
785
- TestNode nums: , text: , bla:
786
- ), TestMM, :root_elements => root_elements)
787
- assert_equal 4, root_elements.size
788
- assert_equal [1], root_elements[0].nums
789
- assert_nil root_elements[0].text
790
- assert_equal [2], root_elements[1].nums
791
- assert_equal 1, root_elements[1].childs.size
792
- assert_equal [3], root_elements[2].nums
793
- assert_equal 1, root_elements[2].childs.size
794
- assert_problems([
795
- [/unexpected newline, expected.*integer/i, 2],
796
- [/unexpected \{, expected.*integer/i, 3],
797
- [/unexpected ,, expected.*integer/i, 6],
798
- [/unexpected ,, expected.*integer/i, 9],
799
- [/unexpected ,, expected.*integer/i, 9],
800
- [/unexpected newline, expected.*integer/i, 9],
801
- [/unknown argument 'bla'/i, 9],
802
- ], problems)
803
- end
804
-
805
- def test_missing_comma
806
- root_elements = []
807
- env, problems = instantiate(%Q(
808
- TestNode nums: 1 text: "bla"
809
- ), TestMM, :root_elements => root_elements)
810
- assert_equal 1, root_elements.size
811
- assert_equal [1], root_elements[0].nums
812
- assert_equal "bla", root_elements[0].text
813
- assert_problems([
814
- [/unexpected label .*, expected ,/i, 2],
815
- ], problems)
816
- end
817
-
818
- def test_missing_label
819
- root_elements = []
820
- env, problems = instantiate(%Q(
821
- TestNode nums: 1 "bla"
822
- ), TestMM, :root_elements => root_elements)
823
- assert_equal 1, root_elements.size
824
- assert_equal [1], root_elements[0].nums
825
- assert_problems([
826
- [/unexpected string 'bla', expected ,/i, 2],
827
- [/unexpected unlabled argument/i, 2]
828
- ], problems)
829
- end
830
-
831
- def test_unclosed_bracket1
832
- root_elements = []
833
- env, problems = instantiate(%Q(
834
- TestNode nums: [1, "bla"
835
- ), TestMM, :root_elements => root_elements)
836
- assert_equal 1, root_elements.size
837
- assert_equal [1], root_elements[0].nums
838
- assert_nil root_elements[0].text
839
- assert_problems([
840
- [/unexpected newline, expected \]/i, 2],
841
- [/argument 'nums' can not take a string, expected integer/i, 2],
842
- ], problems)
843
- end
844
-
845
- def test_unclosed_bracket2
846
- root_elements = []
847
- env, problems = instantiate(%Q(
848
- TestNode nums: [1, text: "bla"
849
- ), TestMM, :root_elements => root_elements)
850
- assert_equal 1, root_elements.size
851
- assert_equal [1], root_elements[0].nums
852
- assert_equal "bla", root_elements[0].text
853
- assert_problems([
854
- [/unexpected label 'text', expected identifier/i, 2],
855
- ], problems)
856
- end
857
-
858
- def test_unclosed_bracket3
859
- root_elements = []
860
- env, problems = instantiate(%Q(
861
- TestNode nums: [1 text: "bla"
862
- ), TestMM, :root_elements => root_elements)
863
- assert_equal 1, root_elements.size
864
- assert_equal [1], root_elements[0].nums
865
- assert_equal "bla", root_elements[0].text
866
- assert_problems([
867
- [/unexpected label 'text', expected \]/i, 2],
868
- ], problems)
869
- end
870
-
871
- def test_unclosed_bracket4
872
- root_elements = []
873
- env, problems = instantiate(%Q(
874
- TestNode nums: [1 "bla"
875
- ), TestMM, :root_elements => root_elements)
876
- assert_equal 1, root_elements.size
877
- assert_equal [1], root_elements[0].nums
878
- assert_nil root_elements[0].text
879
- assert_problems([
880
- [/unexpected string 'bla', expected ,/i, 2],
881
- [/argument 'nums' can not take a string, expected integer/i, 2],
882
- [/unexpected newline, expected \]/i, 2],
883
- ], problems)
884
- end
885
-
886
- def test_unclosed_bracket5
887
- root_elements = []
888
- env, problems = instantiate(%Q(
889
- TestNode [1, "bla"
890
- ), TestMM, :root_elements => root_elements)
891
- assert_equal 1, root_elements.size
892
- assert_equal [], root_elements[0].nums
893
- assert_nil root_elements[0].text
894
- assert_problems([
895
- [/unexpected newline, expected \]/i, 2],
896
- [/unexpected unlabled argument/i, 2],
897
- ], problems)
898
- end
899
-
900
- def test_unclosed_bracket6
901
- root_elements = []
902
- env, problems = instantiate(%Q(
903
- TestNode [1, "bla" [
904
- ), TestMM, :root_elements => root_elements)
905
- assert_equal 1, root_elements.size
906
- assert_problems([
907
- [/unexpected \[, expected \]/i, 2],
908
- [/unexpected end of file, expected \]/i, 2],
909
- [/unexpected unlabled argument/i, 2],
910
- [/unexpected unlabled argument/i, 2],
911
- ], problems)
912
- end
913
-
914
- def test_unclosed_bracket7
915
- root_elements = []
916
- env, problems = instantiate(%Q(
917
- TestNode [1, "bla", [
918
- ), TestMM, :root_elements => root_elements)
919
- assert_equal 1, root_elements.size
920
- assert_problems([
921
- [/unexpected \[, expected identifier/i, 2],
922
- [/unexpected unlabled argument/i, 2],
923
- [/unexpected unlabled argument/i, 2],
924
- [/unexpected end of file, expected \]/i, 2],
925
- ], problems)
926
- end
927
-
928
- def test_closing_bracket
929
- root_elements = []
930
- env, problems = instantiate(%Q(
931
- TestNode ]
932
- TestNode 1 ]
933
- TestNode 1, ]
934
- TestNode nums: ]1, "bla"
935
- TestNode text: "bla" ]
936
- ), TestMM, :root_elements => root_elements)
937
- assert_equal 5, root_elements.size
938
- assert_equal [], root_elements[3].nums
939
- assert_equal "bla", root_elements[4].text
940
- assert_problems([
941
- [/unexpected \], expected newline/i, 2],
942
- [/unexpected \], expected newline/i, 3],
943
- [/unexpected unlabled argument/i, 3],
944
- [/unexpected \], expected identifier/i, 4],
945
- [/unexpected unlabled argument/i, 4],
946
- [/unexpected \], expected identifier/i, 5],
947
- [/unexpected \], expected newline/i, 6],
948
- ], problems)
949
- end
950
-
951
- def test_closing_brace
952
- root_elements = []
953
- env, problems = instantiate(%Q(
954
- TestNode }
955
- TestNode 1 }
956
- TestNode 1, }
957
- TestNode nums: }1, "bla"
958
- TestNode text: "bla" }
959
- ), TestMM, :root_elements => root_elements)
960
- assert_equal 5, root_elements.size
961
- assert_equal [], root_elements[3].nums
962
- assert_equal "bla", root_elements[4].text
963
- assert_problems([
964
- [/unexpected \}, expected newline/i, 2],
965
- [/unexpected \}, expected newline/i, 3],
966
- [/unexpected unlabled argument/i, 3],
967
- [/unexpected \}, expected identifier/i, 4],
968
- [/unexpected unlabled argument/i, 4],
969
- [/unexpected \}, expected identifier/i, 5],
970
- [/unexpected \}, expected newline/i, 6],
971
- ], problems)
972
- end
973
-
974
- def test_starting_non_command
975
- root_elements = []
976
- env, problems = instantiate(%Q(
977
- \)
978
- TestNode
979
- *
980
- TestNode
981
- $
982
- TestNode
983
- ,
984
- TestNode
985
- [
986
- TestNode
987
- {
988
- TestNode
989
- ]
990
- TestNode
991
- }
992
- TestNode
993
- }}
994
- ), TestMM, :root_elements => root_elements)
995
- assert_equal 8, root_elements.size
996
- assert_problems([
997
- [/parse error on token '\)'/i, 2],
998
- [/parse error on token '\*'/i, 4],
999
- [/parse error on token '\$'/i, 6],
1000
- [/unexpected ,, expected identifier/i, 8],
1001
- [/unexpected \[, expected identifier/i, 10],
1002
- [/unexpected \{, expected identifier/i, 12],
1003
- [/unexpected \], expected identifier/i, 14],
1004
- [/unexpected \}, expected identifier/i, 16],
1005
- [/unexpected \}, expected identifier/i, 18],
1006
- ], problems)
1007
- end
1008
-
1009
- def test_parse_error_in_argument_list
1010
- root_elements = []
1011
- env, problems = instantiate(%Q(
1012
- TestNode text: "bla", * nums: 1
1013
- TestNode text: "bla" * , nums: 1
1014
- TestNode ?text: "bla"
1015
- TestNode nums: [1, * 3]
1016
- ), TestMM, :root_elements => root_elements)
1017
- assert_equal 4, root_elements.size
1018
- assert_equal "bla", root_elements[0].text
1019
- assert_equal [1], root_elements[0].nums
1020
- assert_equal "bla", root_elements[1].text
1021
- assert_equal [1], root_elements[1].nums
1022
- assert_equal "bla", root_elements[2].text
1023
- assert_equal [1, 3], root_elements[3].nums
1024
- assert_problems([
1025
- [/parse error on token '\*'/i, 2],
1026
- [/parse error on token '\*'/i, 3],
1027
- [/parse error on token '\?'/i, 4],
1028
- [/parse error on token '\*'/i, 5],
1029
- ], problems)
1030
- end
1031
-
1032
- def test_unclosed_brace
1033
- root_elements = []
1034
- env, problems = instantiate(%Q(
1035
- TestNode {
1036
- ), TestMM, :root_elements => root_elements)
1037
- assert_equal 1, root_elements.size
1038
- assert_problems([
1039
- [/unexpected end of file, expected \}/i, 2]
1040
- ], problems)
1041
- end
1042
-
1043
- def test_unclosed_brace2
1044
- root_elements = []
1045
- env, problems = instantiate(%Q(
1046
- TestNode {
1047
- *
1048
- ), TestMM, :root_elements => root_elements)
1049
- assert_equal 1, root_elements.size
1050
- assert_problems([
1051
- [/parse error on token '\*'/i, 3]
1052
- ], problems)
1053
- end
1054
-
1055
- def test_unclosed_brace3
1056
- root_elements = []
1057
- env, problems = instantiate(%Q(
1058
- TestNode {
1059
- childs:
1060
- ), TestMM, :root_elements => root_elements)
1061
- assert_equal 1, root_elements.size
1062
- assert_problems([
1063
- [/unexpected end of file, expected identifier/i, 3]
1064
- ], problems)
1065
- end
1066
-
1067
- def test_label_without_child
1068
- root_elements = []
1069
- env, problems = instantiate(%Q(
1070
- TestNode {
1071
- childs:
1072
- }
1073
- ), TestMM, :root_elements => root_elements)
1074
- assert_equal 1, root_elements.size
1075
- assert_problems([
1076
- [/unexpected \}, expected identifier/i, 4]
1077
- ], problems)
1078
- end
1079
-
1080
- def test_unclosed_child_bracket
1081
- root_elements = []
1082
- env, problems = instantiate(%Q(
1083
- TestNode {
1084
- childs: [
1085
- ), TestMM, :root_elements => root_elements)
1086
- assert_equal 1, root_elements.size
1087
- assert_problems([
1088
- [/unexpected end of file, expected \]/i, 3]
1089
- ], problems)
1090
- end
1091
-
1092
- def test_child_label_problems
1093
- root_elements = []
1094
- env, problems = instantiate(%Q(
1095
- TestNode {
1096
- childs: x
1097
- SubNode
1098
- childs: *
1099
- SubNode
1100
- childs: &
1101
- }
1102
- ), TestMM, :root_elements => root_elements)
1103
- assert_equal 1, root_elements.size
1104
- assert_equal 2, root_elements[0].childs.size
1105
- assert_problems([
1106
- [/unexpected identifier 'x', expected newline/i, 3],
1107
- [/parse error on token '\*'/i, 5],
1108
- [/parse error on token '&'/i, 7]
1109
- ], problems)
1110
- end
1111
-
1112
- def test_child_label_problems_with_bracket
1113
- root_elements = []
1114
- env, problems = instantiate(%Q(
1115
- TestNode {
1116
- childs: [ x
1117
- SubNode
1118
- ]
1119
- childs: [ *
1120
- SubNode
1121
- ]
1122
- childs: [&
1123
- ]
1124
- }
1125
- ), TestMM, :root_elements => root_elements)
1126
- assert_equal 1, root_elements.size
1127
- assert_equal 2, root_elements[0].childs.size
1128
- assert_problems([
1129
- [/unexpected identifier 'x', expected newline/i, 3],
1130
- [/parse error on token '\*'/i, 6],
1131
- [/parse error on token '&'/i, 9]
1132
- ], problems)
1133
- end
1134
-
1135
- def test_missing_closing_bracket
1136
- root_elements = []
1137
- env, problems = instantiate(%Q(
1138
- TestNode {
1139
- childs: [
1140
- SubNode
1141
- childs: [
1142
- SubNode
1143
- SubNode
1144
- }
1145
- ), TestMM, :root_elements => root_elements)
1146
- assert_equal 1, root_elements.size
1147
- assert_equal 3, root_elements[0].childs.size
1148
- assert_problems([
1149
- [/unexpected label 'childs', expected identifier/i, 5],
1150
- [/unexpected \}, expected identifier/i, 8],
1151
- ], problems)
1152
- end
1153
-
1154
- def test_missing_closing_brace
1155
- root_elements = []
1156
- env, problems = instantiate(%Q(
1157
- TestNode {
1158
- TestNode {
1159
- TestNode
1160
- }
1161
- ), TestMM, :root_elements => root_elements)
1162
- assert_equal 1, root_elements.size
1163
- assert_equal 1, root_elements[0].childs.size
1164
- assert_equal 1, root_elements[0].childs[0].childs.size
1165
- assert_problems([
1166
- [/unexpected end of file, expected \}/i, 5],
1167
- ], problems)
1168
- end
1169
-
1170
- #
1171
- # command name provider
1172
- #
1173
-
1174
- def test_command_name_provider
1175
- env, problems = instantiate(%Q(
1176
- TestNodeX text: "some text", nums: [1,2] {
1177
- TestNodeX text: "child"
1178
- TestNodeX text: "child2"
1179
- }
1180
- ), TestMM, :command_name_provider => proc do |c|
1181
- c.name + "X"
1182
- end)
1183
- assert_no_problems(problems)
1184
- assert_model_simple(env, :with_nums)
1185
- end
1186
-
1187
- def test_command_name_provider_ambiguous
1188
- begin
1189
- env, problems = instantiate(%Q(
1190
- TestNode
1191
- ), TestMM, :command_name_provider => proc do |c|
1192
- "Fixed"
1193
- end)
1194
- assert false
1195
- rescue RuntimeError => e
1196
- assert e.message =~ /ambiguous command name/
1197
- end
1198
- end
1199
-
1200
- #
1201
- # comment handler
1202
- #
1203
-
1204
- def test_comment_handler
1205
- proc_calls = 0
1206
- env, problems = instantiate(%Q(
1207
- #comment
1208
- TestNode text: "node1"
1209
- #comment
1210
- # multiline
1211
- TestNode text: "node2"
1212
- TestNode text: "node3" #comment
1213
- #above
1214
- TestNode text: "node4" {#right1
1215
- childs: [ #right2
1216
- #unassociated1
1217
- ] #right3
1218
- #unassociated2
1219
- } #below
1220
- #above1
1221
- #above2
1222
- TestNode text: "node5" { #right1
1223
- childs: #right2
1224
- TestNode
1225
- }#below
1226
- #comment without
1227
- #an element following
1228
- ), TestMM, :comment_handler => proc {|c,k,e,env|
1229
- proc_calls += 1
1230
- if e.nil?
1231
- case proc_calls
1232
- when 4
1233
- assert_equal "unassociated1", c
1234
- assert_equal :unassociated, k
1235
- when 5
1236
- assert_equal "unassociated2", c
1237
- assert_equal :unassociated, k
1238
- when 15
1239
- assert_equal "comment without\nan element following", c
1240
- assert_equal :unassociated, k
1241
- end
1242
- elsif e.text == "node1"
1243
- assert_equal "comment", c
1244
- assert_equal :above, k
1245
- elsif e.text == "node2"
1246
- assert_equal "comment\n multiline", c
1247
- assert_equal :above, k
1248
- elsif e.text == "node3"
1249
- assert_equal "comment", c
1250
- assert_equal :eol, k
1251
- elsif e.text == "node4"
1252
- case proc_calls
1253
- when 6
1254
- assert_equal "above", c
1255
- assert_equal :above, k
1256
- when 7
1257
- assert_equal "right1", c
1258
- assert_equal :eol, k
1259
- when 8
1260
- assert_equal "right2", c
1261
- assert_equal :eol, k
1262
- when 9
1263
- assert_equal "right3", c
1264
- assert_equal :eol, k
1265
- when 10
1266
- assert_equal "below", c
1267
- assert_equal :eol, k
1268
- end
1269
- elsif e.text == "node5"
1270
- case proc_calls
1271
- when 11
1272
- assert_equal "above1\nabove2", c
1273
- assert_equal :above, k
1274
- when 12
1275
- assert_equal "right1", c
1276
- assert_equal :eol, k
1277
- when 13
1278
- assert_equal "right2", c
1279
- assert_equal :eol, k
1280
- when 14
1281
- assert_equal "below", c
1282
- assert_equal :eol, k
1283
- end
1284
- else
1285
- assert false, "unexpected element in comment handler"
1286
- end
1287
- true
1288
- })
1289
- assert_no_problems(problems)
1290
- assert_equal 15, proc_calls
1291
- end
1292
-
1293
- def test_comment_handler_comment_not_allowed
1294
- env, problems = instantiate(%Q(
1295
- #comment
1296
- TestNode
1297
- ), TestMM, :comment_handler => proc {|c,k,e,env|
1298
- false
1299
- })
1300
- assert_problems([[/element can not take this comment/, 3]], problems)
1301
- end
1302
-
1303
- def test_comment_handler_comment_not_allowed_unassociated
1304
- env, problems = instantiate(%Q(
1305
- #comment
1306
- ), TestMM, :comment_handler => proc {|c,k,e,env|
1307
- false
1308
- })
1309
- assert_problems([[/Unassociated comment not allowed/, 2]], problems)
1310
- end
1311
-
1312
- #
1313
- # annotations
1314
- #
1315
-
1316
- def test_annotation_not_supported
1317
- env, problems = instantiate(%Q(
1318
- @annotation
1319
- TestNode
1320
- ), TestMM)
1321
- assert_problems([[/annotation not allowed/i, 3]], problems)
1322
- end
1323
-
1324
- def test_annotation_not_allowed
1325
- env, problems = instantiate(%Q(
1326
- @annotation
1327
- TestNode
1328
- ), TestMM, :annotation_handler => proc {|a,e,env|
1329
- false
1330
- })
1331
- assert_problems([[/annotation not allowed/i, 3]], problems)
1332
- end
1333
-
1334
- def test_annotation_in_wrong_places
1335
- env, problems = instantiate(%Q(
1336
- @annotation
1337
- #comment
1338
- TestNode {
1339
- @annotation
1340
- childs:
1341
- TestNode
1342
- @annotation
1343
- }
1344
- @annotation
1345
- ), TestMM)
1346
- assert_problems([
1347
- [/unexpected comment 'comment', expected identifier/i, 3],
1348
- [/unexpected label 'childs', expected identifier/i, 6],
1349
- [/unexpected \}, expected identifier/i, 9],
1350
- [/unexpected end of file, expected identifier/i, 10]
1351
- ], problems)
1352
- end
1353
-
1354
- def test_annotation_handler
1355
- annotations = []
1356
- elements = []
1357
- env, problems = instantiate(%Q(
1358
- @annotation
1359
- TestNode text: "aa"
1360
- @annotation
1361
- @ in a new line
1362
-
1363
- @ even with space in between
1364
-
1365
- TestNode text: "bb" {
1366
- @at child
1367
- TestNode text: "cc"
1368
- childs:
1369
- @after label
1370
- TestNode text: "dd"
1371
- @another child
1372
- TestNode text: "ee"
1373
- childs: [
1374
- @in brackets
1375
- TestNode text: "ff"
1376
- ]
1377
- }
1378
- ), TestMM, :annotation_handler => proc {|a,e,env|
1379
- annotations << a
1380
- elements << e
1381
- true
1382
- })
1383
- assert_equal "aa", elements[0].text
1384
- assert_equal "annotation", annotations[0]
1385
- assert_equal "cc", elements[1].text
1386
- assert_equal "at child", annotations[1]
1387
- assert_equal "dd", elements[2].text
1388
- assert_equal "after label", annotations[2]
1389
- assert_equal "ee", elements[3].text
1390
- assert_equal "another child", annotations[3]
1391
- assert_equal "ff", elements[4].text
1392
- assert_equal "in brackets", annotations[4]
1393
- assert_equal "bb", elements[5].text
1394
- assert_equal "annotation\n in a new line\n even with space in between", annotations[5]
1395
- assert_no_problems(problems)
1396
- end
1397
-
1398
- #
1399
- # generics
1400
- #
1401
-
1402
- def test_generics_parse_error
1403
- env, problems = instantiate(%Q(
1404
- TestNode text: <bla
1405
- TestNode text: bla>
1406
- TestNode text: <a<b>
1407
- TestNode text: <a>b>
1408
- TestNode text: <%a
1409
- TestNode text: <%a%
1410
- TestNode text: <%a%>b%>
1411
- ), TestMM, :enable_generics => true)
1412
- assert_problems([
1413
- [/parse error on token '<'/i, 2],
1414
- [/unexpected unlabled argument/i, 2],
1415
- [/parse error on token '>'/i, 3],
1416
- [/unexpected identifier 'b'/i, 5],
1417
- [/parse error on token '>'/i, 5],
1418
- [/unexpected unlabled argument/i, 5],
1419
- [/parse error on token '<'/i, 6],
1420
- [/unexpected unlabled argument/i, 6],
1421
- [/parse error on token '<'/i, 7],
1422
- [/unexpected unlabled argument/i, 7],
1423
- [/parse error on token '%'/i, 7],
1424
- [/unexpected identifier 'b'/i, 8],
1425
- [/unexpected unlabled argument/i, 8],
1426
- [/parse error on token '%'/i, 8],
1427
- ], problems)
1428
- end
1429
-
1430
- def test_generics
1431
- root_elements = []
1432
- env, problems = instantiate(%q(
1433
- TestNode text: <bla>, nums: [<1>, <%2%>], boolean: <truthy>, enum: <%option%>, float: <precise>, related: <%noderef%>, others: [<other1>, <%other2%>]
1434
- ), TestMM, :root_elements => root_elements, :enable_generics => true)
1435
- assert_no_problems(problems)
1436
- assert root_elements[0].text.is_a?(RText::Generic)
1437
- assert_equal "bla", root_elements[0].text.string
1438
- assert_equal ["1", "2"], root_elements[0].nums.collect{|n| n.string}
1439
- assert_equal "truthy", root_elements[0].boolean.string
1440
- assert_equal "option", root_elements[0].enum.string
1441
- assert_equal "precise", root_elements[0].float.string
1442
- assert_equal "noderef", root_elements[0].related.string
1443
- assert_equal ["other1", "other2"], root_elements[0].others.collect{|n| n.string}
1444
- end
1445
-
1446
- def test_generics_forbidden
1447
- env, problems = instantiate(%Q(\
1448
- TestNode text: <bla>
1449
- ), TestMM)
1450
- assert_problems([
1451
- [/generic value not allowed/i, 1],
1452
- ], problems)
1453
- end
1454
-
1455
- #
1456
- # subpackages
1457
- #
1458
-
1459
- def test_subpackage
1460
- env, problems = instantiate(%q(
1461
- TestNodeSub text: "something"
1462
- ), TestMMSubpackage)
1463
- assert_no_problems(problems)
1464
- assert_equal "something", env.elements.first.text
1465
- end
1466
-
1467
- #
1468
- # values
1469
- #
1470
-
1471
- def test_escapes
1472
- env, problems = instantiate(%q(
1473
- TestNode text: "some \" \\\\ \\\\\" text \r xx \n xx \r\n xx \t xx \b xx \f"
1474
- ), TestMM)
1475
- assert_no_problems(problems)
1476
- assert_equal %Q(some " \\ \\" text \r xx \n xx \r\n xx \t xx \b xx \f), env.elements.first.text
1477
- end
1478
-
1479
- def test_escape_single_backslash
1480
- env, problems = instantiate(%q(
1481
- TestNode text: "a single \\ will be just itself"
1482
- ), TestMM)
1483
- assert_no_problems(problems)
1484
- assert_equal %q(a single \\ will be just itself), env.elements.first.text
1485
- end
1486
-
1487
- def test_string_umlauts
1488
- env, problems = instantiate(%q(
1489
- TestNode text: "ä, ö, ü"
1490
- ), TestMM)
1491
- assert_no_problems(problems)
1492
- assert_equal %q(ä, ö, ü), env.elements.first.text
1493
- end
1494
-
1495
- def test_integer
1496
- env, problems = instantiate(%q(
1497
- TestNode integer: 7
1498
- TestNode integer: 4294967296
1499
- TestNode integer: 12345678901234567890
1500
- ), TestMM)
1501
- assert_no_problems(problems)
1502
- assert_equal 7, env.elements[0].integer
1503
- assert_equal 4294967296, env.elements[1].integer
1504
- assert_equal 12345678901234567890, env.elements[2].integer
1505
- end
1506
-
1507
- def test_integer_hex
1508
- env, problems = instantiate(%q(
1509
- TestNode text: root {
1510
- TestNode integer: 0x7
1511
- TestNode integer: 0X7
1512
- TestNode integer: 0x007
1513
- TestNode integer: 0x77
1514
- TestNode integer: 0xabCDEF
1515
- TestNode integer: 0xabcdefabcdefabcdef
1516
- }
1517
- ), TestMM)
1518
- assert_no_problems(problems)
1519
- assert_equal [7, 7, 7, 0x77, 0xABCDEF, 0xabcdefabcdefabcdef], env.find(:text => "root").first.childs.collect{|c| c.integer}
1520
- end
1521
-
1522
- def test_float
1523
- env, problems = instantiate(%q(
1524
- TestNode float: 1.23
1525
- TestNode float: 1.23e-08
1526
- TestNode float: 1.23e+10
1527
- TestNode float: 1234567890.123456789
1528
- ), TestMM)
1529
- assert_no_problems(problems)
1530
- assert_equal 1.23, env.elements[0].float
1531
- assert_equal 1.23e-08, env.elements[1].float
1532
- assert_equal 1.23e+10, env.elements[2].float
1533
- if rgen_with_bigdecimal?
1534
- assert env.elements[3].float.is_a?(BigDecimal)
1535
- assert_equal "1234567890.123456789", env.elements[3].float.to_s("F")
1536
- else
1537
- assert env.elements[3].float.is_a?(Float)
1538
- assert_equal "1234567890.1234567", env.elements[3].float.to_s
1539
- end
1540
- end
1541
-
1542
- def test_boolean
1543
- env, problems = instantiate(%q(
1544
- TestNode text: root {
1545
- TestNode boolean: true
1546
- TestNode boolean: false
1547
- }
1548
- ), TestMM)
1549
- assert_no_problems(problems)
1550
- assert_equal [true, false], env.find(:text => "root").first.childs.collect{|c| c.boolean}
1551
- end
1552
-
1553
- def test_enum
1554
- env, problems = instantiate(%q(
1555
- TestNode text: root {
1556
- TestNode enum: A
1557
- TestNode enum: B
1558
- TestNode enum: "non-word*chars"
1559
- TestNode enum: "2you"
1560
- }
1561
- ), TestMM)
1562
- assert_no_problems(problems)
1563
- assert_equal [:A, :B, :'non-word*chars', :'2you'], env.find(:text => "root").first.childs.collect{|c| c.enum}
1564
- end
1565
-
1566
- def test_with_bom
1567
- env, problems = instantiate(%Q(\xEF\xBB\xBF
1568
- TestNode text: "some text", nums: [1,2] {
1569
- TestNode text: "child"
1570
- TestNode text: "child2"
1571
- }
1572
- ), TestMM)
1573
- assert_no_problems(problems)
1574
- assert_model_simple(env, :with_nums)
1575
- end
1576
-
1577
- #
1578
- # conflicts with builtins
1579
- #
1580
-
1581
- def test_conflict_builtin
1582
- env, problems = instantiate(%q(
1583
- Data notTheBuiltin: "for sure"
1584
- ), TestMMData)
1585
- assert_no_problems(problems)
1586
- assert_equal "for sure", env.elements.first.notTheBuiltin
1587
- end
1588
-
1589
- def test_builtin_in_subpackage
1590
- env, problems = instantiate(%q(
1591
- Data notTheBuiltin: "for sure"
1592
- ), TestMMSubpackage)
1593
- assert_no_problems(problems)
1594
- assert_equal "for sure", env.elements.first.notTheBuiltin
1595
- end
1596
-
1597
- #
1598
- # encoding
1599
- #
1600
-
1601
- def test_encodings
1602
- input = %Q(TestNode text: "iso-8859-1 AE Umlaut: \xc4")
1603
- # force encoding to binary in order to prevent exceptions on invalid byte sequences
1604
- # if the encoding would be utf-8, there would be an exception with the string above
1605
- input.force_encoding("binary")
1606
- env, problems = instantiate(input, TestMM)
1607
- assert_no_problems(problems)
1608
- assert_match /AE Umlaut: /, env.elements.first.text
1609
- end
1610
-
1611
- #
1612
- # line breaks
1613
- #
1614
-
1615
- def test_linebreak
1616
- roots = []
1617
- env, problems = instantiate(%Q(
1618
- TestNode sometext,
1619
- integer: 1,
1620
- nums: [
1621
- 1,
1622
- 2
1623
- ]
1624
- ), TestMM, :root_elements => roots, :unlabled_arguments => proc {|clazz| ["text"]})
1625
- assert_no_problems(problems)
1626
- node = roots.first
1627
- assert_equal "sometext", node.text
1628
- assert_equal 1, node.integer
1629
- assert_equal [1,2], node.nums
1630
- end
1631
-
1632
- def test_linebreak_backslash
1633
- roots = []
1634
- env, problems = instantiate(%Q(
1635
- TestNode \\
1636
- sometext
1637
- ), TestMM, :root_elements => roots, :unlabled_arguments => proc {|clazz| ["text"]})
1638
- assert_no_problems(problems)
1639
- node = roots.first
1640
- assert_equal "sometext", node.text
1641
- end
1642
-
1643
- def test_linebreak_backslash_problems
1644
- roots = []
1645
- env, problems = instantiate(%Q(
1646
- TostNode \\
1647
- sometext
1648
- TostNode
1649
- ), TestMM, :root_elements => roots, :unlabled_arguments => proc {|clazz| ["text"]})
1650
- assert_problems([
1651
- [/unknown command/i, 2],
1652
- [/unknown command/i, 4],
1653
- ], problems)
1654
- end
1655
-
1656
- module TestMMObjectAttribute
1657
- extend RGen::MetamodelBuilder::ModuleExtension
1658
- class TestNode < RGen::MetamodelBuilder::MMBase
1659
- has_many_attr 'objs', Object
1660
- end
1661
- end
1662
-
1663
- def test_object_attribute
1664
- roots = []
1665
- env, problems = instantiate(%Q(
1666
- TestNode objs: ["some text", -123, someSymbol, true, false, -0.097]
1667
- ), TestMMObjectAttribute, :root_elements => roots)
1668
- assert_no_problems(problems)
1669
- node = roots.first
1670
- assert_equal ['some text', -123, 'someSymbol', true, false, -0.097], node.objs
1671
- end
1672
-
1673
- private
1674
-
1675
- def instantiate(text, mm, options={})
1676
- env = RGen::Environment.new
1677
- lang = RText::Language.new(mm.ecore, options.merge(
1678
- :root_classes => mm.ecore.eAllClasses.select{|c|
1679
- c.name == "TestNode" || c.name == "Data" || c.name == "TestNodeSub" || c.name == "SubNode"}))
1680
- inst = RText::Instantiator.new(lang)
1681
- problems = []
1682
- inst.instantiate(text, options.merge({:env => env, :problems => problems, :root_elements => options[:root_elements]}))
1683
- return env, problems
1684
- end
1685
-
1686
- def assert_no_problems(problems)
1687
- assert problems.empty?, problems.collect{|p| "#{p.message}, line: #{p.line}"}.join("\n")
1688
- end
1689
-
1690
- def assert_problems(expected, problems)
1691
- remaining = problems.dup
1692
- probs = []
1693
- expected.each do |e|
1694
- if e.is_a?(Array)
1695
- p = remaining.find{|p| p.message =~ e[0] && p.line == e[1]}
1696
- else
1697
- p = remaining.find{|p| p.message =~ e}
1698
- end
1699
- probs << "expected problem not present: #{e}" if !p
1700
- # make sure to not delete duplicate problems at once
1701
- idx = remaining.index(p)
1702
- remaining.delete_at(idx) if idx
1703
- end
1704
- remaining.each do |p|
1705
- probs << "unexpected problem: #{p.message}, line: #{p.line}"
1706
- end
1707
- assert probs.empty?, probs.join("\n")
1708
- end
1709
-
1710
- def assert_model_simple(env, *opts)
1711
- raise "unknown options" unless (opts - [:with_nums]).empty?
1712
- root = env.find(:class => TestMM::TestNode, :text => "some text").first
1713
- assert root != nil
1714
- assert_equal 2, root.childs.size
1715
- assert_equal [TestMM::TestNode, TestMM::TestNode], root.childs.collect{|c| c.class}
1716
- assert_equal ["child", "child2"], root.childs.text
1717
- if opts.include?(:with_nums)
1718
- assert_equal [1, 2], root.nums
1719
- end
1720
- end
1721
-
1722
- def rgen_with_bigdecimal?
1723
- begin
1724
- TestMM::TestNode.new.float = BigDecimal.new("0.0")
1725
- rescue StandardError
1726
- return false
1727
- end
1728
- true
1729
- end
1730
-
1731
- end
1732
-
1733
-
1
+ # coding: binary
2
+ $:.unshift File.join(File.dirname(__FILE__),"..","lib")
3
+
4
+ require 'minitest/autorun'
5
+ require 'bigdecimal'
6
+ require 'rgen/environment'
7
+ require 'rgen/metamodel_builder'
8
+ require 'rtext/instantiator'
9
+ require 'rtext/language'
10
+
11
+ class InstantiatorTest < MiniTest::Test
12
+
13
+ module TestMM
14
+ extend RGen::MetamodelBuilder::ModuleExtension
15
+ class TestNode < RGen::MetamodelBuilder::MMBase
16
+ SomeEnum = RGen::MetamodelBuilder::DataTypes::Enum.new([:A, :B, :'non-word*chars', :'2you'])
17
+ has_attr 'text', String
18
+ has_attr 'integer', Integer
19
+ has_attr 'boolean', Boolean
20
+ has_attr 'enum', SomeEnum
21
+ has_many_attr 'nums', Integer
22
+ has_attr 'float', Float
23
+ has_one 'related', TestNode
24
+ has_many 'others', TestNode
25
+ contains_many 'childs', TestNode, 'parent'
26
+ end
27
+ class SubNode < TestNode
28
+ end
29
+ end
30
+
31
+ module TestMM2
32
+ extend RGen::MetamodelBuilder::ModuleExtension
33
+ class TestNode < RGen::MetamodelBuilder::MMBase
34
+ contains_one 'singleChild', TestNode, 'parent'
35
+ end
36
+ class TestNode2 < RGen::MetamodelBuilder::MMBase
37
+ end
38
+ class TestNode3 < RGen::MetamodelBuilder::MMBase
39
+ end
40
+ class TestNode4 < TestNode
41
+ end
42
+ TestNode.contains_one 'singleChild2a', TestNode2, 'parentA'
43
+ TestNode.contains_one 'singleChild2b', TestNode2, 'parentB'
44
+ end
45
+
46
+ module TestMMLinenoFilenameFragment
47
+ extend RGen::MetamodelBuilder::ModuleExtension
48
+ class TestNode < RGen::MetamodelBuilder::MMBase
49
+ has_attr 'text', String
50
+ has_attr 'lineno', Integer
51
+ has_attr 'filename', String
52
+ has_attr 'fragmentr', String
53
+ contains_many 'childs', TestNode, 'parent'
54
+ end
55
+ end
56
+
57
+ module TestMMAbstract
58
+ extend RGen::MetamodelBuilder::ModuleExtension
59
+ class TestNode < RGen::MetamodelBuilder::MMBase
60
+ abstract
61
+ end
62
+ end
63
+
64
+ module TestMMData
65
+ extend RGen::MetamodelBuilder::ModuleExtension
66
+ # class "Data" exists in the standard Ruby namespace
67
+ class Data < RGen::MetamodelBuilder::MMBase
68
+ has_attr 'notTheBuiltin', String
69
+ end
70
+ end
71
+
72
+ module TestMMSubpackage
73
+ extend RGen::MetamodelBuilder::ModuleExtension
74
+ module SubPackage
75
+ extend RGen::MetamodelBuilder::ModuleExtension
76
+ class TestNodeSub < RGen::MetamodelBuilder::MMBase
77
+ has_attr 'text', String
78
+ end
79
+ class Data < RGen::MetamodelBuilder::MMBase
80
+ has_attr 'notTheBuiltin', String
81
+ end
82
+ end
83
+ end
84
+
85
+ module TestMMNonRootClass
86
+ extend RGen::MetamodelBuilder::ModuleExtension
87
+ class NonRootClass < RGen::MetamodelBuilder::MMBase
88
+ end
89
+ end
90
+
91
+ module TestMMContextSensitiveCommands
92
+ extend RGen::MetamodelBuilder::ModuleExtension
93
+ module SubPackage2
94
+ extend RGen::MetamodelBuilder::ModuleExtension
95
+ class Command < RGen::MetamodelBuilder::MMBase
96
+ end
97
+ end
98
+ module SubPackage1
99
+ extend RGen::MetamodelBuilder::ModuleExtension
100
+ class Command < RGen::MetamodelBuilder::MMBase
101
+ contains_one 'command', SubPackage2::Command, 'super'
102
+ end
103
+ end
104
+ class TestNode < RGen::MetamodelBuilder::MMBase
105
+ contains_one 'command', SubPackage1::Command, 'testNode'
106
+ end
107
+ end
108
+
109
+ def test_int_float_string
110
+ root_elements = []
111
+ _, problems = instantiate(%Q(
112
+ TestNode text: 10
113
+ TestNode text: -14.55
114
+ ), TestMM, :root_elements => root_elements)
115
+ assert_no_problems(problems)
116
+ assert(root_elements.first.text.is_a?(String))
117
+ assert_equal('10', root_elements.first.text)
118
+ assert(root_elements[1].text.is_a?(String))
119
+ assert_equal('-14.55', root_elements[1].text)
120
+ end
121
+
122
+ def test_int_float
123
+ env, problems = instantiate(%Q(
124
+ TestNode float: "abc"
125
+ ), TestMM)
126
+ assert_equal(1, problems.length)
127
+
128
+ root_elements = []
129
+ env, problems = instantiate(%Q(
130
+ TestNode text: "some text", float: -25 {
131
+ TestNode text: "child"
132
+ TestNode text: "child2"
133
+ }
134
+ ), TestMM, :root_elements => root_elements)
135
+ assert_no_problems(problems)
136
+ assert_model_simple(env)
137
+ assert(root_elements.first.float.is_a?(Float))
138
+ assert_equal(-25.0, root_elements.first.float)
139
+
140
+ root_elements = []
141
+ env, problems = instantiate(%Q(
142
+ TestNode text: "some text", float: -72.001 {
143
+ TestNode text: "child"
144
+ TestNode text: "child2"
145
+ }
146
+ ), TestMM, :root_elements => root_elements)
147
+ assert_no_problems(problems)
148
+ assert_model_simple(env)
149
+ assert(root_elements.first.float.is_a?(Float))
150
+ assert_equal(-72.001, root_elements.first.float)
151
+ end
152
+
153
+ def test_simple
154
+ env, problems = instantiate(%Q(
155
+ TestNode text: "some text", nums: [1,2] {
156
+ TestNode text: "child"
157
+ TestNode text: "child2"
158
+ }
159
+ ), TestMM)
160
+ assert_no_problems(problems)
161
+ assert_model_simple(env, :with_nums)
162
+ end
163
+
164
+ def test_multiple_roots
165
+ env, problems = instantiate(%Q(
166
+ TestNode
167
+ TestNode
168
+ ), TestMM)
169
+ assert_no_problems(problems)
170
+ assert_equal 2, env.elements.size
171
+ end
172
+
173
+ def test_comment
174
+ env, problems = instantiate(%Q(
175
+ # comment 1
176
+ TestNode text: "some text" {# comment 1.1
177
+ childs: [ # comment 1.2
178
+ # comment 2
179
+ TestNode text: "child" # comment 2.1
180
+ # comment 3
181
+ TestNode text: "child2" #comment 3.1
182
+ # unassociated
183
+ ] # comment 1.3
184
+ # unassociated
185
+ } # comment 1.4
186
+ #comment 1
187
+ TestNode { #comment 1.1
188
+ childs: # comment 1.2
189
+ TestNode text: "child" #comment2
190
+ # unassociated
191
+ }# comment 1.3
192
+ # unassociated
193
+ ), TestMM)
194
+ assert_no_problems(problems)
195
+ assert_model_simple(env)
196
+ end
197
+
198
+ def test_comment_only
199
+ env, problems = instantiate(%Q(
200
+ # comment 1
201
+ ), TestMM)
202
+ assert_no_problems(problems)
203
+ end
204
+
205
+ def test_empty
206
+ env, problems = instantiate("", TestMM)
207
+ assert_no_problems(problems)
208
+ end
209
+
210
+ #
211
+ # options
212
+ #
213
+
214
+ def test_line_number_setter
215
+ env, problems = instantiate(%q(
216
+ TestNode text: "node1" {
217
+ TestNode text: "node2"
218
+
219
+ #some comment
220
+ TestNode text: "node3"
221
+ }
222
+ TestNode text: "node4"
223
+ ), TestMMLinenoFilenameFragment, :line_number_attribute => "lineno")
224
+ assert_no_problems(problems)
225
+ assert_equal 2, env.find(:text => "node1").first.lineno
226
+ assert_equal 3, env.find(:text => "node2").first.lineno
227
+ assert_equal 6, env.find(:text => "node3").first.lineno
228
+ assert_equal 8, env.find(:text => "node4").first.lineno
229
+ end
230
+
231
+ def test_missing_line_number_setter
232
+ env, problems = instantiate(%Q(
233
+ TestNode text: A
234
+ ), TestMMLinenoFilenameFragment, :line_number_attribute => "wrong_attribute_name")
235
+ assert_no_problems(problems)
236
+ assert_nil env.elements.first.lineno
237
+ end
238
+
239
+ def test_root_elements
240
+ root_elements = []
241
+ env, problems = instantiate(%Q(
242
+ TestNode text: A
243
+ TestNode text: B
244
+ TestNode text: C
245
+ ), TestMM, :root_elements => root_elements)
246
+ assert_no_problems(problems)
247
+ assert_equal ["A", "B", "C"], root_elements.text
248
+ end
249
+
250
+ def test_file_name_option
251
+ env, problems = instantiate(%Q(
252
+ TestNode text: A
253
+ TestNode text: B
254
+ TestNode a problem here
255
+ ), TestMM, :file_name => "some_file")
256
+ assert_equal "some_file", problems.first.file
257
+ end
258
+
259
+ def test_file_name_setter
260
+ env, problems = instantiate(%Q(
261
+ TestNode text: A
262
+ ), TestMMLinenoFilenameFragment, :file_name => "some_file", :file_name_attribute => "filename")
263
+ assert_equal "some_file", env.elements.first.filename
264
+ end
265
+
266
+ def test_missing_file_name_setter
267
+ env, problems = instantiate(%Q(
268
+ TestNode text: A
269
+ ), TestMMLinenoFilenameFragment, :file_name => "some_file", :file_name_attribute => "wrong_attribute_name")
270
+ assert_nil env.elements.first.filename
271
+ end
272
+
273
+ def test_fragment_ref_setter
274
+ the_ref = "is a string here but would normally be an RGen fragment"
275
+ env, problems = instantiate(%Q(
276
+ TestNode text: A
277
+ ), TestMMLinenoFilenameFragment, :fragment_ref => the_ref, :fragment_ref_attribute => "fragmentr")
278
+ assert_equal the_ref.object_id, env.elements.first.fragmentr.object_id
279
+ end
280
+
281
+ def test_missing_fragment_ref_setter
282
+ the_ref = "is a string here but would normally be an RGen fragment"
283
+ env, problems = instantiate(%Q(
284
+ TestNode text: A
285
+ ), TestMMLinenoFilenameFragment, :fragment_ref => the_ref, :fragment_ref_attribute => "wrong_attribute_name")
286
+ assert_nil env.elements.first.fragmentr
287
+ end
288
+
289
+ #
290
+ # children with role
291
+ #
292
+
293
+ def test_child_role
294
+ env, problems = instantiate(%Q(
295
+ TestNode text: "some text" {
296
+ TestNode text: "child"
297
+ childs:
298
+ TestNode text: "child2"
299
+ }
300
+ ), TestMM)
301
+ assert_no_problems(problems)
302
+ assert_model_simple(env)
303
+ end
304
+
305
+ def test_child_role2
306
+ env, problems = instantiate(%Q(
307
+ TestNode text: "some text" {
308
+ childs: [
309
+ TestNode text: "child"
310
+ TestNode text: "child2"
311
+ ]
312
+ }
313
+ ), TestMM)
314
+ assert_no_problems(problems)
315
+ assert_model_simple(env)
316
+ end
317
+
318
+ def test_child_role3
319
+ env, problems = instantiate(%Q(
320
+ TestNode text: "some text" {
321
+ childs:
322
+ TestNode text: "child"
323
+ childs:
324
+ TestNode text: "child2"
325
+ }
326
+ ), TestMM)
327
+ assert_no_problems(problems)
328
+ assert_model_simple(env)
329
+ end
330
+
331
+ def test_child_role4
332
+ env, problems = instantiate(%Q(
333
+ TestNode text: "some text" {
334
+ childs: [
335
+ TestNode text: "child"
336
+ ]
337
+ childs: [
338
+ TestNode text: "child2"
339
+ ]
340
+ }
341
+ ), TestMM)
342
+ assert_no_problems(problems)
343
+ assert_model_simple(env)
344
+ end
345
+
346
+ def test_child_role_empty
347
+ env, problems = instantiate(%Q(
348
+ TestNode {
349
+ childs: [
350
+ ]
351
+ }
352
+ ), TestMM)
353
+ assert_no_problems(problems)
354
+ end
355
+
356
+
357
+ #
358
+ # whitespace
359
+ #
360
+
361
+ def test_whitespace1
362
+ env, problems = instantiate(%Q(
363
+ TestNode text: "some text" , nums: [ 1 , 2 ] {
364
+
365
+ # comment
366
+
367
+ TestNode text: "child"
368
+
369
+ TestNode text: "child2"
370
+
371
+ }
372
+ ), TestMM)
373
+ assert_no_problems(problems)
374
+ assert_model_simple(env, :with_nums)
375
+ end
376
+
377
+ def test_whitespace2
378
+ env, problems = instantiate(%Q(
379
+ # comment1
380
+
381
+ # comment2
382
+
383
+ TestNode text: "some text" {
384
+
385
+ childs:
386
+
387
+ # comment
388
+
389
+ TestNode text: "child"
390
+
391
+ childs: [
392
+
393
+ TestNode text: "child2"
394
+
395
+ ]
396
+
397
+ }
398
+ ), TestMM)
399
+ assert_no_problems(problems)
400
+ assert_model_simple(env)
401
+ end
402
+
403
+ def test_no_newline_at_eof
404
+ env, problems = instantiate(%Q(
405
+ TestNode), TestMM)
406
+ assert_no_problems(problems)
407
+ end
408
+
409
+ def test_no_newline_at_eof2
410
+ env, problems = instantiate(%Q(
411
+ TestNode {
412
+ }), TestMM)
413
+ assert_no_problems(problems)
414
+ end
415
+
416
+ #
417
+ # references
418
+ #
419
+
420
+ def test_references
421
+ unresolved_refs = []
422
+ env, problems = instantiate(%Q(
423
+ TestNode text: "root" {
424
+ TestNode related: /
425
+ TestNode related: //
426
+ TestNode related: /some
427
+ TestNode related: //some
428
+ TestNode related: /some/
429
+ TestNode related: some/
430
+ TestNode related: some//
431
+ TestNode related: some
432
+ TestNode related: /some/reference
433
+ TestNode related: /some/reference/
434
+ TestNode related: some/reference/
435
+ TestNode related: some/reference
436
+ }
437
+ ), TestMM, :unresolved_refs => unresolved_refs)
438
+ assert_no_problems(problems)
439
+ ref_targets = [
440
+ "/",
441
+ "//",
442
+ "/some",
443
+ "//some",
444
+ "/some/",
445
+ "some/",
446
+ "some//",
447
+ "some",
448
+ "/some/reference",
449
+ "/some/reference/",
450
+ "some/reference/",
451
+ "some/reference"
452
+ ]
453
+ assert_equal ref_targets, env.find(:text => "root").first.childs.collect{|c| c.related.targetIdentifier}
454
+ assert_equal ref_targets, unresolved_refs.collect{|ur| ur.proxy.targetIdentifier}
455
+ assert unresolved_refs.all?{|ur| ur.feature_name == "related"}
456
+ end
457
+
458
+ def test_references_many
459
+ env, problems = instantiate(%Q(
460
+ TestNode text: "root" {
461
+ TestNode others: /other
462
+ TestNode others: [ /other ]
463
+ TestNode others: [ /other1, /other2 ]
464
+ }
465
+ ), TestMM)
466
+ assert_no_problems(problems)
467
+ assert_equal [
468
+ [ "/other" ],
469
+ [ "/other" ],
470
+ [ "/other1", "/other2" ],
471
+ ], env.find(:text => "root").first.childs.collect{|c| c.others.collect{|p| p.targetIdentifier}}
472
+ end
473
+
474
+ def test_reference_regexp
475
+ env, problems = instantiate(%Q(
476
+ TestNode text: "root" {
477
+ TestNode related: some
478
+ TestNode related: ::some
479
+ TestNode related: some::reference
480
+ TestNode related: ::some::reference
481
+ }
482
+ ), TestMM, :reference_regexp => /\A\w*(::\w*)+/)
483
+ assert_no_problems(problems)
484
+ assert_equal [
485
+ "some",
486
+ "::some",
487
+ "some::reference",
488
+ "::some::reference"
489
+ ], env.find(:text => "root").first.childs.collect{|c| c.related.targetIdentifier}
490
+ end
491
+
492
+ #
493
+ # unlabled arguments
494
+ #
495
+
496
+ def test_unlabled_arguments
497
+ env, problems = instantiate(%Q(
498
+ TestNode "some text", [1,2] {
499
+ TestNode "child"
500
+ TestNode "child2"
501
+ }
502
+ ), TestMM, :unlabled_arguments => proc {|clazz| ["text", "nums"]})
503
+ assert_no_problems(problems)
504
+ assert_model_simple(env, :with_nums)
505
+ end
506
+
507
+ def test_unlabled_arguments_not_in_front
508
+ env, problems = instantiate(%Q(
509
+ TestNode nums: [1,2], "some text" {
510
+ TestNode "child"
511
+ TestNode "child2"
512
+ }
513
+ ), TestMM, :unlabled_arguments => proc {|clazz| ["text", "nums"]})
514
+ assert_no_problems(problems)
515
+ assert_model_simple(env, :with_nums)
516
+ end
517
+
518
+ def test_unlabled_arguments_using_labled
519
+ env, problems = instantiate(%Q(
520
+ TestNode text: "some text", nums: [1,2] {
521
+ TestNode text: "child"
522
+ TestNode text: "child2"
523
+ }
524
+ ), TestMM, :unlabled_arguments => proc {|clazz| ["text", "nums"]})
525
+ assert_no_problems(problems)
526
+ assert_model_simple(env, :with_nums)
527
+ end
528
+
529
+ def test_unlabled_arguments_subclass
530
+ env, problems = instantiate(%Q(
531
+ SubNode "some text", [1, 2] {
532
+ TestNode text: "child"
533
+ TestNode text: "child2"
534
+ }
535
+ ), TestMM, :unlabled_arguments => proc {|clazz| ["text", "nums"]})
536
+ assert_no_problems(problems)
537
+ assert_model_simple(env, :with_nums)
538
+ end
539
+
540
+ #
541
+ # context sensitive commands
542
+ #
543
+
544
+ def test_context_sensitive
545
+ env, problems = instantiate(%Q(
546
+ TestNode {
547
+ Command {
548
+ Command
549
+ }
550
+ }
551
+ ), TestMMContextSensitiveCommands)
552
+ assert_no_problems(problems)
553
+ root = env.find(:class => TestMMContextSensitiveCommands::TestNode).first
554
+ assert root != nil
555
+ assert(root.command.is_a?(TestMMContextSensitiveCommands::SubPackage1::Command))
556
+ assert(root.command.command.is_a?(TestMMContextSensitiveCommands::SubPackage2::Command))
557
+ end
558
+
559
+ def test_context_sensitive_command_name_mapping
560
+ env, problems = instantiate(%Q(
561
+ Command {
562
+ Command {
563
+ Command
564
+ }
565
+ }
566
+ ), TestMMContextSensitiveCommands, :command_name_provider => lambda do |c|
567
+ "Command" end)
568
+ assert_no_problems(problems)
569
+ root = env.find(:class => TestMMContextSensitiveCommands::TestNode).first
570
+ assert root != nil
571
+ assert(root.command.is_a?(TestMMContextSensitiveCommands::SubPackage1::Command))
572
+ assert(root.command.command.is_a?(TestMMContextSensitiveCommands::SubPackage2::Command))
573
+ end
574
+
575
+ #
576
+ # problems
577
+ #
578
+
579
+ def test_unexpected_end_of_file
580
+ env, problems = instantiate(%Q(
581
+ TestNode text: "some text" {
582
+ ), TestMM)
583
+ assert_problems([[/unexpected end of file, expected \}/i, 2]], problems)
584
+ end
585
+
586
+ def test_unknown_command
587
+ env, problems = instantiate(%Q(
588
+ NotDefined
589
+ ), TestMM)
590
+ assert_problems([[/unknown command 'NotDefined'/i, 2]], problems)
591
+ end
592
+
593
+ def test_unknown_command_abstract
594
+ env, problems = instantiate(%Q(
595
+ TestNode
596
+ ), TestMMAbstract)
597
+ assert_problems([[/unknown command 'TestNode'/i, 2]], problems)
598
+ end
599
+
600
+ def test_unexpected_unlabled_argument
601
+ env, problems = instantiate(%Q(
602
+ TestNode "more text"
603
+ ), TestMM)
604
+ assert_problems([[/unexpected unlabled argument, 0 unlabled arguments expected/i, 2]], problems)
605
+ end
606
+
607
+ def test_unknown_child_role
608
+ env, problems = instantiate(%Q(
609
+ TestNode {
610
+ notdefined:
611
+ TestNode
612
+ }
613
+ ), TestMM)
614
+ assert_problems([[/unknown child role 'notdefined'/i, 3]], problems)
615
+ end
616
+
617
+ def test_not_a_child_role
618
+ env, problems = instantiate(%Q(
619
+ TestNode {
620
+ text:
621
+ TestNode
622
+ others:
623
+ TestNode
624
+ }
625
+ ), TestMM)
626
+ assert_problems([
627
+ [/role 'text' can not take child elements/i, 3],
628
+ [/role 'others' can not take child elements/i, 5]
629
+ ], problems)
630
+ end
631
+
632
+ def test_not_a_single_child
633
+ env, problems = instantiate(%Q(
634
+ TestNode {
635
+ singleChild: [
636
+ TestNode
637
+ TestNode
638
+ ]
639
+ }
640
+ ), TestMM2)
641
+ assert_problems([
642
+ [/only one child allowed in role 'singleChild'/i, 5]
643
+ ], problems)
644
+ end
645
+
646
+ def test_not_a_single_child2
647
+ env, problems = instantiate(%Q(
648
+ TestNode {
649
+ singleChild:
650
+ TestNode
651
+ singleChild: [
652
+ ]
653
+ singleChild:
654
+ TestNode
655
+ }
656
+ ), TestMM2)
657
+ assert_problems([
658
+ [/only one child allowed in role 'singleChild'/i, 8]
659
+ ], problems)
660
+ end
661
+
662
+ def test_wrong_child_role
663
+ env, problems = instantiate(%Q(
664
+ TestNode {
665
+ singleChild:
666
+ TestNode2
667
+ }
668
+ ), TestMM2)
669
+ assert_problems([
670
+ [/role 'singleChild' can not take a TestNode2, expected TestNode/i, 4]
671
+ ], problems)
672
+ end
673
+
674
+ def test_child_role_without_child
675
+ env, problems = instantiate(%Q(
676
+ TestNode {
677
+ singleChild:
678
+ }
679
+ ), TestMM2)
680
+ assert_problems([
681
+ [/unexpected \}, expected identifier/i, 4]
682
+ ], problems)
683
+ end
684
+
685
+ def test_wrong_child
686
+ env, problems = instantiate(%Q(
687
+ TestNode {
688
+ TestNode3
689
+ }
690
+ ), TestMM2)
691
+ assert_problems([
692
+ [/command 'TestNode3' can not be used in this context/i, 3]
693
+ ], problems)
694
+ end
695
+
696
+ def test_ambiguous_child_role
697
+ env, problems = instantiate(%Q(
698
+ TestNode {
699
+ TestNode2
700
+ }
701
+ ), TestMM2)
702
+ assert_problems([
703
+ [/role of element is ambiguous, use a role label/i, 3]
704
+ ], problems)
705
+ end
706
+
707
+ def test_non_ambiguous_child_role_subclass
708
+ env, problems = instantiate(%Q(
709
+ TestNode {
710
+ TestNode4
711
+ }
712
+ ), TestMM2)
713
+ assert_no_problems(problems)
714
+ end
715
+
716
+ def test_not_a_single_child3
717
+ env, problems = instantiate(%Q(
718
+ TestNode {
719
+ TestNode
720
+ TestNode
721
+ }
722
+ ), TestMM2)
723
+ assert_problems([
724
+ [/only one child allowed in role 'singleChild'/i, 4]
725
+ ], problems)
726
+ end
727
+
728
+ def test_unknown_argument
729
+ env, problems = instantiate(%Q(
730
+ TestNode unknown: "some text"
731
+ ), TestMM)
732
+ assert_problems([[/unknown argument 'unknown'/i, 2]], problems)
733
+ end
734
+
735
+ def test_attribute_in_child_reference
736
+ env, problems = instantiate(%Q(
737
+ TestNode singleChild: "some text"
738
+ ), TestMM2)
739
+ assert_problems([[/argument 'singleChild' can only take child elements/i, 2]], problems)
740
+ end
741
+
742
+ def test_arguments_duplicate
743
+ env, problems = instantiate(%Q(
744
+ TestNode text: "some text", text: "more text"
745
+ ), TestMM)
746
+ assert_problems([[/argument 'text' already defined/i, 2]], problems)
747
+ end
748
+
749
+ def test_unlabled_arguments_duplicate
750
+ env, problems = instantiate(%Q(
751
+ TestNode text: "some text", "more text"
752
+ ), TestMM, :unlabled_arguments => proc {|c| ["text"]})
753
+ assert_problems([[/argument 'text' already defined/i, 2]], problems)
754
+ end
755
+
756
+ def test_multiple_arguments_in_non_many_attribute
757
+ env, problems = instantiate(%Q(
758
+ TestNode text: ["text1", "text2"]
759
+ ), TestMM)
760
+ assert_problems([[/argument 'text' can take only one value/i, 2]], problems)
761
+ end
762
+
763
+ def test_wrong_argument_type
764
+ env, problems = instantiate(%Q(
765
+ TestNode text: 1
766
+ TestNode integer: "text"
767
+ TestNode integer: true
768
+ TestNode integer: 1.2
769
+ TestNode integer: a
770
+ TestNode integer: /a
771
+ TestNode enum: 1
772
+ TestNode enum: x
773
+ TestNode related: 1
774
+ ), TestMM)
775
+ assert_problems([
776
+ [/argument 'integer' can not take a string, expected integer/i, 3],
777
+ [/argument 'integer' can not take a boolean, expected integer/i, 4],
778
+ [/argument 'integer' can not take a float, expected integer/i, 5],
779
+ [/argument 'integer' can not take a identifier, expected integer/i, 6],
780
+ [/argument 'integer' can not take a reference, expected integer/i, 7],
781
+ [/argument 'enum' can not take a integer, expected identifier/i, 8],
782
+ [/argument 'enum' can not take value x, expected A, B/i, 9],
783
+ [/argument 'related' can not take a integer, expected reference, identifier/i, 10]
784
+ ], problems)
785
+ end
786
+
787
+ def test_missing_opening_brace
788
+ env, problems = instantiate(%Q(
789
+ TestNode
790
+ }
791
+ ), TestMM)
792
+ assert_problems([[/unexpected \}, expected identifier/i, 3]], problems)
793
+ end
794
+
795
+ def test_invalid_root
796
+ env, problems = instantiate(%Q(
797
+ NonRootClass
798
+ ), TestMMNonRootClass)
799
+ assert_problems([[/command 'NonRootClass' can not be used on root level/i, 2]], problems)
800
+ end
801
+
802
+ def test_invalid_root_label
803
+ root_elements = []
804
+ env, problems = instantiate(%Q(
805
+ TestNode text : A
806
+ ), TestMM, :root_elements => root_elements)
807
+ assert_problems([
808
+ [/Unexpected unlabled argument, 0 unlabled arguments expected/i, 2],
809
+ [/Unexpected :, expected newline/i, 2]
810
+ ], problems)
811
+ end
812
+
813
+ #
814
+ # problem recovery
815
+ #
816
+
817
+ def test_missing_value
818
+ root_elements = []
819
+ env, problems = instantiate(%Q(
820
+ TestNode nums: 1, text:
821
+ TestNode nums: 2, text: {
822
+ SubNode
823
+ }
824
+ TestNode text: ,nums: 3 {
825
+ SubNode
826
+ }
827
+ TestNode nums: , text: , bla:
828
+ ), TestMM, :root_elements => root_elements)
829
+ assert_equal 4, root_elements.size
830
+ assert_equal [1], root_elements[0].nums
831
+ assert_nil root_elements[0].text
832
+ assert_equal [2], root_elements[1].nums
833
+ assert_equal 1, root_elements[1].childs.size
834
+ assert_equal [3], root_elements[2].nums
835
+ assert_equal 1, root_elements[2].childs.size
836
+ assert_problems([
837
+ [/unexpected newline, expected.*integer/i, 2],
838
+ [/unexpected \{, expected.*integer/i, 3],
839
+ [/unexpected ,, expected.*integer/i, 6],
840
+ [/unexpected ,, expected.*integer/i, 9],
841
+ [/unexpected ,, expected.*integer/i, 9],
842
+ [/unexpected newline, expected.*integer/i, 9],
843
+ [/unknown argument 'bla'/i, 9],
844
+ ], problems)
845
+ end
846
+
847
+ def test_missing_comma
848
+ root_elements = []
849
+ env, problems = instantiate(%Q(
850
+ TestNode nums: 1 text: "bla"
851
+ ), TestMM, :root_elements => root_elements)
852
+ assert_equal 1, root_elements.size
853
+ assert_equal [1], root_elements[0].nums
854
+ assert_equal "bla", root_elements[0].text
855
+ assert_problems([
856
+ [/unexpected label .*, expected ,/i, 2],
857
+ ], problems)
858
+ end
859
+
860
+ def test_missing_label
861
+ root_elements = []
862
+ env, problems = instantiate(%Q(
863
+ TestNode nums: 1 "bla"
864
+ ), TestMM, :root_elements => root_elements)
865
+ assert_equal 1, root_elements.size
866
+ assert_equal [1], root_elements[0].nums
867
+ assert_problems([
868
+ [/unexpected string 'bla', expected ,/i, 2],
869
+ [/unexpected unlabled argument/i, 2]
870
+ ], problems)
871
+ end
872
+
873
+ def test_unclosed_bracket1
874
+ root_elements = []
875
+ env, problems = instantiate(%Q(
876
+ TestNode nums: [1, "bla"
877
+ ), TestMM, :root_elements => root_elements)
878
+ assert_equal 1, root_elements.size
879
+ assert_equal [1], root_elements[0].nums
880
+ assert_nil root_elements[0].text
881
+ assert_problems([
882
+ [/unexpected newline, expected \]/i, 2],
883
+ [/argument 'nums' can not take a string, expected integer/i, 2],
884
+ ], problems)
885
+ end
886
+
887
+ def test_unclosed_bracket2
888
+ root_elements = []
889
+ env, problems = instantiate(%Q(
890
+ TestNode nums: [1, text: "bla"
891
+ ), TestMM, :root_elements => root_elements)
892
+ assert_equal 1, root_elements.size
893
+ assert_equal [1], root_elements[0].nums
894
+ assert_equal "bla", root_elements[0].text
895
+ assert_problems([
896
+ [/unexpected label 'text', expected identifier/i, 2],
897
+ ], problems)
898
+ end
899
+
900
+ def test_unclosed_bracket3
901
+ root_elements = []
902
+ env, problems = instantiate(%Q(
903
+ TestNode nums: [1 text: "bla"
904
+ ), TestMM, :root_elements => root_elements)
905
+ assert_equal 1, root_elements.size
906
+ assert_equal [1], root_elements[0].nums
907
+ assert_equal "bla", root_elements[0].text
908
+ assert_problems([
909
+ [/unexpected label 'text', expected \]/i, 2],
910
+ ], problems)
911
+ end
912
+
913
+ def test_unclosed_bracket4
914
+ root_elements = []
915
+ env, problems = instantiate(%Q(
916
+ TestNode nums: [1 "bla"
917
+ ), TestMM, :root_elements => root_elements)
918
+ assert_equal 1, root_elements.size
919
+ assert_equal [1], root_elements[0].nums
920
+ assert_nil root_elements[0].text
921
+ assert_problems([
922
+ [/unexpected string 'bla', expected ,/i, 2],
923
+ [/argument 'nums' can not take a string, expected integer/i, 2],
924
+ [/unexpected newline, expected \]/i, 2],
925
+ ], problems)
926
+ end
927
+
928
+ def test_unclosed_bracket5
929
+ root_elements = []
930
+ env, problems = instantiate(%Q(
931
+ TestNode [1, "bla"
932
+ ), TestMM, :root_elements => root_elements)
933
+ assert_equal 1, root_elements.size
934
+ assert_equal [], root_elements[0].nums
935
+ assert_nil root_elements[0].text
936
+ assert_problems([
937
+ [/unexpected newline, expected \]/i, 2],
938
+ [/unexpected unlabled argument/i, 2],
939
+ ], problems)
940
+ end
941
+
942
+ def test_unclosed_bracket6
943
+ root_elements = []
944
+ env, problems = instantiate(%Q(
945
+ TestNode [1, "bla" [
946
+ ), TestMM, :root_elements => root_elements)
947
+ assert_equal 1, root_elements.size
948
+ assert_problems([
949
+ [/unexpected \[, expected \]/i, 2],
950
+ [/unexpected end of file, expected \]/i, 2],
951
+ [/unexpected unlabled argument/i, 2],
952
+ [/unexpected unlabled argument/i, 2],
953
+ ], problems)
954
+ end
955
+
956
+ def test_unclosed_bracket7
957
+ root_elements = []
958
+ env, problems = instantiate(%Q(
959
+ TestNode [1, "bla", [
960
+ ), TestMM, :root_elements => root_elements)
961
+ assert_equal 1, root_elements.size
962
+ assert_problems([
963
+ [/unexpected \[, expected identifier/i, 2],
964
+ [/unexpected unlabled argument/i, 2],
965
+ [/unexpected unlabled argument/i, 2],
966
+ [/unexpected end of file, expected \]/i, 2],
967
+ ], problems)
968
+ end
969
+
970
+ def test_closing_bracket
971
+ root_elements = []
972
+ env, problems = instantiate(%Q(
973
+ TestNode ]
974
+ TestNode 1 ]
975
+ TestNode 1, ]
976
+ TestNode nums: ]1, "bla"
977
+ TestNode text: "bla" ]
978
+ ), TestMM, :root_elements => root_elements)
979
+ assert_equal 5, root_elements.size
980
+ assert_equal [], root_elements[3].nums
981
+ assert_equal "bla", root_elements[4].text
982
+ assert_problems([
983
+ [/unexpected \], expected newline/i, 2],
984
+ [/unexpected \], expected newline/i, 3],
985
+ [/unexpected unlabled argument/i, 3],
986
+ [/unexpected \], expected identifier/i, 4],
987
+ [/unexpected unlabled argument/i, 4],
988
+ [/unexpected \], expected identifier/i, 5],
989
+ [/unexpected \], expected newline/i, 6],
990
+ ], problems)
991
+ end
992
+
993
+ def test_closing_brace
994
+ root_elements = []
995
+ env, problems = instantiate(%Q(
996
+ TestNode }
997
+ TestNode 1 }
998
+ TestNode 1, }
999
+ TestNode nums: }1, "bla"
1000
+ TestNode text: "bla" }
1001
+ ), TestMM, :root_elements => root_elements)
1002
+ assert_equal 5, root_elements.size
1003
+ assert_equal [], root_elements[3].nums
1004
+ assert_equal "bla", root_elements[4].text
1005
+ assert_problems([
1006
+ [/unexpected \}, expected newline/i, 2],
1007
+ [/unexpected \}, expected newline/i, 3],
1008
+ [/unexpected unlabled argument/i, 3],
1009
+ [/unexpected \}, expected identifier/i, 4],
1010
+ [/unexpected unlabled argument/i, 4],
1011
+ [/unexpected \}, expected identifier/i, 5],
1012
+ [/unexpected \}, expected newline/i, 6],
1013
+ ], problems)
1014
+ end
1015
+
1016
+ def test_starting_non_command
1017
+ root_elements = []
1018
+ env, problems = instantiate(%Q(
1019
+ \)
1020
+ TestNode
1021
+ *
1022
+ TestNode
1023
+ $
1024
+ TestNode
1025
+ ,
1026
+ TestNode
1027
+ [
1028
+ TestNode
1029
+ {
1030
+ TestNode
1031
+ ]
1032
+ TestNode
1033
+ }
1034
+ TestNode
1035
+ }}
1036
+ ), TestMM, :root_elements => root_elements)
1037
+ assert_equal 8, root_elements.size
1038
+ assert_problems([
1039
+ [/parse error on token '\)'/i, 2],
1040
+ [/parse error on token '\*'/i, 4],
1041
+ [/parse error on token '\$'/i, 6],
1042
+ [/unexpected ,, expected identifier/i, 8],
1043
+ [/unexpected \[, expected identifier/i, 10],
1044
+ [/unexpected \{, expected identifier/i, 12],
1045
+ [/unexpected \], expected identifier/i, 14],
1046
+ [/unexpected \}, expected identifier/i, 16],
1047
+ [/unexpected \}, expected identifier/i, 18],
1048
+ ], problems)
1049
+ end
1050
+
1051
+ def test_parse_error_in_argument_list
1052
+ root_elements = []
1053
+ env, problems = instantiate(%Q(
1054
+ TestNode text: "bla", * nums: 1
1055
+ TestNode text: "bla" * , nums: 1
1056
+ TestNode ?text: "bla"
1057
+ TestNode nums: [1, * 3]
1058
+ ), TestMM, :root_elements => root_elements)
1059
+ assert_equal 4, root_elements.size
1060
+ assert_equal "bla", root_elements[0].text
1061
+ assert_equal [1], root_elements[0].nums
1062
+ assert_equal "bla", root_elements[1].text
1063
+ assert_equal [1], root_elements[1].nums
1064
+ assert_equal "bla", root_elements[2].text
1065
+ assert_equal [1, 3], root_elements[3].nums
1066
+ assert_problems([
1067
+ [/parse error on token '\*'/i, 2],
1068
+ [/parse error on token '\*'/i, 3],
1069
+ [/parse error on token '\?'/i, 4],
1070
+ [/parse error on token '\*'/i, 5],
1071
+ ], problems)
1072
+ end
1073
+
1074
+ def test_unclosed_brace
1075
+ root_elements = []
1076
+ env, problems = instantiate(%Q(
1077
+ TestNode {
1078
+ ), TestMM, :root_elements => root_elements)
1079
+ assert_equal 1, root_elements.size
1080
+ assert_problems([
1081
+ [/unexpected end of file, expected \}/i, 2]
1082
+ ], problems)
1083
+ end
1084
+
1085
+ def test_unclosed_brace2
1086
+ root_elements = []
1087
+ env, problems = instantiate(%Q(
1088
+ TestNode {
1089
+ *
1090
+ ), TestMM, :root_elements => root_elements)
1091
+ assert_equal 1, root_elements.size
1092
+ assert_problems([
1093
+ [/parse error on token '\*'/i, 3]
1094
+ ], problems)
1095
+ end
1096
+
1097
+ def test_unclosed_brace3
1098
+ root_elements = []
1099
+ env, problems = instantiate(%Q(
1100
+ TestNode {
1101
+ childs:
1102
+ ), TestMM, :root_elements => root_elements)
1103
+ assert_equal 1, root_elements.size
1104
+ assert_problems([
1105
+ [/unexpected end of file, expected identifier/i, 3]
1106
+ ], problems)
1107
+ end
1108
+
1109
+ def test_label_without_child
1110
+ root_elements = []
1111
+ env, problems = instantiate(%Q(
1112
+ TestNode {
1113
+ childs:
1114
+ }
1115
+ ), TestMM, :root_elements => root_elements)
1116
+ assert_equal 1, root_elements.size
1117
+ assert_problems([
1118
+ [/unexpected \}, expected identifier/i, 4]
1119
+ ], problems)
1120
+ end
1121
+
1122
+ def test_unclosed_child_bracket
1123
+ root_elements = []
1124
+ env, problems = instantiate(%Q(
1125
+ TestNode {
1126
+ childs: [
1127
+ ), TestMM, :root_elements => root_elements)
1128
+ assert_equal 1, root_elements.size
1129
+ assert_problems([
1130
+ [/unexpected end of file, expected \]/i, 3]
1131
+ ], problems)
1132
+ end
1133
+
1134
+ def test_child_label_problems
1135
+ root_elements = []
1136
+ env, problems = instantiate(%Q(
1137
+ TestNode {
1138
+ childs: x
1139
+ SubNode
1140
+ childs: *
1141
+ SubNode
1142
+ childs: &
1143
+ }
1144
+ ), TestMM, :root_elements => root_elements)
1145
+ assert_equal 1, root_elements.size
1146
+ assert_equal 2, root_elements[0].childs.size
1147
+ assert_problems([
1148
+ [/unexpected identifier 'x', expected newline/i, 3],
1149
+ [/parse error on token '\*'/i, 5],
1150
+ [/parse error on token '&'/i, 7]
1151
+ ], problems)
1152
+ end
1153
+
1154
+ def test_child_label_problems_with_bracket
1155
+ root_elements = []
1156
+ env, problems = instantiate(%Q(
1157
+ TestNode {
1158
+ childs: [ x
1159
+ SubNode
1160
+ ]
1161
+ childs: [ *
1162
+ SubNode
1163
+ ]
1164
+ childs: [&
1165
+ ]
1166
+ }
1167
+ ), TestMM, :root_elements => root_elements)
1168
+ assert_equal 1, root_elements.size
1169
+ assert_equal 2, root_elements[0].childs.size
1170
+ assert_problems([
1171
+ [/unexpected identifier 'x', expected newline/i, 3],
1172
+ [/parse error on token '\*'/i, 6],
1173
+ [/parse error on token '&'/i, 9]
1174
+ ], problems)
1175
+ end
1176
+
1177
+ def test_missing_closing_bracket
1178
+ root_elements = []
1179
+ env, problems = instantiate(%Q(
1180
+ TestNode {
1181
+ childs: [
1182
+ SubNode
1183
+ childs: [
1184
+ SubNode
1185
+ SubNode
1186
+ }
1187
+ ), TestMM, :root_elements => root_elements)
1188
+ assert_equal 1, root_elements.size
1189
+ assert_equal 3, root_elements[0].childs.size
1190
+ assert_problems([
1191
+ [/unexpected label 'childs', expected identifier/i, 5],
1192
+ [/unexpected \}, expected identifier/i, 8],
1193
+ ], problems)
1194
+ end
1195
+
1196
+ def test_missing_closing_brace
1197
+ root_elements = []
1198
+ env, problems = instantiate(%Q(
1199
+ TestNode {
1200
+ TestNode {
1201
+ TestNode
1202
+ }
1203
+ ), TestMM, :root_elements => root_elements)
1204
+ assert_equal 1, root_elements.size
1205
+ assert_equal 1, root_elements[0].childs.size
1206
+ assert_equal 1, root_elements[0].childs[0].childs.size
1207
+ assert_problems([
1208
+ [/unexpected end of file, expected \}/i, 5],
1209
+ ], problems)
1210
+ end
1211
+
1212
+ #
1213
+ # command name provider
1214
+ #
1215
+
1216
+ def test_command_name_provider
1217
+ env, problems = instantiate(%Q(
1218
+ TestNodeX text: "some text", nums: [1,2] {
1219
+ TestNodeX text: "child"
1220
+ TestNodeX text: "child2"
1221
+ }
1222
+ ), TestMM, :command_name_provider => proc do |c|
1223
+ c.name + "X"
1224
+ end)
1225
+ assert_no_problems(problems)
1226
+ assert_model_simple(env, :with_nums)
1227
+ end
1228
+
1229
+ def test_command_name_provider_ambiguous
1230
+ begin
1231
+ env, problems = instantiate(%Q(
1232
+ TestNode
1233
+ ), TestMM, :command_name_provider => proc do |c|
1234
+ "Fixed"
1235
+ end)
1236
+ assert false
1237
+ rescue RuntimeError => e
1238
+ assert e.message =~ /ambiguous command name/
1239
+ end
1240
+ end
1241
+
1242
+ #
1243
+ # comment handler
1244
+ #
1245
+
1246
+ def test_comment_handler
1247
+ proc_calls = 0
1248
+ env, problems = instantiate(%Q(
1249
+ #comment
1250
+ TestNode text: "node1"
1251
+ #comment
1252
+ # multiline
1253
+ TestNode text: "node2"
1254
+ TestNode text: "node3" #comment
1255
+ #above
1256
+ TestNode text: "node4" {#right1
1257
+ childs: [ #right2
1258
+ #unassociated1
1259
+ ] #right3
1260
+ #unassociated2
1261
+ } #below
1262
+ #above1
1263
+ #above2
1264
+ TestNode text: "node5" { #right1
1265
+ childs: #right2
1266
+ TestNode
1267
+ }#below
1268
+ #comment without
1269
+ #an element following
1270
+ ), TestMM, :comment_handler => proc {|c,k,e,env|
1271
+ proc_calls += 1
1272
+ if e.nil?
1273
+ case proc_calls
1274
+ when 4
1275
+ assert_equal "unassociated1", c
1276
+ assert_equal :unassociated, k
1277
+ when 5
1278
+ assert_equal "unassociated2", c
1279
+ assert_equal :unassociated, k
1280
+ when 15
1281
+ assert_equal "comment without\nan element following", c
1282
+ assert_equal :unassociated, k
1283
+ end
1284
+ elsif e.text == "node1"
1285
+ assert_equal "comment", c
1286
+ assert_equal :above, k
1287
+ elsif e.text == "node2"
1288
+ assert_equal "comment\n multiline", c
1289
+ assert_equal :above, k
1290
+ elsif e.text == "node3"
1291
+ assert_equal "comment", c
1292
+ assert_equal :eol, k
1293
+ elsif e.text == "node4"
1294
+ case proc_calls
1295
+ when 6
1296
+ assert_equal "above", c
1297
+ assert_equal :above, k
1298
+ when 7
1299
+ assert_equal "right1", c
1300
+ assert_equal :eol, k
1301
+ when 8
1302
+ assert_equal "right2", c
1303
+ assert_equal :eol, k
1304
+ when 9
1305
+ assert_equal "right3", c
1306
+ assert_equal :eol, k
1307
+ when 10
1308
+ assert_equal "below", c
1309
+ assert_equal :eol, k
1310
+ end
1311
+ elsif e.text == "node5"
1312
+ case proc_calls
1313
+ when 11
1314
+ assert_equal "above1\nabove2", c
1315
+ assert_equal :above, k
1316
+ when 12
1317
+ assert_equal "right1", c
1318
+ assert_equal :eol, k
1319
+ when 13
1320
+ assert_equal "right2", c
1321
+ assert_equal :eol, k
1322
+ when 14
1323
+ assert_equal "below", c
1324
+ assert_equal :eol, k
1325
+ end
1326
+ else
1327
+ assert false, "unexpected element in comment handler"
1328
+ end
1329
+ true
1330
+ })
1331
+ assert_no_problems(problems)
1332
+ assert_equal 15, proc_calls
1333
+ end
1334
+
1335
+ def test_comment_handler_comment_not_allowed
1336
+ env, problems = instantiate(%Q(
1337
+ #comment
1338
+ TestNode
1339
+ ), TestMM, :comment_handler => proc {|c,k,e,env|
1340
+ false
1341
+ })
1342
+ assert_problems([[/element can not take this comment/, 3]], problems)
1343
+ end
1344
+
1345
+ def test_comment_handler_comment_not_allowed_unassociated
1346
+ env, problems = instantiate(%Q(
1347
+ #comment
1348
+ ), TestMM, :comment_handler => proc {|c,k,e,env|
1349
+ false
1350
+ })
1351
+ assert_problems([[/Unassociated comment not allowed/, 2]], problems)
1352
+ end
1353
+
1354
+ #
1355
+ # annotations
1356
+ #
1357
+
1358
+ def test_annotation_not_supported
1359
+ env, problems = instantiate(%Q(
1360
+ @annotation
1361
+ TestNode
1362
+ ), TestMM)
1363
+ assert_problems([[/annotation not allowed/i, 3]], problems)
1364
+ end
1365
+
1366
+ def test_annotation_not_allowed
1367
+ env, problems = instantiate(%Q(
1368
+ @annotation
1369
+ TestNode
1370
+ ), TestMM, :annotation_handler => proc {|a,e,env|
1371
+ false
1372
+ })
1373
+ assert_problems([[/annotation not allowed/i, 3]], problems)
1374
+ end
1375
+
1376
+ def test_annotation_in_wrong_places
1377
+ env, problems = instantiate(%Q(
1378
+ @annotation
1379
+ #comment
1380
+ TestNode {
1381
+ @annotation
1382
+ childs:
1383
+ TestNode
1384
+ @annotation
1385
+ }
1386
+ @annotation
1387
+ ), TestMM)
1388
+ assert_problems([
1389
+ [/unexpected comment 'comment', expected identifier/i, 3],
1390
+ [/unexpected label 'childs', expected identifier/i, 6],
1391
+ [/unexpected \}, expected identifier/i, 9],
1392
+ [/unexpected end of file, expected identifier/i, 10]
1393
+ ], problems)
1394
+ end
1395
+
1396
+ def test_annotation_handler
1397
+ annotations = []
1398
+ elements = []
1399
+ env, problems = instantiate(%Q(
1400
+ @annotation
1401
+ TestNode text: "aa"
1402
+ @annotation
1403
+ @ in a new line
1404
+
1405
+ @ even with space in between
1406
+
1407
+ TestNode text: "bb" {
1408
+ @at child
1409
+ TestNode text: "cc"
1410
+ childs:
1411
+ @after label
1412
+ TestNode text: "dd"
1413
+ @another child
1414
+ TestNode text: "ee"
1415
+ childs: [
1416
+ @in brackets
1417
+ TestNode text: "ff"
1418
+ ]
1419
+ }
1420
+ ), TestMM, :annotation_handler => proc {|a,e,env|
1421
+ annotations << a
1422
+ elements << e
1423
+ true
1424
+ })
1425
+ assert_equal "aa", elements[0].text
1426
+ assert_equal "annotation", annotations[0]
1427
+ assert_equal "cc", elements[1].text
1428
+ assert_equal "at child", annotations[1]
1429
+ assert_equal "dd", elements[2].text
1430
+ assert_equal "after label", annotations[2]
1431
+ assert_equal "ee", elements[3].text
1432
+ assert_equal "another child", annotations[3]
1433
+ assert_equal "ff", elements[4].text
1434
+ assert_equal "in brackets", annotations[4]
1435
+ assert_equal "bb", elements[5].text
1436
+ assert_equal "annotation\n in a new line\n even with space in between", annotations[5]
1437
+ assert_no_problems(problems)
1438
+ end
1439
+
1440
+ #
1441
+ # generics
1442
+ #
1443
+
1444
+ def test_generics_parse_error
1445
+ env, problems = instantiate(%Q(
1446
+ TestNode text: <bla
1447
+ TestNode text: bla>
1448
+ TestNode text: <a<b>
1449
+ TestNode text: <a>b>
1450
+ TestNode text: <%a
1451
+ TestNode text: <%a%
1452
+ TestNode text: <%a%>b%>
1453
+ ), TestMM, :enable_generics => true)
1454
+ assert_problems([
1455
+ [/parse error on token '<'/i, 2],
1456
+ [/unexpected unlabled argument/i, 2],
1457
+ [/parse error on token '>'/i, 3],
1458
+ [/unexpected identifier 'b'/i, 5],
1459
+ [/parse error on token '>'/i, 5],
1460
+ [/unexpected unlabled argument/i, 5],
1461
+ [/parse error on token '<'/i, 6],
1462
+ [/unexpected unlabled argument/i, 6],
1463
+ [/parse error on token '<'/i, 7],
1464
+ [/unexpected unlabled argument/i, 7],
1465
+ [/parse error on token '%'/i, 7],
1466
+ [/unexpected identifier 'b'/i, 8],
1467
+ [/unexpected unlabled argument/i, 8],
1468
+ [/parse error on token '%'/i, 8],
1469
+ ], problems)
1470
+ end
1471
+
1472
+ def test_generics
1473
+ root_elements = []
1474
+ env, problems = instantiate(%q(
1475
+ TestNode text: <bla>, nums: [<1>, <%2%>], boolean: <truthy>, enum: <%option%>, float: <precise>, related: <%noderef%>, others: [<other1>, <%other2%>]
1476
+ ), TestMM, :root_elements => root_elements, :enable_generics => true)
1477
+ assert_no_problems(problems)
1478
+ assert root_elements[0].text.is_a?(RText::Generic)
1479
+ assert_equal "bla", root_elements[0].text.string
1480
+ assert_equal ["1", "2"], root_elements[0].nums.collect{|n| n.string}
1481
+ assert_equal "truthy", root_elements[0].boolean.string
1482
+ assert_equal "option", root_elements[0].enum.string
1483
+ assert_equal "precise", root_elements[0].float.string
1484
+ assert_equal "noderef", root_elements[0].related.string
1485
+ assert_equal ["other1", "other2"], root_elements[0].others.collect{|n| n.string}
1486
+ end
1487
+
1488
+ def test_generics_forbidden
1489
+ env, problems = instantiate(%Q(\
1490
+ TestNode text: <bla>
1491
+ ), TestMM)
1492
+ assert_problems([
1493
+ [/generic value not allowed/i, 1],
1494
+ ], problems)
1495
+ end
1496
+
1497
+ #
1498
+ # subpackages
1499
+ #
1500
+
1501
+ def test_subpackage
1502
+ env, problems = instantiate(%q(
1503
+ TestNodeSub text: "something"
1504
+ ), TestMMSubpackage)
1505
+ assert_no_problems(problems)
1506
+ assert_equal "something", env.elements.first.text
1507
+ end
1508
+
1509
+ #
1510
+ # values
1511
+ #
1512
+
1513
+ def test_escapes
1514
+ env, problems = instantiate(%q(
1515
+ TestNode text: "some \" \\\\ \\\\\" text \r xx \n xx \r\n xx \t xx \b xx \f"
1516
+ ), TestMM)
1517
+ assert_no_problems(problems)
1518
+ assert_equal %Q(some " \\ \\" text \r xx \n xx \r\n xx \t xx \b xx \f), env.elements.first.text
1519
+ end
1520
+
1521
+ def test_escape_single_backslash
1522
+ env, problems = instantiate(%q(
1523
+ TestNode text: "a single \\ will be just itself"
1524
+ ), TestMM)
1525
+ assert_no_problems(problems)
1526
+ assert_equal %q(a single \\ will be just itself), env.elements.first.text
1527
+ end
1528
+
1529
+ def test_string_umlauts
1530
+ env, problems = instantiate(%q(
1531
+ TestNode text: "ä, ö, ü"
1532
+ ), TestMM)
1533
+ assert_no_problems(problems)
1534
+ assert_equal %q(ä, ö, ü), env.elements.first.text
1535
+ end
1536
+
1537
+ def test_integer
1538
+ env, problems = instantiate(%q(
1539
+ TestNode integer: 7
1540
+ TestNode integer: 4294967296
1541
+ TestNode integer: 12345678901234567890
1542
+ ), TestMM)
1543
+ assert_no_problems(problems)
1544
+ assert_equal 7, env.elements[0].integer
1545
+ assert_equal 4294967296, env.elements[1].integer
1546
+ assert_equal 12345678901234567890, env.elements[2].integer
1547
+ end
1548
+
1549
+ def test_integer_hex
1550
+ env, problems = instantiate(%q(
1551
+ TestNode text: root {
1552
+ TestNode integer: 0x7
1553
+ TestNode integer: 0X7
1554
+ TestNode integer: 0x007
1555
+ TestNode integer: 0x77
1556
+ TestNode integer: 0xabCDEF
1557
+ TestNode integer: 0xabcdefabcdefabcdef
1558
+ }
1559
+ ), TestMM)
1560
+ assert_no_problems(problems)
1561
+ assert_equal [7, 7, 7, 0x77, 0xABCDEF, 0xabcdefabcdefabcdef], env.find(:text => "root").first.childs.collect{|c| c.integer}
1562
+ end
1563
+
1564
+ def test_float
1565
+ env, problems = instantiate(%q(
1566
+ TestNode float: 1.23
1567
+ TestNode float: 1.23e-08
1568
+ TestNode float: 1.23e+10
1569
+ TestNode float: 1234567890.123456789
1570
+ ), TestMM)
1571
+ assert_no_problems(problems)
1572
+ assert_equal 1.23, env.elements[0].float
1573
+ assert_equal 1.23e-08, env.elements[1].float
1574
+ assert_equal 1.23e+10, env.elements[2].float
1575
+ if rgen_with_bigdecimal?
1576
+ assert env.elements[3].float.is_a?(BigDecimal)
1577
+ assert_equal "1234567890.123456789", env.elements[3].float.to_s("F")
1578
+ else
1579
+ assert env.elements[3].float.is_a?(Float)
1580
+ assert_equal "1234567890.1234567", env.elements[3].float.to_s
1581
+ end
1582
+ end
1583
+
1584
+ def test_boolean
1585
+ env, problems = instantiate(%q(
1586
+ TestNode text: root {
1587
+ TestNode boolean: true
1588
+ TestNode boolean: false
1589
+ }
1590
+ ), TestMM)
1591
+ assert_no_problems(problems)
1592
+ assert_equal [true, false], env.find(:text => "root").first.childs.collect{|c| c.boolean}
1593
+ end
1594
+
1595
+ def test_enum
1596
+ env, problems = instantiate(%q(
1597
+ TestNode text: root {
1598
+ TestNode enum: A
1599
+ TestNode enum: B
1600
+ TestNode enum: "non-word*chars"
1601
+ TestNode enum: "2you"
1602
+ }
1603
+ ), TestMM)
1604
+ assert_no_problems(problems)
1605
+ assert_equal [:A, :B, :'non-word*chars', :'2you'], env.find(:text => "root").first.childs.collect{|c| c.enum}
1606
+ end
1607
+
1608
+ def test_with_bom
1609
+ env, problems = instantiate(%Q(\xEF\xBB\xBF
1610
+ TestNode text: "some text", nums: [1,2] {
1611
+ TestNode text: "child"
1612
+ TestNode text: "child2"
1613
+ }
1614
+ ), TestMM)
1615
+ assert_no_problems(problems)
1616
+ assert_model_simple(env, :with_nums)
1617
+ end
1618
+
1619
+ #
1620
+ # conflicts with builtins
1621
+ #
1622
+
1623
+ def test_conflict_builtin
1624
+ env, problems = instantiate(%q(
1625
+ Data notTheBuiltin: "for sure"
1626
+ ), TestMMData)
1627
+ assert_no_problems(problems)
1628
+ assert_equal "for sure", env.elements.first.notTheBuiltin
1629
+ end
1630
+
1631
+ def test_builtin_in_subpackage
1632
+ env, problems = instantiate(%q(
1633
+ Data notTheBuiltin: "for sure"
1634
+ ), TestMMSubpackage)
1635
+ assert_no_problems(problems)
1636
+ assert_equal "for sure", env.elements.first.notTheBuiltin
1637
+ end
1638
+
1639
+ #
1640
+ # encoding
1641
+ #
1642
+
1643
+ def test_encodings
1644
+ input = %Q(TestNode text: "iso-8859-1 AE Umlaut: \xc4")
1645
+ # force encoding to binary in order to prevent exceptions on invalid byte sequences
1646
+ # if the encoding would be utf-8, there would be an exception with the string above
1647
+ input.force_encoding("binary")
1648
+ env, problems = instantiate(input, TestMM)
1649
+ assert_no_problems(problems)
1650
+ assert_match /AE Umlaut: /, env.elements.first.text
1651
+ end
1652
+
1653
+ #
1654
+ # line breaks
1655
+ #
1656
+
1657
+ def test_linebreak
1658
+ roots = []
1659
+ env, problems = instantiate(%Q(
1660
+ TestNode sometext,
1661
+ integer: 1,
1662
+ nums: [
1663
+ 1,
1664
+ 2
1665
+ ]
1666
+ ), TestMM, :root_elements => roots, :unlabled_arguments => proc {|clazz| ["text"]})
1667
+ assert_no_problems(problems)
1668
+ node = roots.first
1669
+ assert_equal "sometext", node.text
1670
+ assert_equal 1, node.integer
1671
+ assert_equal [1,2], node.nums
1672
+ end
1673
+
1674
+ def test_linebreak_backslash
1675
+ roots = []
1676
+ env, problems = instantiate(%Q(
1677
+ TestNode \\
1678
+ sometext
1679
+ ), TestMM, :root_elements => roots, :unlabled_arguments => proc {|clazz| ["text"]})
1680
+ assert_no_problems(problems)
1681
+ node = roots.first
1682
+ assert_equal "sometext", node.text
1683
+ end
1684
+
1685
+ def test_linebreak_backslash_problems
1686
+ roots = []
1687
+ env, problems = instantiate(%Q(
1688
+ TostNode \\
1689
+ sometext
1690
+ TostNode
1691
+ ), TestMM, :root_elements => roots, :unlabled_arguments => proc {|clazz| ["text"]})
1692
+ assert_problems([
1693
+ [/unknown command/i, 2],
1694
+ [/unknown command/i, 4],
1695
+ ], problems)
1696
+ end
1697
+
1698
+ module TestMMObjectAttribute
1699
+ extend RGen::MetamodelBuilder::ModuleExtension
1700
+ class TestNode < RGen::MetamodelBuilder::MMBase
1701
+ has_many_attr 'objs', Object
1702
+ end
1703
+ end
1704
+
1705
+ def test_object_attribute
1706
+ roots = []
1707
+ env, problems = instantiate(%Q(
1708
+ TestNode objs: ["some text", -123, someSymbol, true, false, -0.097]
1709
+ ), TestMMObjectAttribute, :root_elements => roots)
1710
+ assert_no_problems(problems)
1711
+ node = roots.first
1712
+ assert_equal ['some text', -123, 'someSymbol', true, false, -0.097], node.objs
1713
+ end
1714
+
1715
+ private
1716
+
1717
+ def instantiate(text, mm, options={})
1718
+ env = RGen::Environment.new
1719
+ lang = RText::Language.new(mm.ecore, options.merge(
1720
+ :root_classes => mm.ecore.eAllClasses.select{|c|
1721
+ c.name == "TestNode" || c.name == "Data" || c.name == "TestNodeSub" || c.name == "SubNode"}))
1722
+ inst = RText::Instantiator.new(lang)
1723
+ problems = []
1724
+ inst.instantiate(text, options.merge({:env => env, :problems => problems, :root_elements => options[:root_elements]}))
1725
+ return env, problems
1726
+ end
1727
+
1728
+ def assert_no_problems(problems)
1729
+ assert problems.empty?, problems.collect{|p| "#{p.message}, line: #{p.line}"}.join("\n")
1730
+ end
1731
+
1732
+ def assert_problems(expected, problems)
1733
+ remaining = problems.dup
1734
+ probs = []
1735
+ expected.each do |e|
1736
+ if e.is_a?(Array)
1737
+ p = remaining.find{|p| p.message =~ e[0] && p.line == e[1]}
1738
+ else
1739
+ p = remaining.find{|p| p.message =~ e}
1740
+ end
1741
+ probs << "expected problem not present: #{e}" if !p
1742
+ # make sure to not delete duplicate problems at once
1743
+ idx = remaining.index(p)
1744
+ remaining.delete_at(idx) if idx
1745
+ end
1746
+ remaining.each do |p|
1747
+ probs << "unexpected problem: #{p.message}, line: #{p.line}"
1748
+ end
1749
+ assert probs.empty?, probs.join("\n")
1750
+ end
1751
+
1752
+ def assert_model_simple(env, *opts)
1753
+ raise "unknown options" unless (opts - [:with_nums]).empty?
1754
+ root = env.find(:class => TestMM::TestNode, :text => "some text").first
1755
+ assert root != nil
1756
+ assert_equal 2, root.childs.size
1757
+ assert_equal [TestMM::TestNode, TestMM::TestNode], root.childs.collect{|c| c.class}
1758
+ assert_equal ["child", "child2"], root.childs.text
1759
+ if opts.include?(:with_nums)
1760
+ assert_equal [1, 2], root.nums
1761
+ end
1762
+ end
1763
+
1764
+ def rgen_with_bigdecimal?
1765
+ begin
1766
+ TestMM::TestNode.new.float = BigDecimal.new("0.0")
1767
+ rescue StandardError
1768
+ return false
1769
+ end
1770
+ true
1771
+ end
1772
+
1773
+ end