rtext 0.8.1 → 0.10.0

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