rtext 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,968 +1,967 @@
1
- # encoding: binary
2
- $:.unshift(File.dirname(__FILE__)+"/../../lib")
3
-
4
- gem 'minitest'
5
- require 'minitest/autorun'
6
- require 'rtext/frontend/connector_manager'
7
- require 'rtext/frontend/context'
8
- require 'logger'
9
-
10
- class IntegrationTest < MiniTest::Test
11
-
12
- ModelFile = File.dirname(__FILE__)+"/model/test_metamodel.ect"
13
- ModelFile2 = File.dirname(__FILE__)+"/model/test_metamodel2.ect"
14
- ModelFile3 = File.dirname(__FILE__)+"/model/test_metamodel3.ect4"
15
- LargeWithErrorsFile = File.dirname(__FILE__)+"/model/test_large_with_errors.ect3"
16
- InvalidEncodingFile = File.dirname(__FILE__)+"/model/invalid_encoding.invenc"
17
- NotInRTextFile = File.dirname(__FILE__)+"/model/test.not_in_rtext"
18
- InvalidCmdLineFile = File.dirname(__FILE__)+"/model/test.invalid_cmd_line"
19
- CrashingBackendFile = File.dirname(__FILE__)+"/model/test.crashing_backend"
20
- DontOpenSocketFile = File.dirname(__FILE__)+"/model/test.dont_open_socket"
21
- CrashOnRequestFile = File.dirname(__FILE__)+"/model/test.crash_on_request"
22
-
23
- def setup_connector(file)
24
- @infile = file
25
- outfile = File.dirname(__FILE__)+"/backend.out"
26
- logfile = File.dirname(__FILE__)+"/frontend.log"
27
- logger = Logger.new(logfile)
28
- File.unlink(outfile) if File.exist?(outfile)
29
- @connection_timeout = false
30
- man = RText::Frontend::ConnectorManager.new(
31
- :logger => logger,
32
- :keep_outfile => true,
33
- :connection_timeout => 2,
34
- :outfile_provider => lambda { File.expand_path(outfile) },
35
- :connect_callback => lambda do |connector, state|
36
- @connection_timeout = true if state == :timeout
37
- end)
38
- @con = man.connector_for_file(@infile)
39
- end
40
-
41
- def teardown
42
- @con.stop if @con
43
- end
44
-
45
- def test_non_existing_file
46
- setup_connector("this is not a file")
47
- assert_nil @con
48
- end
49
-
50
- def test_not_in_rtext_file
51
- setup_connector(NotInRTextFile)
52
- assert_nil @con
53
- end
54
-
55
- def test_invalid_command_line
56
- setup_connector(InvalidCmdLineFile)
57
- assert @con
58
- response = load_model
59
- assert @connection_timeout
60
- end
61
-
62
- def test_crashing_backend
63
- setup_connector(CrashingBackendFile)
64
- assert @con
65
- response = load_model
66
- assert @connection_timeout
67
- end
68
-
69
- def test_backend_doesnt_open_socket
70
- setup_connector(DontOpenSocketFile)
71
- assert @con
72
- response = load_model
73
- assert @connection_timeout
74
- end
75
-
76
- def test_backend_crash_on_request
77
- setup_connector(CrashOnRequestFile)
78
- assert @con
79
- response = load_model
80
- assert_equal [], response["problems"]
81
- response = @con.execute_command({"command" => "link_targets", "context" => [], "column" => 1})
82
- assert_equal :timeout, response
83
- end
84
-
85
- # simulate external encoding utf-8 (-E in .rext) containing a iso-8859-1 character
86
- def test_invalid_encoding
87
- setup_connector(InvalidEncodingFile)
88
- response = load_model
89
- assert_equal "response", response["type"]
90
- assert_equal [], response["problems"]
91
- text = %Q(EPackage "iso-8859-1 umlaut: \xe4",| nsPrefix: "")
92
- context = build_context(text)
93
- assert_completions context, [
94
- "nsPrefix:",
95
- "nsURI:"
96
- ]
97
- end
98
-
99
- def test_loadmodel
100
- setup_connector(ModelFile)
101
- response = load_model
102
- assert_equal "response", response["type"]
103
- assert_equal [], response["problems"]
104
- end
105
-
106
- def test_loadmodel_large_with_errors
107
- setup_connector(LargeWithErrorsFile)
108
- response = load_model
109
- assert_equal "response", response["type"]
110
- assert_equal 43523, response["problems"].first["problems"].size
111
- end
112
-
113
- def test_unknown_command
114
- setup_connector(ModelFile)
115
- response = load_model
116
- response = @con.execute_command({"command" => "unknown"})
117
- assert_equal "unknown_command_error", response["type"]
118
- end
119
-
120
- #TODO: connector restart when .rtext file changes
121
-
122
- def test_complete_first_line
123
- setup_connector(ModelFile)
124
- load_model
125
- context = build_context <<-END
126
- |EPackage StatemachineMM {
127
- END
128
- assert_completions context, [
129
- "EPackage"
130
- ]
131
- context = build_context <<-END
132
- EPackage| StatemachineMM {
133
- END
134
- assert_completions context, [
135
- "EPackage"
136
- ]
137
- context = build_context <<-END
138
- EPackage |StatemachineMM {
139
- END
140
- assert_completions context, [
141
- "name",
142
- "nsPrefix:",
143
- "nsURI:"
144
- ]
145
- context = build_context <<-END
146
- EPackage S|tatemachineMM {
147
- END
148
- assert_completions context, [
149
- "name",
150
- "nsPrefix:",
151
- "nsURI:"
152
- ]
153
- context = build_context <<-END
154
- EPackage StatemachineMM| {
155
- END
156
- assert_completions context, [
157
- "name",
158
- "nsPrefix:",
159
- "nsURI:"
160
- ]
161
- context = build_context <<-END
162
- EPackage StatemachineMM |{
163
- END
164
- assert_completions context, [
165
- ]
166
- context = build_context <<-END
167
- EPackage StatemachineMM {|
168
- END
169
- # these columns don't exist
170
- assert_completions context, []
171
- context = build_context({:col => 27}, "EPackage StatemachineMM {")
172
- assert_completions context, []
173
- context = build_context({:col => 28}, "EPackage StatemachineMM {")
174
- assert_completions context, []
175
- context = build_context({:col => 100}, "EPackage StatemachineMM {")
176
- assert_completions context, []
177
- # before first column is like first column
178
- context = build_context({:col => 0}, "EPackage StatemachineMM {")
179
- assert_completions context, [
180
- "EPackage"
181
- ]
182
- context = build_context({:col => -1}, "EPackage StatemachineMM {")
183
- assert_completions context, [
184
- "EPackage"
185
- ]
186
- context = build_context({:col => -100}, "EPackage StatemachineMM {")
187
- assert_completions context, [
188
- "EPackage"
189
- ]
190
- end
191
-
192
- def test_nested_command
193
- setup_connector(ModelFile)
194
- load_model
195
- context = build_context <<-END
196
- EPackage StatemachineMM {
197
- | EClass State, abstract: true {
198
- END
199
- assert_completions context, [
200
- "EAnnotation",
201
- "EClass",
202
- "EClassifier",
203
- "EDataType",
204
- "EEnum",
205
- "EGenericType",
206
- "EPackage"
207
- ]
208
- context = build_context <<-END
209
- EPackage StatemachineMM {
210
- |EClass State, abstract: true {
211
- END
212
- assert_completions context, [
213
- "EAnnotation",
214
- "EClass",
215
- "EClassifier",
216
- "EDataType",
217
- "EEnum",
218
- "EGenericType",
219
- "EPackage"
220
- ]
221
- context = build_context <<-END
222
- EPackage StatemachineMM {
223
- EC|lass State, abstract: true {
224
- END
225
- assert_completions context, [
226
- "EAnnotation",
227
- "EClass",
228
- "EClassifier",
229
- "EDataType",
230
- "EEnum",
231
- "EGenericType",
232
- "EPackage"
233
- ]
234
- context = build_context <<-END
235
- EPackage StatemachineMM {
236
- EClass| State, abstract: true {
237
- END
238
- assert_completions context, [
239
- "EAnnotation",
240
- "EClass",
241
- "EClassifier",
242
- "EDataType",
243
- "EEnum",
244
- "EGenericType",
245
- "EPackage"
246
- ]
247
- context = build_context <<-END
248
- EPackage StatemachineMM {
249
- EClass |State, abstract: true {
250
- END
251
- assert_completions context, [
252
- "name",
253
- "abstract:",
254
- "interface:",
255
- "eSuperTypes:",
256
- "instanceClassName:"
257
- ]
258
- context = build_context <<-END
259
- EPackage StatemachineMM {
260
- EClass S|tate, abstract: true {
261
- END
262
- assert_completions context, [
263
- "name",
264
- "abstract:",
265
- "interface:",
266
- "eSuperTypes:",
267
- "instanceClassName:"
268
- ]
269
- context = build_context <<-END
270
- EPackage StatemachineMM {
271
- EClass State|, abstract: true {
272
- END
273
- assert_completions context, [
274
- "name",
275
- "abstract:",
276
- "interface:",
277
- "eSuperTypes:",
278
- "instanceClassName:"
279
- ]
280
- context = build_context <<-END
281
- EPackage StatemachineMM {
282
- EClass State,| abstract: true {
283
- END
284
- assert_completions context, [
285
- "abstract:",
286
- "interface:",
287
- "eSuperTypes:",
288
- "instanceClassName:"
289
- ]
290
- context = build_context <<-END
291
- EPackage StatemachineMM {
292
- EClass State, |abstract: true {
293
- END
294
- assert_completions context, [
295
- "abstract:",
296
- "interface:",
297
- "eSuperTypes:",
298
- "instanceClassName:"
299
- ]
300
- context = build_context <<-END
301
- EPackage StatemachineMM {
302
- EClass State, a|bstract: true {
303
- END
304
- assert_completions context, [
305
- "abstract:",
306
- "interface:",
307
- "eSuperTypes:",
308
- "instanceClassName:"
309
- ]
310
- context = build_context <<-END
311
- EPackage StatemachineMM {
312
- EClass State, abstract:| true {
313
- END
314
- assert_completions context, [
315
- "true",
316
- "false"
317
- ]
318
- context = build_context <<-END
319
- EPackage StatemachineMM {
320
- EClass State, abstract: |true {
321
- END
322
- assert_completions context, [
323
- "true",
324
- "false"
325
- ]
326
- context = build_context <<-END
327
- EPackage StatemachineMM {
328
- EClass State, abstract: t|rue {
329
- END
330
- assert_completions context, [
331
- "true",
332
- "false"
333
- ]
334
- context = build_context <<-END
335
- EPackage StatemachineMM {
336
- EClass State, abstract: true| {
337
- END
338
- assert_completions context, [
339
- "true",
340
- "false"
341
- ]
342
- context = build_context <<-END
343
- EPackage StatemachineMM {
344
- EClass State, abstract: true |{
345
- END
346
- assert_completions context, [
347
- ]
348
- context = build_context <<-END
349
- EPackage StatemachineMM {
350
- EClass State, abstract: true {|
351
- END
352
- assert_completions context, [
353
- ]
354
- end
355
-
356
- def test_complete_feature_after_linebreak
357
- setup_connector(ModelFile)
358
- load_model
359
- context = build_context <<-END
360
- EPackage StatemachineMM {
361
- EClass State, abstract: true {
362
- EAttribute name, eType: /StatemachineMM/StringType
363
- EReference parent,
364
- |eType: /StatemachineMM/CompositeState,
365
- END
366
- assert_completions context, [
367
- "containment:",
368
- "resolveProxies:",
369
- "eOpposite:",
370
- "changeable:",
371
- "defaultValueLiteral:",
372
- "derived:",
373
- "transient:",
374
- "unsettable:",
375
- "volatile:",
376
- "lowerBound:",
377
- "ordered:",
378
- "unique:",
379
- "upperBound:",
380
- "eType:"
381
- ]
382
- end
383
-
384
- def test_complete_reference_after_linebreak
385
- setup_connector(ModelFile)
386
- load_model
387
- context = build_context <<-END
388
- EPackage StatemachineMM {
389
- EClass State, abstract: true {
390
- EAttribute name, eType: /StatemachineMM/StringType
391
- EReference parent,
392
- eType: |/StatemachineMM/CompositeState,
393
- END
394
- assert_completions context, [
395
- "/StatemachineMM/CompositeState",
396
- "/StatemachineMM/SimpleState",
397
- "/StatemachineMM/State",
398
- "/StatemachineMM/StringType",
399
- "/StatemachineMM/Transition",
400
- "/StatemachineMM2/SimpleState",
401
- "/StatemachineMM2/State"
402
- ]
403
- end
404
-
405
- def test_complete_command_after_linebreak
406
- setup_connector(ModelFile)
407
- load_model
408
- context = build_context <<-END
409
- EPackage StatemachineMM {
410
- EClass State, abstract: true {
411
- EAttribute name, eType: /StatemachineMM/StringType
412
- EReference parent,
413
- eType: /StatemachineMM/CompositeState,
414
- eOpposite: /StatemachineMM/CompositeState/substates
415
- }
416
- EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
417
- EClass CompositeState,
418
- eSuperTypes: [
419
- /StatemachineMM/State
420
- ],
421
- abstract: false {
422
- |EReference substates, upperBound: -1, containment: true, eType: /StatemachineMM/State, eOpposite: /StatemachineMM/State/parent
423
- END
424
- assert_completions context, [
425
- "EAnnotation",
426
- "EAttribute",
427
- "EOperation",
428
- "EReference",
429
- "EStructuralFeature"
430
- ]
431
- end
432
-
433
- def test_complete_value_after_linebreak
434
- setup_connector(ModelFile)
435
- load_model
436
- context = build_context <<-END
437
- EPackage StatemachineMM {
438
- EClass State, abstract: true {
439
- EAttribute name, eType: /StatemachineMM/StringType
440
- EReference parent,
441
- eType: /StatemachineMM/CompositeState,
442
- eOpposite: /StatemachineMM/CompositeState/substates
443
- }
444
- EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
445
- EClass CompositeState,
446
- eSuperTypes: [
447
- /StatemachineMM/State
448
- ],
449
- abstract: |false {
450
- END
451
- assert_completions context, [
452
- "true",
453
- "false"
454
- ]
455
- end
456
-
457
- def test_complete_in_array_after_linebreak
458
- setup_connector(ModelFile)
459
- load_model
460
- context = build_context <<-END
461
- EPackage StatemachineMM {
462
- EClass State, abstract: true {
463
- EAttribute name, eType: /StatemachineMM/StringType
464
- EReference parent,
465
- eType: /StatemachineMM/CompositeState,
466
- eOpposite: /StatemachineMM/CompositeState/substates
467
- }
468
- EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
469
- EClass CompositeState,
470
- eSuperTypes: [
471
- |/StatemachineMM/State
472
- END
473
- assert_completions context, [
474
- "/StatemachineMM/CompositeState",
475
- "/StatemachineMM/SimpleState",
476
- "/StatemachineMM/State",
477
- "/StatemachineMM/Transition",
478
- "/StatemachineMM2/SimpleState",
479
- "/StatemachineMM2/State"
480
- ]
481
- end
482
-
483
- def test_complete_in_array_after_linebreak2
484
- setup_connector(ModelFile)
485
- load_model
486
- context = build_context <<-END
487
- EPackage StatemachineMM {
488
- EClass State, abstract: true {
489
- EAttribute name, eType: /StatemachineMM/StringType
490
- EReference parent,
491
- eType: /StatemachineMM/CompositeState,
492
- eOpposite: /StatemachineMM/CompositeState/substates
493
- }
494
- EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
495
- EClass CompositeState,
496
- eSuperTypes: [
497
- /StatemachineMM/State
498
- |],
499
- END
500
- assert_completions context, [
501
- ]
502
- end
503
-
504
- def test_complete_after_backslash
505
- setup_connector(ModelFile3)
506
- load_model
507
- context = build_context <<-END
508
- EPackage StatemachineMM3 {
509
- EClass State
510
- EClass \\
511
- |SimpleState,
512
- END
513
- assert_completions context, [
514
- "name",
515
- "abstract:",
516
- "interface:",
517
- "eSuperTypes:",
518
- "instanceClassName:"
519
- ]
520
- end
521
-
522
- def test_complete_after_backslash2
523
- setup_connector(ModelFile3)
524
- load_model
525
- context = build_context <<-END
526
- EPackage StatemachineMM3 {
527
- EClass State
528
- EClass \\
529
- SimpleState,
530
- |eSuperTypes: [/StatemachineMM3/State]
531
- END
532
- assert_completions context, [
533
- "abstract:",
534
- "interface:",
535
- "eSuperTypes:",
536
- "instanceClassName:"
537
- ]
538
- end
539
-
540
- def test_link_target_after_backslash
541
- setup_connector(ModelFile3)
542
- load_model
543
- context = build_context <<-END
544
- EPackage StatemachineMM3 {
545
- EClass State
546
- EClass \\
547
- SimpleState,
548
- eSuperTypes: [/S|tatemachineMM3/State]
549
- END
550
- assert_link_targets context, :file => ModelFile3, :begin => 45, :end => 66, :targets => [
551
- {"file"=> File.expand_path(ModelFile3),
552
- "line"=>2,
553
- "display"=>"/StatemachineMM3/State [EClass]"}
554
- ]
555
- end
556
-
557
- def test_reference_completion
558
- setup_connector(ModelFile)
559
- load_model
560
- context = build_context <<-END
561
- EPackage StatemachineMM {
562
- EClass State, abstract: true {
563
- EAttribute name, eType: |/StatemachineMM/StringType
564
- END
565
- assert_completions context, [
566
- "/StatemachineMM/CompositeState",
567
- "/StatemachineMM/SimpleState",
568
- "/StatemachineMM/State",
569
- "/StatemachineMM/StringType",
570
- "/StatemachineMM/Transition",
571
- "/StatemachineMM2/SimpleState",
572
- "/StatemachineMM2/State",
573
- ]
574
- context = build_context <<-END
575
- EPackage StatemachineMM {
576
- EClass State, abstract: true {
577
- EAttribute name, eType: /StatemachineMM/|StringType
578
- END
579
- assert_completions context, [
580
- "/StatemachineMM/CompositeState",
581
- "/StatemachineMM/SimpleState",
582
- "/StatemachineMM/State",
583
- "/StatemachineMM/StringType",
584
- "/StatemachineMM/Transition",
585
- "/StatemachineMM2/SimpleState",
586
- "/StatemachineMM2/State",
587
- ]
588
- context = build_context <<-END
589
- EPackage StatemachineMM {
590
- EClass State, abstract: true {
591
- EAttribute name, eType: /StatemachineMM/St|ringType
592
- END
593
- assert_completions context, [
594
- "/StatemachineMM/CompositeState",
595
- "/StatemachineMM/SimpleState",
596
- "/StatemachineMM/State",
597
- "/StatemachineMM/StringType",
598
- "/StatemachineMM/Transition",
599
- "/StatemachineMM2/SimpleState",
600
- "/StatemachineMM2/State",
601
- ]
602
- context = build_context <<-END
603
- EPackage StatemachineMM {
604
- EClass State, abstract: true {
605
- EAttribute name, eType: /StatemachineMM/StringType|
606
- END
607
- assert_completions context, [
608
- "/StatemachineMM/CompositeState",
609
- "/StatemachineMM/SimpleState",
610
- "/StatemachineMM/State",
611
- "/StatemachineMM/StringType",
612
- "/StatemachineMM/Transition",
613
- "/StatemachineMM2/SimpleState",
614
- "/StatemachineMM2/State",
615
- ]
616
- end
617
-
618
- def test_reference_completion_in_array
619
- setup_connector(ModelFile)
620
- load_model
621
- context = build_context <<-END
622
- EPackage StatemachineMM {
623
- EClass State, abstract: true {
624
- EAttribute name, eType: /StatemachineMM/StringType
625
- EReference parent,
626
- eType: /StatemachineMM/CompositeState,
627
- eOpposite: /StatemachineMM/CompositeState/substates
628
- }
629
- EClass SimpleState, eSuperTypes: [|/StatemachineMM/State]
630
- END
631
- assert_completions context, [
632
- "/StatemachineMM/CompositeState",
633
- "/StatemachineMM/SimpleState",
634
- "/StatemachineMM/State",
635
- "/StatemachineMM/Transition",
636
- "/StatemachineMM2/SimpleState",
637
- "/StatemachineMM2/State",
638
- ]
639
- context = build_context <<-END
640
- EPackage StatemachineMM {
641
- EClass State, abstract: true {
642
- EAttribute name, eType: /StatemachineMM/StringType
643
- EReference parent,
644
- eType: /StatemachineMM/CompositeState,
645
- eOpposite: /StatemachineMM/CompositeState/substates
646
- }
647
- EClass SimpleState, eSuperTypes: [/StatemachineMM/S|tate]
648
- END
649
- assert_completions context, [
650
- "/StatemachineMM/CompositeState",
651
- "/StatemachineMM/SimpleState",
652
- "/StatemachineMM/State",
653
- "/StatemachineMM/Transition",
654
- "/StatemachineMM2/SimpleState",
655
- "/StatemachineMM2/State",
656
- ]
657
- context = build_context <<-END
658
- EPackage StatemachineMM {
659
- EClass State, abstract: true {
660
- EAttribute name, eType: /StatemachineMM/StringType
661
- EReference parent,
662
- eType: /StatemachineMM/CompositeState,
663
- eOpposite: /StatemachineMM/CompositeState/substates
664
- }
665
- EClass SimpleState, eSuperTypes: [/StatemachineMM/State|]
666
- END
667
- assert_completions context, [
668
- "/StatemachineMM/CompositeState",
669
- "/StatemachineMM/SimpleState",
670
- "/StatemachineMM/State",
671
- "/StatemachineMM/Transition",
672
- "/StatemachineMM2/SimpleState",
673
- "/StatemachineMM2/State",
674
- ]
675
- context = build_context <<-END
676
- EPackage StatemachineMM {
677
- EClass State, abstract: true {
678
- EAttribute name, eType: /StatemachineMM/StringType
679
- EReference parent,
680
- eType: /StatemachineMM/CompositeState,
681
- eOpposite: /StatemachineMM/CompositeState/substates
682
- }
683
- EClass SimpleState, eSuperTypes: [/StatemachineMM/State]|
684
- END
685
- assert_completions context, [
686
- ]
687
- end
688
-
689
- def test_integer_completion
690
- setup_connector(ModelFile)
691
- load_model
692
- context = build_context <<-END
693
- EPackage StatemachineMM {
694
- EClass State, abstract: true {
695
- EAttribute name, eType: /StatemachineMM/StringType
696
- EReference parent,
697
- eType: /StatemachineMM/CompositeState,
698
- eOpposite: /StatemachineMM/CompositeState/substates
699
- }
700
- EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
701
- EClass CompositeState,
702
- eSuperTypes: [
703
- /StatemachineMM/State
704
- ],
705
- abstract: false {
706
- EReference substates, upperBound: |-1, containment: true, eType: /StatemachineMM/State, eOpposite: /StatemachineMM/State/parent
707
- END
708
- assert_completions context, [
709
- "1",
710
- ]
711
- context = build_context <<-END
712
- EPackage StatemachineMM {
713
- EClass State, abstract: true {
714
- EAttribute name, eType: /StatemachineMM/StringType
715
- EReference parent,
716
- eType: /StatemachineMM/CompositeState,
717
- eOpposite: /StatemachineMM/CompositeState/substates
718
- }
719
- EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
720
- EClass CompositeState,
721
- eSuperTypes: [
722
- /StatemachineMM/State
723
- ],
724
- abstract: false {
725
- EReference substates, upperBound: -1|, containment: true, eType: /StatemachineMM/State, eOpposite: /StatemachineMM/State/parent
726
- END
727
- assert_completions context, [
728
- "1",
729
- ]
730
- end
731
-
732
- def test_link_targets
733
- setup_connector(ModelFile)
734
- load_model
735
- context = build_context <<-END
736
- EPackage StatemachineMM {
737
- EClass State, abstract: true {
738
- EAttribute name, eType: /St|atemachineMM/StringType
739
- END
740
- assert_link_targets context, :begin => 29, :end => 54, :targets => [
741
- {"file"=> File.expand_path(@infile),
742
- "line"=>20,
743
- "display"=>"/StatemachineMM/StringType [EDataType]"}
744
- ]
745
- context = build_context <<-END
746
- EPackage StatemachineMM {
747
- EClass State, abstract: true {
748
- EAttribute name, eType: |/StatemachineMM/StringType
749
- END
750
- assert_link_targets context, :begin => 29, :end => 54, :targets => [
751
- {"file"=> File.expand_path(@infile),
752
- "line"=>20,
753
- "display"=>"/StatemachineMM/StringType [EDataType]"}
754
- ]
755
- context = build_context <<-END
756
- EPackage StatemachineMM {
757
- EClass State, abstract: true {
758
- EAttribute name, eType: /StatemachineMM/StringTyp|e
759
- END
760
- assert_link_targets context, :begin => 29, :end => 54, :targets => [
761
- {"file"=> File.expand_path(@infile),
762
- "line"=>20,
763
- "display"=>"/StatemachineMM/StringType [EDataType]"}
764
- ]
765
- context = build_context <<-END
766
- EPackage StatemachineMM {
767
- EClass State, abstract: true {
768
- EAttribute name, eType: /StatemachineMM/StringType|
769
- END
770
- assert_link_targets context, :begin => nil, :end => nil, :targets => []
771
- context = build_context <<-END
772
- EPackage StatemachineMM {
773
- EClass State, abstract: true {
774
- EAttribute name, eType:| /StatemachineMM/StringType
775
- END
776
- assert_link_targets context, :begin => nil, :end => nil, :targets => []
777
- # backward ref
778
- context = build_context <<-END
779
- EPackage StatemachineMM {
780
- E|Class State, abstract: true {
781
- END
782
- assert_link_targets context, :begin => 3, :end => 8, :targets => [
783
- {"file"=> File.expand_path(@infile),
784
- "line"=>8,
785
- "display"=>"/StatemachineMM/SimpleState [EClass]"},
786
- {"file"=> File.expand_path(@infile),
787
- "line"=>9,
788
- "display"=>"/StatemachineMM/CompositeState [EClass]"}
789
- ]
790
- context = build_context <<-END
791
- EPackage StatemachineMM {
792
- EClass State, abstract: true {
793
- EAttribute name, eType: /StatemachineMM/StringType
794
- EReference parent,
795
- eType: /StatemachineMM/CompositeState,
796
- eOpposite: /StatemachineMM/CompositeState/substates
797
- }
798
- |EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
799
- END
800
- assert_link_targets context, :begin => 3, :end => 8, :targets => []
801
- # bad location
802
- context = build_context <<-END
803
- EPackage S|tatemachineMM {
804
- END
805
- assert_link_targets context, :begin => 10, :end => 23, :targets => []
806
- end
807
-
808
- def test_link_targets_no_text_after_name
809
- setup_connector(ModelFile)
810
- load_model
811
- context = build_context({:infile => ModelFile2}, <<-END
812
- EPackage StatemachineMM2 {
813
- ECl|ass State
814
- END
815
- )
816
- assert_link_targets context, :file => ModelFile2, :begin => 3, :end => 8, :targets => [
817
- {"file"=> File.expand_path(ModelFile2),
818
- "line"=>3,
819
- "display"=>"/StatemachineMM2/SimpleState [EClass]"}
820
- ]
821
- end
822
-
823
- def test_link_targets_after_linebreak
824
- setup_connector(ModelFile)
825
- load_model
826
- context = build_context <<-END
827
- EPackage StatemachineMM {
828
- EClass State, abstract: true {
829
- EAttribute name, eType: /StatemachineMM/StringType
830
- EReference parent,
831
- eType: /St|atemachineMM/CompositeState,
832
- END
833
- # in case of linebreaks, the begin and end column refer to the string which
834
- # was passed to the backend as the context; in this case the context extractor
835
- # appends each broken line to the previous line with all the leading whitespace removed
836
- assert_link_targets context, :begin => 37, :end => 66, :targets => [
837
- {"file"=> File.expand_path(@infile),
838
- "line"=>9,
839
- "display"=>"/StatemachineMM/CompositeState [EClass]"}
840
- ]
841
- context = build_context <<-END
842
- EPackage StatemachineMM {
843
- EClass State, abstract: true {
844
- EAttribute name, eType: /StatemachineMM/StringType
845
- EReference parent,
846
- eType: |/StatemachineMM/CompositeState,
847
- END
848
- assert_link_targets context, :begin => 37, :end => 66, :targets => [
849
- {"file"=> File.expand_path(@infile),
850
- "line"=>9,
851
- "display"=>"/StatemachineMM/CompositeState [EClass]"}
852
- ]
853
- context = build_context <<-END
854
- EPackage StatemachineMM {
855
- EClass State, abstract: true {
856
- EAttribute name, eType: /StatemachineMM/StringType
857
- EReference parent,
858
- eType: /StatemachineMM/CompositeStat|e,
859
- END
860
- assert_link_targets context, :begin => 37, :end => 66, :targets => [
861
- {"file"=> File.expand_path(@infile),
862
- "line"=>9,
863
- "display"=>"/StatemachineMM/CompositeState [EClass]"}
864
- ]
865
- context = build_context <<-END
866
- EPackage StatemachineMM {
867
- EClass State, abstract: true {
868
- EAttribute name, eType: /StatemachineMM/StringType
869
- EReference parent,
870
- eType: /StatemachineMM/CompositeState|,
871
- END
872
- assert_link_targets context, :begin => nil, :end => nil, :targets => []
873
- end
874
-
875
- def test_find_elements
876
- setup_connector(ModelFile)
877
- load_model
878
- response = @con.execute_command(
879
- {"command" => "find_elements", "search_pattern" => "Sta"})
880
- assert_equal \
881
- [{"display"=>"State [EClass] - /StatemachineMM",
882
- "file"=> File.expand_path(@infile),
883
- "line"=>2},
884
- {"display"=>"State [EClass] - /StatemachineMM2",
885
- "file"=> File.expand_path(ModelFile2),
886
- "line"=>2},
887
- {"display"=>"StatemachineMM [EPackage] - /StatemachineMM",
888
- "file"=> File.expand_path(@infile),
889
- "line"=>1},
890
- {"display"=>"StatemachineMM2 [EPackage] - /StatemachineMM2",
891
- "file"=> File.expand_path(ModelFile2),
892
- "line"=>1}], response["elements"]
893
- response = @con.execute_command(
894
- {"command" => "find_elements", "search_pattern" => "target"})
895
- assert_equal \
896
- [{"display"=>"target [EReference] - /StatemachineMM/Transition",
897
- "file"=> File.expand_path(@infile),
898
- "line"=>17}], response["elements"]
899
- response = @con.execute_command(
900
- {"command" => "find_elements", "search_pattern" => ""})
901
- assert_equal [], response["elements"]
902
- response = @con.execute_command(
903
- {"command" => "find_elements", "search_pattern" => "xxx"})
904
- assert_equal [], response["elements"]
905
- end
906
-
907
- TestContext = Struct.new(:line, :col)
908
-
909
- def build_context(text, text2=nil)
910
- if text.is_a?(Hash)
911
- context_lines = text2.split("\n")
912
- pos_in_line = text[:col] || context_lines.last.index("|") + 1
913
- infile = text[:infile] || @infile
914
- else
915
- context_lines = text.split("\n")
916
- pos_in_line = context_lines.last.index("|") + 1
917
- infile = @infile
918
- end
919
- context_lines.last.sub!("|", "")
920
-
921
- # check that the context data actally matches the real file in the filesystem
922
- content = File.open(infile, "rb"){|f| f.read}
923
- ref_lines = content.split(/\r?\n/)[0..context_lines.size-1]
924
- raise "inconsistent test data, expected\n:#{ref_lines.join("\n")}\ngot:\n#{context_lines.join("\n")}\n" \
925
- unless ref_lines == context_lines
926
-
927
- # column numbers start at 1
928
- TestContext.new(context_lines.size, pos_in_line)
929
- end
930
-
931
- def assert_link_targets(context, options)
932
- infile = options[:file] || @infile
933
- content = File.open(infile, "rb") {|f| f.read}
934
- lines = content.split(/\r?\n/)[0..context.line-1]
935
- lines, col = RText::Frontend::Context.new.extract(lines, context.col)
936
- response = @con.execute_command(
937
- {"command" => "link_targets", "context" => lines, "column" => col})
938
- assert_equal "response", response["type"]
939
- assert_equal options[:targets], response["targets"]
940
- assert_equal options[:begin], response["begin_column"]
941
- assert_equal options[:end], response["end_column"]
942
- end
943
-
944
- def assert_completions(context, expected)
945
- content = File.open(@infile, "rb"){|f| f.read}
946
- lines = content.split(/\r?\n/)[0..context.line-1]
947
- lines, col = RText::Frontend::Context.new.extract(lines, context.col)
948
- response = @con.execute_command(
949
- {"command" => "content_complete", "context" => lines, "column" => col})
950
- assert_equal expected, response["options"].collect{|o| o["insert"]}
951
- end
952
-
953
- def load_model
954
- done = false
955
- response = nil
956
- while !done
957
- response = @con.execute_command({"command" => "load_model"})
958
- if response == :connecting && !@connection_timeout
959
- sleep(0.1)
960
- @con.resume
961
- else
962
- done = true
963
- end
964
- end
965
- response
966
- end
967
-
968
- end
1
+ # encoding: binary
2
+ $:.unshift(File.dirname(__FILE__)+"/../../lib")
3
+
4
+ require 'minitest/autorun'
5
+ require 'rtext/frontend/connector_manager'
6
+ require 'rtext/frontend/context'
7
+ require 'logger'
8
+
9
+ class IntegrationTest < MiniTest::Test
10
+
11
+ ModelFile = File.dirname(__FILE__)+"/model/test_metamodel.ect"
12
+ ModelFile2 = File.dirname(__FILE__)+"/model/test_metamodel2.ect"
13
+ ModelFile3 = File.dirname(__FILE__)+"/model/test_metamodel3.ect4"
14
+ LargeWithErrorsFile = File.dirname(__FILE__)+"/model/test_large_with_errors.ect3"
15
+ InvalidEncodingFile = File.dirname(__FILE__)+"/model/invalid_encoding.invenc"
16
+ NotInRTextFile = File.dirname(__FILE__)+"/model/test.not_in_rtext"
17
+ InvalidCmdLineFile = File.dirname(__FILE__)+"/model/test.invalid_cmd_line"
18
+ CrashingBackendFile = File.dirname(__FILE__)+"/model/test.crashing_backend"
19
+ DontOpenSocketFile = File.dirname(__FILE__)+"/model/test.dont_open_socket"
20
+ CrashOnRequestFile = File.dirname(__FILE__)+"/model/test.crash_on_request"
21
+
22
+ def setup_connector(file)
23
+ @infile = file
24
+ outfile = File.dirname(__FILE__)+"/backend.out"
25
+ logfile = File.dirname(__FILE__)+"/frontend.log"
26
+ logger = Logger.new(logfile)
27
+ File.unlink(outfile) if File.exist?(outfile)
28
+ @connection_timeout = false
29
+ man = RText::Frontend::ConnectorManager.new(
30
+ :logger => logger,
31
+ :keep_outfile => true,
32
+ :connection_timeout => 2,
33
+ :outfile_provider => lambda { File.expand_path(outfile) },
34
+ :connect_callback => lambda do |connector, state|
35
+ @connection_timeout = true if state == :timeout
36
+ end)
37
+ @con = man.connector_for_file(@infile)
38
+ end
39
+
40
+ def teardown
41
+ @con.stop if @con
42
+ end
43
+
44
+ def test_non_existing_file
45
+ setup_connector("this is not a file")
46
+ assert_nil @con
47
+ end
48
+
49
+ def test_not_in_rtext_file
50
+ setup_connector(NotInRTextFile)
51
+ assert_nil @con
52
+ end
53
+
54
+ def test_invalid_command_line
55
+ setup_connector(InvalidCmdLineFile)
56
+ assert @con
57
+ response = load_model
58
+ assert @connection_timeout
59
+ end
60
+
61
+ def test_crashing_backend
62
+ setup_connector(CrashingBackendFile)
63
+ assert @con
64
+ response = load_model
65
+ assert @connection_timeout
66
+ end
67
+
68
+ def test_backend_doesnt_open_socket
69
+ setup_connector(DontOpenSocketFile)
70
+ assert @con
71
+ response = load_model
72
+ assert @connection_timeout
73
+ end
74
+
75
+ def test_backend_crash_on_request
76
+ setup_connector(CrashOnRequestFile)
77
+ assert @con
78
+ response = load_model
79
+ assert_equal [], response["problems"]
80
+ response = @con.execute_command({"command" => "link_targets", "context" => [], "column" => 1})
81
+ assert_equal :timeout, response
82
+ end
83
+
84
+ # simulate external encoding utf-8 (-E in .rext) containing a iso-8859-1 character
85
+ def test_invalid_encoding
86
+ setup_connector(InvalidEncodingFile)
87
+ response = load_model
88
+ assert_equal "response", response["type"]
89
+ assert_equal [], response["problems"]
90
+ text = %Q(EPackage "iso-8859-1 umlaut: \xe4",| nsPrefix: "")
91
+ context = build_context(text)
92
+ assert_completions context, [
93
+ "nsPrefix:",
94
+ "nsURI:"
95
+ ]
96
+ end
97
+
98
+ def test_loadmodel
99
+ setup_connector(ModelFile)
100
+ response = load_model
101
+ assert_equal "response", response["type"]
102
+ assert_equal [], response["problems"]
103
+ end
104
+
105
+ def test_loadmodel_large_with_errors
106
+ setup_connector(LargeWithErrorsFile)
107
+ response = load_model
108
+ assert_equal "response", response["type"]
109
+ assert_equal 43523, response["problems"].first["problems"].size
110
+ end
111
+
112
+ def test_unknown_command
113
+ setup_connector(ModelFile)
114
+ response = load_model
115
+ response = @con.execute_command({"command" => "unknown"})
116
+ assert_equal "unknown_command_error", response["type"]
117
+ end
118
+
119
+ #TODO: connector restart when .rtext file changes
120
+
121
+ def test_complete_first_line
122
+ setup_connector(ModelFile)
123
+ load_model
124
+ context = build_context <<-END
125
+ |EPackage StatemachineMM {
126
+ END
127
+ assert_completions context, [
128
+ "EPackage"
129
+ ]
130
+ context = build_context <<-END
131
+ EPackage| StatemachineMM {
132
+ END
133
+ assert_completions context, [
134
+ "EPackage"
135
+ ]
136
+ context = build_context <<-END
137
+ EPackage |StatemachineMM {
138
+ END
139
+ assert_completions context, [
140
+ "name",
141
+ "nsPrefix:",
142
+ "nsURI:"
143
+ ]
144
+ context = build_context <<-END
145
+ EPackage S|tatemachineMM {
146
+ END
147
+ assert_completions context, [
148
+ "name",
149
+ "nsPrefix:",
150
+ "nsURI:"
151
+ ]
152
+ context = build_context <<-END
153
+ EPackage StatemachineMM| {
154
+ END
155
+ assert_completions context, [
156
+ "name",
157
+ "nsPrefix:",
158
+ "nsURI:"
159
+ ]
160
+ context = build_context <<-END
161
+ EPackage StatemachineMM |{
162
+ END
163
+ assert_completions context, [
164
+ ]
165
+ context = build_context <<-END
166
+ EPackage StatemachineMM {|
167
+ END
168
+ # these columns don't exist
169
+ assert_completions context, []
170
+ context = build_context({:col => 27}, "EPackage StatemachineMM {")
171
+ assert_completions context, []
172
+ context = build_context({:col => 28}, "EPackage StatemachineMM {")
173
+ assert_completions context, []
174
+ context = build_context({:col => 100}, "EPackage StatemachineMM {")
175
+ assert_completions context, []
176
+ # before first column is like first column
177
+ context = build_context({:col => 0}, "EPackage StatemachineMM {")
178
+ assert_completions context, [
179
+ "EPackage"
180
+ ]
181
+ context = build_context({:col => -1}, "EPackage StatemachineMM {")
182
+ assert_completions context, [
183
+ "EPackage"
184
+ ]
185
+ context = build_context({:col => -100}, "EPackage StatemachineMM {")
186
+ assert_completions context, [
187
+ "EPackage"
188
+ ]
189
+ end
190
+
191
+ def test_nested_command
192
+ setup_connector(ModelFile)
193
+ load_model
194
+ context = build_context <<-END
195
+ EPackage StatemachineMM {
196
+ | EClass State, abstract: true {
197
+ END
198
+ assert_completions context, [
199
+ "EAnnotation",
200
+ "EClass",
201
+ "EClassifier",
202
+ "EDataType",
203
+ "EEnum",
204
+ "EGenericType",
205
+ "EPackage"
206
+ ]
207
+ context = build_context <<-END
208
+ EPackage StatemachineMM {
209
+ |EClass State, abstract: true {
210
+ END
211
+ assert_completions context, [
212
+ "EAnnotation",
213
+ "EClass",
214
+ "EClassifier",
215
+ "EDataType",
216
+ "EEnum",
217
+ "EGenericType",
218
+ "EPackage"
219
+ ]
220
+ context = build_context <<-END
221
+ EPackage StatemachineMM {
222
+ EC|lass State, abstract: true {
223
+ END
224
+ assert_completions context, [
225
+ "EAnnotation",
226
+ "EClass",
227
+ "EClassifier",
228
+ "EDataType",
229
+ "EEnum",
230
+ "EGenericType",
231
+ "EPackage"
232
+ ]
233
+ context = build_context <<-END
234
+ EPackage StatemachineMM {
235
+ EClass| State, abstract: true {
236
+ END
237
+ assert_completions context, [
238
+ "EAnnotation",
239
+ "EClass",
240
+ "EClassifier",
241
+ "EDataType",
242
+ "EEnum",
243
+ "EGenericType",
244
+ "EPackage"
245
+ ]
246
+ context = build_context <<-END
247
+ EPackage StatemachineMM {
248
+ EClass |State, abstract: true {
249
+ END
250
+ assert_completions context, [
251
+ "name",
252
+ "abstract:",
253
+ "interface:",
254
+ "eSuperTypes:",
255
+ "instanceClassName:"
256
+ ]
257
+ context = build_context <<-END
258
+ EPackage StatemachineMM {
259
+ EClass S|tate, abstract: true {
260
+ END
261
+ assert_completions context, [
262
+ "name",
263
+ "abstract:",
264
+ "interface:",
265
+ "eSuperTypes:",
266
+ "instanceClassName:"
267
+ ]
268
+ context = build_context <<-END
269
+ EPackage StatemachineMM {
270
+ EClass State|, abstract: true {
271
+ END
272
+ assert_completions context, [
273
+ "name",
274
+ "abstract:",
275
+ "interface:",
276
+ "eSuperTypes:",
277
+ "instanceClassName:"
278
+ ]
279
+ context = build_context <<-END
280
+ EPackage StatemachineMM {
281
+ EClass State,| abstract: true {
282
+ END
283
+ assert_completions context, [
284
+ "abstract:",
285
+ "interface:",
286
+ "eSuperTypes:",
287
+ "instanceClassName:"
288
+ ]
289
+ context = build_context <<-END
290
+ EPackage StatemachineMM {
291
+ EClass State, |abstract: true {
292
+ END
293
+ assert_completions context, [
294
+ "abstract:",
295
+ "interface:",
296
+ "eSuperTypes:",
297
+ "instanceClassName:"
298
+ ]
299
+ context = build_context <<-END
300
+ EPackage StatemachineMM {
301
+ EClass State, a|bstract: true {
302
+ END
303
+ assert_completions context, [
304
+ "abstract:",
305
+ "interface:",
306
+ "eSuperTypes:",
307
+ "instanceClassName:"
308
+ ]
309
+ context = build_context <<-END
310
+ EPackage StatemachineMM {
311
+ EClass State, abstract:| true {
312
+ END
313
+ assert_completions context, [
314
+ "true",
315
+ "false"
316
+ ]
317
+ context = build_context <<-END
318
+ EPackage StatemachineMM {
319
+ EClass State, abstract: |true {
320
+ END
321
+ assert_completions context, [
322
+ "true",
323
+ "false"
324
+ ]
325
+ context = build_context <<-END
326
+ EPackage StatemachineMM {
327
+ EClass State, abstract: t|rue {
328
+ END
329
+ assert_completions context, [
330
+ "true",
331
+ "false"
332
+ ]
333
+ context = build_context <<-END
334
+ EPackage StatemachineMM {
335
+ EClass State, abstract: true| {
336
+ END
337
+ assert_completions context, [
338
+ "true",
339
+ "false"
340
+ ]
341
+ context = build_context <<-END
342
+ EPackage StatemachineMM {
343
+ EClass State, abstract: true |{
344
+ END
345
+ assert_completions context, [
346
+ ]
347
+ context = build_context <<-END
348
+ EPackage StatemachineMM {
349
+ EClass State, abstract: true {|
350
+ END
351
+ assert_completions context, [
352
+ ]
353
+ end
354
+
355
+ def test_complete_feature_after_linebreak
356
+ setup_connector(ModelFile)
357
+ load_model
358
+ context = build_context <<-END
359
+ EPackage StatemachineMM {
360
+ EClass State, abstract: true {
361
+ EAttribute name, eType: /StatemachineMM/StringType
362
+ EReference parent,
363
+ |eType: /StatemachineMM/CompositeState,
364
+ END
365
+ assert_completions context, [
366
+ "containment:",
367
+ "resolveProxies:",
368
+ "eOpposite:",
369
+ "changeable:",
370
+ "defaultValueLiteral:",
371
+ "derived:",
372
+ "transient:",
373
+ "unsettable:",
374
+ "volatile:",
375
+ "lowerBound:",
376
+ "ordered:",
377
+ "unique:",
378
+ "upperBound:",
379
+ "eType:"
380
+ ]
381
+ end
382
+
383
+ def test_complete_reference_after_linebreak
384
+ setup_connector(ModelFile)
385
+ load_model
386
+ context = build_context <<-END
387
+ EPackage StatemachineMM {
388
+ EClass State, abstract: true {
389
+ EAttribute name, eType: /StatemachineMM/StringType
390
+ EReference parent,
391
+ eType: |/StatemachineMM/CompositeState,
392
+ END
393
+ assert_completions context, [
394
+ "/StatemachineMM/CompositeState",
395
+ "/StatemachineMM/SimpleState",
396
+ "/StatemachineMM/State",
397
+ "/StatemachineMM/StringType",
398
+ "/StatemachineMM/Transition",
399
+ "/StatemachineMM2/SimpleState",
400
+ "/StatemachineMM2/State"
401
+ ]
402
+ end
403
+
404
+ def test_complete_command_after_linebreak
405
+ setup_connector(ModelFile)
406
+ load_model
407
+ context = build_context <<-END
408
+ EPackage StatemachineMM {
409
+ EClass State, abstract: true {
410
+ EAttribute name, eType: /StatemachineMM/StringType
411
+ EReference parent,
412
+ eType: /StatemachineMM/CompositeState,
413
+ eOpposite: /StatemachineMM/CompositeState/substates
414
+ }
415
+ EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
416
+ EClass CompositeState,
417
+ eSuperTypes: [
418
+ /StatemachineMM/State
419
+ ],
420
+ abstract: false {
421
+ |EReference substates, upperBound: -1, containment: true, eType: /StatemachineMM/State, eOpposite: /StatemachineMM/State/parent
422
+ END
423
+ assert_completions context, [
424
+ "EAnnotation",
425
+ "EAttribute",
426
+ "EOperation",
427
+ "EReference",
428
+ "EStructuralFeature"
429
+ ]
430
+ end
431
+
432
+ def test_complete_value_after_linebreak
433
+ setup_connector(ModelFile)
434
+ load_model
435
+ context = build_context <<-END
436
+ EPackage StatemachineMM {
437
+ EClass State, abstract: true {
438
+ EAttribute name, eType: /StatemachineMM/StringType
439
+ EReference parent,
440
+ eType: /StatemachineMM/CompositeState,
441
+ eOpposite: /StatemachineMM/CompositeState/substates
442
+ }
443
+ EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
444
+ EClass CompositeState,
445
+ eSuperTypes: [
446
+ /StatemachineMM/State
447
+ ],
448
+ abstract: |false {
449
+ END
450
+ assert_completions context, [
451
+ "true",
452
+ "false"
453
+ ]
454
+ end
455
+
456
+ def test_complete_in_array_after_linebreak
457
+ setup_connector(ModelFile)
458
+ load_model
459
+ context = build_context <<-END
460
+ EPackage StatemachineMM {
461
+ EClass State, abstract: true {
462
+ EAttribute name, eType: /StatemachineMM/StringType
463
+ EReference parent,
464
+ eType: /StatemachineMM/CompositeState,
465
+ eOpposite: /StatemachineMM/CompositeState/substates
466
+ }
467
+ EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
468
+ EClass CompositeState,
469
+ eSuperTypes: [
470
+ |/StatemachineMM/State
471
+ END
472
+ assert_completions context, [
473
+ "/StatemachineMM/CompositeState",
474
+ "/StatemachineMM/SimpleState",
475
+ "/StatemachineMM/State",
476
+ "/StatemachineMM/Transition",
477
+ "/StatemachineMM2/SimpleState",
478
+ "/StatemachineMM2/State"
479
+ ]
480
+ end
481
+
482
+ def test_complete_in_array_after_linebreak2
483
+ setup_connector(ModelFile)
484
+ load_model
485
+ context = build_context <<-END
486
+ EPackage StatemachineMM {
487
+ EClass State, abstract: true {
488
+ EAttribute name, eType: /StatemachineMM/StringType
489
+ EReference parent,
490
+ eType: /StatemachineMM/CompositeState,
491
+ eOpposite: /StatemachineMM/CompositeState/substates
492
+ }
493
+ EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
494
+ EClass CompositeState,
495
+ eSuperTypes: [
496
+ /StatemachineMM/State
497
+ |],
498
+ END
499
+ assert_completions context, [
500
+ ]
501
+ end
502
+
503
+ def test_complete_after_backslash
504
+ setup_connector(ModelFile3)
505
+ load_model
506
+ context = build_context <<-END
507
+ EPackage StatemachineMM3 {
508
+ EClass State
509
+ EClass \\
510
+ |SimpleState,
511
+ END
512
+ assert_completions context, [
513
+ "name",
514
+ "abstract:",
515
+ "interface:",
516
+ "eSuperTypes:",
517
+ "instanceClassName:"
518
+ ]
519
+ end
520
+
521
+ def test_complete_after_backslash2
522
+ setup_connector(ModelFile3)
523
+ load_model
524
+ context = build_context <<-END
525
+ EPackage StatemachineMM3 {
526
+ EClass State
527
+ EClass \\
528
+ SimpleState,
529
+ |eSuperTypes: [/StatemachineMM3/State]
530
+ END
531
+ assert_completions context, [
532
+ "abstract:",
533
+ "interface:",
534
+ "eSuperTypes:",
535
+ "instanceClassName:"
536
+ ]
537
+ end
538
+
539
+ def test_link_target_after_backslash
540
+ setup_connector(ModelFile3)
541
+ load_model
542
+ context = build_context <<-END
543
+ EPackage StatemachineMM3 {
544
+ EClass State
545
+ EClass \\
546
+ SimpleState,
547
+ eSuperTypes: [/S|tatemachineMM3/State]
548
+ END
549
+ assert_link_targets context, :file => ModelFile3, :begin => 45, :end => 66, :targets => [
550
+ {"file"=> File.expand_path(ModelFile3),
551
+ "line"=>2,
552
+ "display"=>"/StatemachineMM3/State [EClass]"}
553
+ ]
554
+ end
555
+
556
+ def test_reference_completion
557
+ setup_connector(ModelFile)
558
+ load_model
559
+ context = build_context <<-END
560
+ EPackage StatemachineMM {
561
+ EClass State, abstract: true {
562
+ EAttribute name, eType: |/StatemachineMM/StringType
563
+ END
564
+ assert_completions context, [
565
+ "/StatemachineMM/CompositeState",
566
+ "/StatemachineMM/SimpleState",
567
+ "/StatemachineMM/State",
568
+ "/StatemachineMM/StringType",
569
+ "/StatemachineMM/Transition",
570
+ "/StatemachineMM2/SimpleState",
571
+ "/StatemachineMM2/State",
572
+ ]
573
+ context = build_context <<-END
574
+ EPackage StatemachineMM {
575
+ EClass State, abstract: true {
576
+ EAttribute name, eType: /StatemachineMM/|StringType
577
+ END
578
+ assert_completions context, [
579
+ "/StatemachineMM/CompositeState",
580
+ "/StatemachineMM/SimpleState",
581
+ "/StatemachineMM/State",
582
+ "/StatemachineMM/StringType",
583
+ "/StatemachineMM/Transition",
584
+ "/StatemachineMM2/SimpleState",
585
+ "/StatemachineMM2/State",
586
+ ]
587
+ context = build_context <<-END
588
+ EPackage StatemachineMM {
589
+ EClass State, abstract: true {
590
+ EAttribute name, eType: /StatemachineMM/St|ringType
591
+ END
592
+ assert_completions context, [
593
+ "/StatemachineMM/CompositeState",
594
+ "/StatemachineMM/SimpleState",
595
+ "/StatemachineMM/State",
596
+ "/StatemachineMM/StringType",
597
+ "/StatemachineMM/Transition",
598
+ "/StatemachineMM2/SimpleState",
599
+ "/StatemachineMM2/State",
600
+ ]
601
+ context = build_context <<-END
602
+ EPackage StatemachineMM {
603
+ EClass State, abstract: true {
604
+ EAttribute name, eType: /StatemachineMM/StringType|
605
+ END
606
+ assert_completions context, [
607
+ "/StatemachineMM/CompositeState",
608
+ "/StatemachineMM/SimpleState",
609
+ "/StatemachineMM/State",
610
+ "/StatemachineMM/StringType",
611
+ "/StatemachineMM/Transition",
612
+ "/StatemachineMM2/SimpleState",
613
+ "/StatemachineMM2/State",
614
+ ]
615
+ end
616
+
617
+ def test_reference_completion_in_array
618
+ setup_connector(ModelFile)
619
+ load_model
620
+ context = build_context <<-END
621
+ EPackage StatemachineMM {
622
+ EClass State, abstract: true {
623
+ EAttribute name, eType: /StatemachineMM/StringType
624
+ EReference parent,
625
+ eType: /StatemachineMM/CompositeState,
626
+ eOpposite: /StatemachineMM/CompositeState/substates
627
+ }
628
+ EClass SimpleState, eSuperTypes: [|/StatemachineMM/State]
629
+ END
630
+ assert_completions context, [
631
+ "/StatemachineMM/CompositeState",
632
+ "/StatemachineMM/SimpleState",
633
+ "/StatemachineMM/State",
634
+ "/StatemachineMM/Transition",
635
+ "/StatemachineMM2/SimpleState",
636
+ "/StatemachineMM2/State",
637
+ ]
638
+ context = build_context <<-END
639
+ EPackage StatemachineMM {
640
+ EClass State, abstract: true {
641
+ EAttribute name, eType: /StatemachineMM/StringType
642
+ EReference parent,
643
+ eType: /StatemachineMM/CompositeState,
644
+ eOpposite: /StatemachineMM/CompositeState/substates
645
+ }
646
+ EClass SimpleState, eSuperTypes: [/StatemachineMM/S|tate]
647
+ END
648
+ assert_completions context, [
649
+ "/StatemachineMM/CompositeState",
650
+ "/StatemachineMM/SimpleState",
651
+ "/StatemachineMM/State",
652
+ "/StatemachineMM/Transition",
653
+ "/StatemachineMM2/SimpleState",
654
+ "/StatemachineMM2/State",
655
+ ]
656
+ context = build_context <<-END
657
+ EPackage StatemachineMM {
658
+ EClass State, abstract: true {
659
+ EAttribute name, eType: /StatemachineMM/StringType
660
+ EReference parent,
661
+ eType: /StatemachineMM/CompositeState,
662
+ eOpposite: /StatemachineMM/CompositeState/substates
663
+ }
664
+ EClass SimpleState, eSuperTypes: [/StatemachineMM/State|]
665
+ END
666
+ assert_completions context, [
667
+ "/StatemachineMM/CompositeState",
668
+ "/StatemachineMM/SimpleState",
669
+ "/StatemachineMM/State",
670
+ "/StatemachineMM/Transition",
671
+ "/StatemachineMM2/SimpleState",
672
+ "/StatemachineMM2/State",
673
+ ]
674
+ context = build_context <<-END
675
+ EPackage StatemachineMM {
676
+ EClass State, abstract: true {
677
+ EAttribute name, eType: /StatemachineMM/StringType
678
+ EReference parent,
679
+ eType: /StatemachineMM/CompositeState,
680
+ eOpposite: /StatemachineMM/CompositeState/substates
681
+ }
682
+ EClass SimpleState, eSuperTypes: [/StatemachineMM/State]|
683
+ END
684
+ assert_completions context, [
685
+ ]
686
+ end
687
+
688
+ def test_integer_completion
689
+ setup_connector(ModelFile)
690
+ load_model
691
+ context = build_context <<-END
692
+ EPackage StatemachineMM {
693
+ EClass State, abstract: true {
694
+ EAttribute name, eType: /StatemachineMM/StringType
695
+ EReference parent,
696
+ eType: /StatemachineMM/CompositeState,
697
+ eOpposite: /StatemachineMM/CompositeState/substates
698
+ }
699
+ EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
700
+ EClass CompositeState,
701
+ eSuperTypes: [
702
+ /StatemachineMM/State
703
+ ],
704
+ abstract: false {
705
+ EReference substates, upperBound: |-1, containment: true, eType: /StatemachineMM/State, eOpposite: /StatemachineMM/State/parent
706
+ END
707
+ assert_completions context, [
708
+ "1",
709
+ ]
710
+ context = build_context <<-END
711
+ EPackage StatemachineMM {
712
+ EClass State, abstract: true {
713
+ EAttribute name, eType: /StatemachineMM/StringType
714
+ EReference parent,
715
+ eType: /StatemachineMM/CompositeState,
716
+ eOpposite: /StatemachineMM/CompositeState/substates
717
+ }
718
+ EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
719
+ EClass CompositeState,
720
+ eSuperTypes: [
721
+ /StatemachineMM/State
722
+ ],
723
+ abstract: false {
724
+ EReference substates, upperBound: -1|, containment: true, eType: /StatemachineMM/State, eOpposite: /StatemachineMM/State/parent
725
+ END
726
+ assert_completions context, [
727
+ "1",
728
+ ]
729
+ end
730
+
731
+ def test_link_targets
732
+ setup_connector(ModelFile)
733
+ load_model
734
+ context = build_context <<-END
735
+ EPackage StatemachineMM {
736
+ EClass State, abstract: true {
737
+ EAttribute name, eType: /St|atemachineMM/StringType
738
+ END
739
+ assert_link_targets context, :begin => 29, :end => 54, :targets => [
740
+ {"file"=> File.expand_path(@infile),
741
+ "line"=>20,
742
+ "display"=>"/StatemachineMM/StringType [EDataType]"}
743
+ ]
744
+ context = build_context <<-END
745
+ EPackage StatemachineMM {
746
+ EClass State, abstract: true {
747
+ EAttribute name, eType: |/StatemachineMM/StringType
748
+ END
749
+ assert_link_targets context, :begin => 29, :end => 54, :targets => [
750
+ {"file"=> File.expand_path(@infile),
751
+ "line"=>20,
752
+ "display"=>"/StatemachineMM/StringType [EDataType]"}
753
+ ]
754
+ context = build_context <<-END
755
+ EPackage StatemachineMM {
756
+ EClass State, abstract: true {
757
+ EAttribute name, eType: /StatemachineMM/StringTyp|e
758
+ END
759
+ assert_link_targets context, :begin => 29, :end => 54, :targets => [
760
+ {"file"=> File.expand_path(@infile),
761
+ "line"=>20,
762
+ "display"=>"/StatemachineMM/StringType [EDataType]"}
763
+ ]
764
+ context = build_context <<-END
765
+ EPackage StatemachineMM {
766
+ EClass State, abstract: true {
767
+ EAttribute name, eType: /StatemachineMM/StringType|
768
+ END
769
+ assert_link_targets context, :begin => nil, :end => nil, :targets => []
770
+ context = build_context <<-END
771
+ EPackage StatemachineMM {
772
+ EClass State, abstract: true {
773
+ EAttribute name, eType:| /StatemachineMM/StringType
774
+ END
775
+ assert_link_targets context, :begin => nil, :end => nil, :targets => []
776
+ # backward ref
777
+ context = build_context <<-END
778
+ EPackage StatemachineMM {
779
+ E|Class State, abstract: true {
780
+ END
781
+ assert_link_targets context, :begin => 3, :end => 8, :targets => [
782
+ {"file"=> File.expand_path(@infile),
783
+ "line"=>8,
784
+ "display"=>"/StatemachineMM/SimpleState [EClass]"},
785
+ {"file"=> File.expand_path(@infile),
786
+ "line"=>9,
787
+ "display"=>"/StatemachineMM/CompositeState [EClass]"}
788
+ ]
789
+ context = build_context <<-END
790
+ EPackage StatemachineMM {
791
+ EClass State, abstract: true {
792
+ EAttribute name, eType: /StatemachineMM/StringType
793
+ EReference parent,
794
+ eType: /StatemachineMM/CompositeState,
795
+ eOpposite: /StatemachineMM/CompositeState/substates
796
+ }
797
+ |EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
798
+ END
799
+ assert_link_targets context, :begin => 3, :end => 8, :targets => []
800
+ # bad location
801
+ context = build_context <<-END
802
+ EPackage S|tatemachineMM {
803
+ END
804
+ assert_link_targets context, :begin => 10, :end => 23, :targets => []
805
+ end
806
+
807
+ def test_link_targets_no_text_after_name
808
+ setup_connector(ModelFile)
809
+ load_model
810
+ context = build_context({:infile => ModelFile2}, <<-END
811
+ EPackage StatemachineMM2 {
812
+ ECl|ass State
813
+ END
814
+ )
815
+ assert_link_targets context, :file => ModelFile2, :begin => 3, :end => 8, :targets => [
816
+ {"file"=> File.expand_path(ModelFile2),
817
+ "line"=>3,
818
+ "display"=>"/StatemachineMM2/SimpleState [EClass]"}
819
+ ]
820
+ end
821
+
822
+ def test_link_targets_after_linebreak
823
+ setup_connector(ModelFile)
824
+ load_model
825
+ context = build_context <<-END
826
+ EPackage StatemachineMM {
827
+ EClass State, abstract: true {
828
+ EAttribute name, eType: /StatemachineMM/StringType
829
+ EReference parent,
830
+ eType: /St|atemachineMM/CompositeState,
831
+ END
832
+ # in case of linebreaks, the begin and end column refer to the string which
833
+ # was passed to the backend as the context; in this case the context extractor
834
+ # appends each broken line to the previous line with all the leading whitespace removed
835
+ assert_link_targets context, :begin => 37, :end => 66, :targets => [
836
+ {"file"=> File.expand_path(@infile),
837
+ "line"=>9,
838
+ "display"=>"/StatemachineMM/CompositeState [EClass]"}
839
+ ]
840
+ context = build_context <<-END
841
+ EPackage StatemachineMM {
842
+ EClass State, abstract: true {
843
+ EAttribute name, eType: /StatemachineMM/StringType
844
+ EReference parent,
845
+ eType: |/StatemachineMM/CompositeState,
846
+ END
847
+ assert_link_targets context, :begin => 37, :end => 66, :targets => [
848
+ {"file"=> File.expand_path(@infile),
849
+ "line"=>9,
850
+ "display"=>"/StatemachineMM/CompositeState [EClass]"}
851
+ ]
852
+ context = build_context <<-END
853
+ EPackage StatemachineMM {
854
+ EClass State, abstract: true {
855
+ EAttribute name, eType: /StatemachineMM/StringType
856
+ EReference parent,
857
+ eType: /StatemachineMM/CompositeStat|e,
858
+ END
859
+ assert_link_targets context, :begin => 37, :end => 66, :targets => [
860
+ {"file"=> File.expand_path(@infile),
861
+ "line"=>9,
862
+ "display"=>"/StatemachineMM/CompositeState [EClass]"}
863
+ ]
864
+ context = build_context <<-END
865
+ EPackage StatemachineMM {
866
+ EClass State, abstract: true {
867
+ EAttribute name, eType: /StatemachineMM/StringType
868
+ EReference parent,
869
+ eType: /StatemachineMM/CompositeState|,
870
+ END
871
+ assert_link_targets context, :begin => nil, :end => nil, :targets => []
872
+ end
873
+
874
+ def test_find_elements
875
+ setup_connector(ModelFile)
876
+ load_model
877
+ response = @con.execute_command(
878
+ {"command" => "find_elements", "search_pattern" => "Sta"})
879
+ assert_equal \
880
+ [{"display"=>"State [EClass] - /StatemachineMM",
881
+ "file"=> File.expand_path(@infile),
882
+ "line"=>2},
883
+ {"display"=>"State [EClass] - /StatemachineMM2",
884
+ "file"=> File.expand_path(ModelFile2),
885
+ "line"=>2},
886
+ {"display"=>"StatemachineMM [EPackage] - /StatemachineMM",
887
+ "file"=> File.expand_path(@infile),
888
+ "line"=>1},
889
+ {"display"=>"StatemachineMM2 [EPackage] - /StatemachineMM2",
890
+ "file"=> File.expand_path(ModelFile2),
891
+ "line"=>1}], response["elements"]
892
+ response = @con.execute_command(
893
+ {"command" => "find_elements", "search_pattern" => "target"})
894
+ assert_equal \
895
+ [{"display"=>"target [EReference] - /StatemachineMM/Transition",
896
+ "file"=> File.expand_path(@infile),
897
+ "line"=>17}], response["elements"]
898
+ response = @con.execute_command(
899
+ {"command" => "find_elements", "search_pattern" => ""})
900
+ assert_equal [], response["elements"]
901
+ response = @con.execute_command(
902
+ {"command" => "find_elements", "search_pattern" => "xxx"})
903
+ assert_equal [], response["elements"]
904
+ end
905
+
906
+ TestContext = Struct.new(:line, :col)
907
+
908
+ def build_context(text, text2=nil)
909
+ if text.is_a?(Hash)
910
+ context_lines = text2.split("\n")
911
+ pos_in_line = text[:col] || context_lines.last.index("|") + 1
912
+ infile = text[:infile] || @infile
913
+ else
914
+ context_lines = text.split("\n")
915
+ pos_in_line = context_lines.last.index("|") + 1
916
+ infile = @infile
917
+ end
918
+ context_lines.last.sub!("|", "")
919
+
920
+ # check that the context data actally matches the real file in the filesystem
921
+ content = File.open(infile, "rb"){|f| f.read}
922
+ ref_lines = content.split(/\r?\n/)[0..context_lines.size-1]
923
+ raise "inconsistent test data, expected\n:#{ref_lines.join("\n")}\ngot:\n#{context_lines.join("\n")}\n" \
924
+ unless ref_lines == context_lines
925
+
926
+ # column numbers start at 1
927
+ TestContext.new(context_lines.size, pos_in_line)
928
+ end
929
+
930
+ def assert_link_targets(context, options)
931
+ infile = options[:file] || @infile
932
+ content = File.open(infile, "rb") {|f| f.read}
933
+ lines = content.split(/\r?\n/)[0..context.line-1]
934
+ lines, col = RText::Frontend::Context.new.extract(lines, context.col)
935
+ response = @con.execute_command(
936
+ {"command" => "link_targets", "context" => lines, "column" => col})
937
+ assert_equal "response", response["type"]
938
+ assert_equal options[:targets], response["targets"]
939
+ assert_equal options[:begin], response["begin_column"]
940
+ assert_equal options[:end], response["end_column"]
941
+ end
942
+
943
+ def assert_completions(context, expected)
944
+ content = File.open(@infile, "rb"){|f| f.read}
945
+ lines = content.split(/\r?\n/)[0..context.line-1]
946
+ lines, col = RText::Frontend::Context.new.extract(lines, context.col)
947
+ response = @con.execute_command(
948
+ {"command" => "content_complete", "context" => lines, "column" => col})
949
+ assert_equal expected, response["options"].collect{|o| o["insert"]}
950
+ end
951
+
952
+ def load_model
953
+ done = false
954
+ response = nil
955
+ while !done
956
+ response = @con.execute_command({"command" => "load_model"})
957
+ if response == :connecting && !@connection_timeout
958
+ sleep(0.1)
959
+ @con.resume
960
+ else
961
+ done = true
962
+ end
963
+ end
964
+ response
965
+ end
966
+
967
+ end