rtext 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/CHANGELOG +20 -0
  2. data/{README → README.rdoc} +5 -1
  3. data/RText_Protocol +444 -0
  4. data/Rakefile +10 -10
  5. data/lib/rtext/completer.rb +32 -26
  6. data/lib/rtext/context_builder.rb +113 -59
  7. data/lib/rtext/default_loader.rb +73 -8
  8. data/lib/rtext/default_service_provider.rb +30 -14
  9. data/lib/rtext/frontend/config.rb +58 -0
  10. data/lib/rtext/frontend/connector.rb +233 -0
  11. data/lib/rtext/frontend/connector_manager.rb +81 -0
  12. data/lib/rtext/frontend/context.rb +56 -0
  13. data/lib/rtext/generic.rb +13 -0
  14. data/lib/rtext/instantiator.rb +30 -7
  15. data/lib/rtext/language.rb +54 -27
  16. data/lib/rtext/link_detector.rb +57 -0
  17. data/lib/rtext/message_helper.rb +77 -0
  18. data/lib/rtext/parser.rb +19 -68
  19. data/lib/rtext/serializer.rb +18 -3
  20. data/lib/rtext/service.rb +182 -118
  21. data/lib/rtext/tokenizer.rb +102 -0
  22. data/test/completer_test.rb +327 -70
  23. data/test/context_builder_test.rb +671 -91
  24. data/test/instantiator_test.rb +153 -0
  25. data/test/integration/backend.out +10 -0
  26. data/test/integration/crash_on_request_editor.rb +12 -0
  27. data/test/integration/ecore_editor.rb +50 -0
  28. data/test/integration/frontend.log +25138 -0
  29. data/test/integration/model/invalid_encoding.invenc +2 -0
  30. data/test/integration/model/test.crash_on_request +18 -0
  31. data/test/integration/model/test.crashing_backend +18 -0
  32. data/test/integration/model/test.dont_open_socket +0 -0
  33. data/test/integration/model/test.invalid_cmd_line +0 -0
  34. data/test/integration/model/test.not_in_rtext +0 -0
  35. data/test/integration/model/test_large_with_errors.ect3 +43523 -0
  36. data/test/integration/model/test_metamodel.ect +18 -0
  37. data/test/integration/model/test_metamodel2.ect +5 -0
  38. data/test/integration/model/test_metamodel_error.ect2 +3 -0
  39. data/test/integration/model/test_metamodel_ok.ect2 +18 -0
  40. data/test/integration/test.rb +684 -0
  41. data/test/link_detector_test.rb +276 -0
  42. data/test/message_helper_test.rb +118 -0
  43. data/test/rtext_test.rb +4 -1
  44. data/test/serializer_test.rb +96 -1
  45. data/test/tokenizer_test.rb +125 -0
  46. metadata +36 -10
  47. data/RText_Plugin_Implementation_Guide +0 -268
  48. data/lib/rtext_plugin/connection_manager.rb +0 -59
@@ -0,0 +1,18 @@
1
+ EPackage StatemachineMM {
2
+ EClass State, abstract: true {
3
+ EAttribute name, eType: /StatemachineMM/StringType
4
+ EReference parent, eType: /StatemachineMM/CompositeState, eOpposite: /StatemachineMM/CompositeState/substates
5
+ }
6
+ EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
7
+ EClass CompositeState, eSuperTypes: [/StatemachineMM/State] {
8
+ EReference substates, upperBound: -1, containment: true, eType: /StatemachineMM/State, eOpposite: /StatemachineMM/State/parent
9
+ }
10
+ EClass Transition {
11
+ EReference target, upperBound: 1, eType: /StatemachineMM/State
12
+ EReference source, upperBound: 1, eType: /StatemachineMM/State
13
+ }
14
+ EDataType StringType
15
+ EAnnotation source: "test" {
16
+ EStringToStringMapEntry key: "kind", value: "package"
17
+ }
18
+ }
@@ -0,0 +1,5 @@
1
+ EPackage StatemachineMM2 {
2
+ EClass State
3
+ EClass SimpleState, eSuperTypes: [/StatemachineMM2/State]
4
+ }
5
+
@@ -0,0 +1,3 @@
1
+ EPackage StatemachineMM {
2
+ problem
3
+ }
@@ -0,0 +1,18 @@
1
+ EPackage StatemachineMM {
2
+ EClass State, abstract: true {
3
+ EAttribute name, eType: /StatemachineMM/StringType
4
+ EReference parent, eType: /StatemachineMM/CompositeState, eOpposite: /StatemachineMM/CompositeState/substates
5
+ }
6
+ EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
7
+ EClass CompositeState, eSuperTypes: [/StatemachineMM/State] {
8
+ EReference substates, upperBound: -1, containment: true, eType: /StatemachineMM/State, eOpposite: /StatemachineMM/State/parent
9
+ }
10
+ EClass Transition {
11
+ EReference target, upperBound: 1, eType: /StatemachineMM/State
12
+ EReference source, upperBound: 1, eType: /StatemachineMM/State
13
+ }
14
+ EDataType StringType
15
+ EAnnotation source: "test" {
16
+ EStringToStringMapEntry key: "kind", value: "package"
17
+ }
18
+ }
@@ -0,0 +1,684 @@
1
+ # encoding: binary
2
+ $:.unshift(File.dirname(__FILE__)+"/../../lib")
3
+ require 'test/unit'
4
+ require 'rtext/frontend/connector_manager'
5
+ require 'rtext/frontend/context'
6
+ require 'logger'
7
+
8
+ class IntegrationTest < Test::Unit::TestCase
9
+
10
+ ModelFile = File.dirname(__FILE__)+"/model/test_metamodel.ect"
11
+ ModelFile2 = File.dirname(__FILE__)+"/model/test_metamodel2.ect"
12
+ LargeWithErrorsFile = File.dirname(__FILE__)+"/model/test_large_with_errors.ect3"
13
+ InvalidEncodingFile = File.dirname(__FILE__)+"/model/invalid_encoding.invenc"
14
+ NotInRTextFile = File.dirname(__FILE__)+"/model/test.not_in_rtext"
15
+ InvalidCmdLineFile = File.dirname(__FILE__)+"/model/test.invalid_cmd_line"
16
+ CrashingBackendFile = File.dirname(__FILE__)+"/model/test.crashing_backend"
17
+ DontOpenSocketFile = File.dirname(__FILE__)+"/model/test.dont_open_socket"
18
+ CrashOnRequestFile = File.dirname(__FILE__)+"/model/test.crash_on_request"
19
+
20
+ def setup_connector(file)
21
+ @infile = file
22
+ outfile = File.dirname(__FILE__)+"/backend.out"
23
+ logfile = File.dirname(__FILE__)+"/frontend.log"
24
+ logger = Logger.new(logfile)
25
+ File.unlink(outfile) if File.exist?(outfile)
26
+ @connection_timeout = false
27
+ man = RText::Frontend::ConnectorManager.new(
28
+ :logger => logger,
29
+ :keep_outfile => true,
30
+ :connection_timeout => 1,
31
+ :outfile_provider => lambda { File.expand_path(outfile) },
32
+ :connect_callback => lambda do |connector, state|
33
+ @connection_timeout = true if state == :timeout
34
+ end)
35
+ @con = man.connector_for_file(@infile)
36
+ end
37
+
38
+ def teardown
39
+ @con.stop if @con
40
+ end
41
+
42
+ def test_non_existing_file
43
+ setup_connector("this is not a file")
44
+ assert_nil @con
45
+ end
46
+
47
+ def test_not_in_rtext_file
48
+ setup_connector(NotInRTextFile)
49
+ assert_nil @con
50
+ end
51
+
52
+ def test_invalid_command_line
53
+ setup_connector(InvalidCmdLineFile)
54
+ assert @con
55
+ response = load_model
56
+ assert @connection_timeout
57
+ end
58
+
59
+ def test_crashing_backend
60
+ setup_connector(CrashingBackendFile)
61
+ assert @con
62
+ response = load_model
63
+ assert @connection_timeout
64
+ end
65
+
66
+ def test_backend_doesnt_open_socket
67
+ setup_connector(DontOpenSocketFile)
68
+ assert @con
69
+ response = load_model
70
+ assert @connection_timeout
71
+ end
72
+
73
+ def test_backend_crash_on_request
74
+ setup_connector(CrashOnRequestFile)
75
+ assert @con
76
+ response = load_model
77
+ assert_equal [], response["problems"]
78
+ response = @con.execute_command({"command" => "link_targets", "context" => [], "column" => 1})
79
+ assert_equal :timeout, response
80
+ end
81
+
82
+ # simulate external encoding utf-8 (-E in .rext) containing a iso-8859-1 character
83
+ def test_invalid_encoding
84
+ setup_connector(InvalidEncodingFile)
85
+ response = load_model
86
+ assert_equal "response", response["type"]
87
+ assert_equal [], response["problems"]
88
+ text = %Q(EPackage "iso-8859-1 umlaut: \xe4",| nsPrefix: "")
89
+ context = build_context(text)
90
+ assert_completions context, [
91
+ "nsPrefix:",
92
+ "nsURI:"
93
+ ]
94
+ end
95
+
96
+ def test_loadmodel
97
+ setup_connector(ModelFile)
98
+ response = load_model
99
+ assert_equal "response", response["type"]
100
+ assert_equal [], response["problems"]
101
+ end
102
+
103
+ def test_loadmodel_large_with_errors
104
+ setup_connector(LargeWithErrorsFile)
105
+ response = load_model
106
+ assert_equal "response", response["type"]
107
+ assert_equal 43523, response["problems"].first["problems"].size
108
+ end
109
+
110
+ def test_unknown_command
111
+ setup_connector(ModelFile)
112
+ response = load_model
113
+ response = @con.execute_command({"command" => "unknown"})
114
+ assert_equal "unknown_command_error", response["type"]
115
+ end
116
+
117
+ #TODO: connector restart when .rtext file changes
118
+
119
+ def test_complete_first_line
120
+ setup_connector(ModelFile)
121
+ load_model
122
+ context = build_context <<-END
123
+ |EPackage StatemachineMM {
124
+ END
125
+ assert_completions context, [
126
+ "EPackage"
127
+ ]
128
+ context = build_context <<-END
129
+ EPackage| StatemachineMM {
130
+ END
131
+ assert_completions context, [
132
+ "EPackage"
133
+ ]
134
+ context = build_context <<-END
135
+ EPackage |StatemachineMM {
136
+ END
137
+ assert_completions context, [
138
+ "name",
139
+ "nsPrefix:",
140
+ "nsURI:"
141
+ ]
142
+ context = build_context <<-END
143
+ EPackage S|tatemachineMM {
144
+ END
145
+ assert_completions context, [
146
+ "name",
147
+ "nsPrefix:",
148
+ "nsURI:"
149
+ ]
150
+ context = build_context <<-END
151
+ EPackage StatemachineMM| {
152
+ END
153
+ assert_completions context, [
154
+ "name",
155
+ "nsPrefix:",
156
+ "nsURI:"
157
+ ]
158
+ context = build_context <<-END
159
+ EPackage StatemachineMM |{
160
+ END
161
+ assert_completions context, [
162
+ ]
163
+ context = build_context <<-END
164
+ EPackage StatemachineMM {|
165
+ END
166
+ # these columns don't exist
167
+ assert_completions context, []
168
+ context = build_context({:col => 27}, "EPackage StatemachineMM {")
169
+ assert_completions context, []
170
+ context = build_context({:col => 28}, "EPackage StatemachineMM {")
171
+ assert_completions context, []
172
+ context = build_context({:col => 100}, "EPackage StatemachineMM {")
173
+ assert_completions context, []
174
+ # before first column is like first column
175
+ context = build_context({:col => 0}, "EPackage StatemachineMM {")
176
+ assert_completions context, [
177
+ "EPackage"
178
+ ]
179
+ context = build_context({:col => -1}, "EPackage StatemachineMM {")
180
+ assert_completions context, [
181
+ "EPackage"
182
+ ]
183
+ context = build_context({:col => -100}, "EPackage StatemachineMM {")
184
+ assert_completions context, [
185
+ "EPackage"
186
+ ]
187
+ end
188
+
189
+ def test_nested_command
190
+ setup_connector(ModelFile)
191
+ load_model
192
+ context = build_context <<-END
193
+ EPackage StatemachineMM {
194
+ | EClass State, abstract: true {
195
+ END
196
+ assert_completions context, [
197
+ "EAnnotation",
198
+ "EClass",
199
+ "EClassifier",
200
+ "EDataType",
201
+ "EEnum",
202
+ "EGenericType",
203
+ "EPackage"
204
+ ]
205
+ context = build_context <<-END
206
+ EPackage StatemachineMM {
207
+ |EClass State, abstract: true {
208
+ END
209
+ assert_completions context, [
210
+ "EAnnotation",
211
+ "EClass",
212
+ "EClassifier",
213
+ "EDataType",
214
+ "EEnum",
215
+ "EGenericType",
216
+ "EPackage"
217
+ ]
218
+ context = build_context <<-END
219
+ EPackage StatemachineMM {
220
+ EC|lass State, abstract: true {
221
+ END
222
+ assert_completions context, [
223
+ "EAnnotation",
224
+ "EClass",
225
+ "EClassifier",
226
+ "EDataType",
227
+ "EEnum",
228
+ "EGenericType",
229
+ "EPackage"
230
+ ]
231
+ context = build_context <<-END
232
+ EPackage StatemachineMM {
233
+ EClass| State, abstract: true {
234
+ END
235
+ assert_completions context, [
236
+ "EAnnotation",
237
+ "EClass",
238
+ "EClassifier",
239
+ "EDataType",
240
+ "EEnum",
241
+ "EGenericType",
242
+ "EPackage"
243
+ ]
244
+ context = build_context <<-END
245
+ EPackage StatemachineMM {
246
+ EClass |State, abstract: true {
247
+ END
248
+ assert_completions context, [
249
+ "name",
250
+ "abstract:",
251
+ "interface:",
252
+ "eSuperTypes:",
253
+ "instanceClassName:"
254
+ ]
255
+ context = build_context <<-END
256
+ EPackage StatemachineMM {
257
+ EClass S|tate, abstract: true {
258
+ END
259
+ assert_completions context, [
260
+ "name",
261
+ "abstract:",
262
+ "interface:",
263
+ "eSuperTypes:",
264
+ "instanceClassName:"
265
+ ]
266
+ context = build_context <<-END
267
+ EPackage StatemachineMM {
268
+ EClass State|, abstract: true {
269
+ END
270
+ assert_completions context, [
271
+ "name",
272
+ "abstract:",
273
+ "interface:",
274
+ "eSuperTypes:",
275
+ "instanceClassName:"
276
+ ]
277
+ context = build_context <<-END
278
+ EPackage StatemachineMM {
279
+ EClass State,| abstract: true {
280
+ END
281
+ assert_completions context, [
282
+ "abstract:",
283
+ "interface:",
284
+ "eSuperTypes:",
285
+ "instanceClassName:"
286
+ ]
287
+ context = build_context <<-END
288
+ EPackage StatemachineMM {
289
+ EClass State, |abstract: true {
290
+ END
291
+ assert_completions context, [
292
+ "abstract:",
293
+ "interface:",
294
+ "eSuperTypes:",
295
+ "instanceClassName:"
296
+ ]
297
+ context = build_context <<-END
298
+ EPackage StatemachineMM {
299
+ EClass State, a|bstract: true {
300
+ END
301
+ assert_completions context, [
302
+ "abstract:",
303
+ "interface:",
304
+ "eSuperTypes:",
305
+ "instanceClassName:"
306
+ ]
307
+ context = build_context <<-END
308
+ EPackage StatemachineMM {
309
+ EClass State, abstract:| true {
310
+ END
311
+ assert_completions context, [
312
+ "true",
313
+ "false"
314
+ ]
315
+ context = build_context <<-END
316
+ EPackage StatemachineMM {
317
+ EClass State, abstract: |true {
318
+ END
319
+ assert_completions context, [
320
+ "true",
321
+ "false"
322
+ ]
323
+ context = build_context <<-END
324
+ EPackage StatemachineMM {
325
+ EClass State, abstract: t|rue {
326
+ END
327
+ assert_completions context, [
328
+ "true",
329
+ "false"
330
+ ]
331
+ context = build_context <<-END
332
+ EPackage StatemachineMM {
333
+ EClass State, abstract: true| {
334
+ END
335
+ assert_completions context, [
336
+ "true",
337
+ "false"
338
+ ]
339
+ context = build_context <<-END
340
+ EPackage StatemachineMM {
341
+ EClass State, abstract: true |{
342
+ END
343
+ assert_completions context, [
344
+ ]
345
+ context = build_context <<-END
346
+ EPackage StatemachineMM {
347
+ EClass State, abstract: true {|
348
+ END
349
+ assert_completions context, [
350
+ ]
351
+ end
352
+
353
+ def test_reference_completion
354
+ setup_connector(ModelFile)
355
+ load_model
356
+ context = build_context <<-END
357
+ EPackage StatemachineMM {
358
+ EClass State, abstract: true {
359
+ EAttribute name, eType: |/StatemachineMM/StringType
360
+ END
361
+ assert_completions context, [
362
+ "/StatemachineMM/CompositeState",
363
+ "/StatemachineMM/SimpleState",
364
+ "/StatemachineMM/State",
365
+ "/StatemachineMM/StringType",
366
+ "/StatemachineMM/Transition",
367
+ "/StatemachineMM2/SimpleState",
368
+ "/StatemachineMM2/State",
369
+ ]
370
+ context = build_context <<-END
371
+ EPackage StatemachineMM {
372
+ EClass State, abstract: true {
373
+ EAttribute name, eType: /StatemachineMM/|StringType
374
+ END
375
+ assert_completions context, [
376
+ "/StatemachineMM/CompositeState",
377
+ "/StatemachineMM/SimpleState",
378
+ "/StatemachineMM/State",
379
+ "/StatemachineMM/StringType",
380
+ "/StatemachineMM/Transition",
381
+ "/StatemachineMM2/SimpleState",
382
+ "/StatemachineMM2/State",
383
+ ]
384
+ context = build_context <<-END
385
+ EPackage StatemachineMM {
386
+ EClass State, abstract: true {
387
+ EAttribute name, eType: /StatemachineMM/St|ringType
388
+ END
389
+ assert_completions context, [
390
+ "/StatemachineMM/CompositeState",
391
+ "/StatemachineMM/SimpleState",
392
+ "/StatemachineMM/State",
393
+ "/StatemachineMM/StringType",
394
+ "/StatemachineMM/Transition",
395
+ "/StatemachineMM2/SimpleState",
396
+ "/StatemachineMM2/State",
397
+ ]
398
+ context = build_context <<-END
399
+ EPackage StatemachineMM {
400
+ EClass State, abstract: true {
401
+ EAttribute name, eType: /StatemachineMM/StringType|
402
+ END
403
+ assert_completions context, [
404
+ "/StatemachineMM/CompositeState",
405
+ "/StatemachineMM/SimpleState",
406
+ "/StatemachineMM/State",
407
+ "/StatemachineMM/StringType",
408
+ "/StatemachineMM/Transition",
409
+ "/StatemachineMM2/SimpleState",
410
+ "/StatemachineMM2/State",
411
+ ]
412
+ end
413
+
414
+ def test_reference_completion_in_array
415
+ setup_connector(ModelFile)
416
+ load_model
417
+ context = build_context <<-END
418
+ EPackage StatemachineMM {
419
+ EClass State, abstract: true {
420
+ EAttribute name, eType: /StatemachineMM/StringType
421
+ EReference parent, eType: /StatemachineMM/CompositeState, eOpposite: /StatemachineMM/CompositeState/substates
422
+ }
423
+ EClass SimpleState, eSuperTypes: [|/StatemachineMM/State]
424
+ END
425
+ assert_completions context, [
426
+ "/StatemachineMM/CompositeState",
427
+ "/StatemachineMM/SimpleState",
428
+ "/StatemachineMM/State",
429
+ "/StatemachineMM/Transition",
430
+ "/StatemachineMM2/SimpleState",
431
+ "/StatemachineMM2/State",
432
+ ]
433
+ context = build_context <<-END
434
+ EPackage StatemachineMM {
435
+ EClass State, abstract: true {
436
+ EAttribute name, eType: /StatemachineMM/StringType
437
+ EReference parent, eType: /StatemachineMM/CompositeState, eOpposite: /StatemachineMM/CompositeState/substates
438
+ }
439
+ EClass SimpleState, eSuperTypes: [/StatemachineMM/S|tate]
440
+ END
441
+ assert_completions context, [
442
+ "/StatemachineMM/CompositeState",
443
+ "/StatemachineMM/SimpleState",
444
+ "/StatemachineMM/State",
445
+ "/StatemachineMM/Transition",
446
+ "/StatemachineMM2/SimpleState",
447
+ "/StatemachineMM2/State",
448
+ ]
449
+ context = build_context <<-END
450
+ EPackage StatemachineMM {
451
+ EClass State, abstract: true {
452
+ EAttribute name, eType: /StatemachineMM/StringType
453
+ EReference parent, eType: /StatemachineMM/CompositeState, eOpposite: /StatemachineMM/CompositeState/substates
454
+ }
455
+ EClass SimpleState, eSuperTypes: [/StatemachineMM/State|]
456
+ END
457
+ assert_completions context, [
458
+ "/StatemachineMM/CompositeState",
459
+ "/StatemachineMM/SimpleState",
460
+ "/StatemachineMM/State",
461
+ "/StatemachineMM/Transition",
462
+ "/StatemachineMM2/SimpleState",
463
+ "/StatemachineMM2/State",
464
+ ]
465
+ context = build_context <<-END
466
+ EPackage StatemachineMM {
467
+ EClass State, abstract: true {
468
+ EAttribute name, eType: /StatemachineMM/StringType
469
+ EReference parent, eType: /StatemachineMM/CompositeState, eOpposite: /StatemachineMM/CompositeState/substates
470
+ }
471
+ EClass SimpleState, eSuperTypes: [/StatemachineMM/State]|
472
+ END
473
+ assert_completions context, [
474
+ ]
475
+ end
476
+
477
+ def test_integer_completion
478
+ setup_connector(ModelFile)
479
+ load_model
480
+ context = build_context <<-END
481
+ EPackage StatemachineMM {
482
+ EClass State, abstract: true {
483
+ EAttribute name, eType: /StatemachineMM/StringType
484
+ EReference parent, eType: /StatemachineMM/CompositeState, eOpposite: /StatemachineMM/CompositeState/substates
485
+ }
486
+ EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
487
+ EClass CompositeState, eSuperTypes: [/StatemachineMM/State] {
488
+ EReference substates, upperBound: |-1, containment: true, eType: /StatemachineMM/State, eOpposite: /StatemachineMM/State/parent
489
+ END
490
+ assert_completions context, [
491
+ "0",
492
+ ]
493
+ context = build_context <<-END
494
+ EPackage StatemachineMM {
495
+ EClass State, abstract: true {
496
+ EAttribute name, eType: /StatemachineMM/StringType
497
+ EReference parent, eType: /StatemachineMM/CompositeState, eOpposite: /StatemachineMM/CompositeState/substates
498
+ }
499
+ EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
500
+ EClass CompositeState, eSuperTypes: [/StatemachineMM/State] {
501
+ EReference substates, upperBound: -1|, containment: true, eType: /StatemachineMM/State, eOpposite: /StatemachineMM/State/parent
502
+ END
503
+ assert_completions context, [
504
+ "0",
505
+ ]
506
+ end
507
+
508
+ def test_link_targets
509
+ setup_connector(ModelFile)
510
+ load_model
511
+ context = build_context <<-END
512
+ EPackage StatemachineMM {
513
+ EClass State, abstract: true {
514
+ EAttribute name, eType: /St|atemachineMM/StringType
515
+ END
516
+ assert_link_targets context, :begin => 29, :end => 54, :targets => [
517
+ {"file"=> File.expand_path(@infile),
518
+ "line"=>14,
519
+ "display"=>"/StatemachineMM/StringType [EDataType]"}
520
+ ]
521
+ context = build_context <<-END
522
+ EPackage StatemachineMM {
523
+ EClass State, abstract: true {
524
+ EAttribute name, eType: |/StatemachineMM/StringType
525
+ END
526
+ assert_link_targets context, :begin => 29, :end => 54, :targets => [
527
+ {"file"=> File.expand_path(@infile),
528
+ "line"=>14,
529
+ "display"=>"/StatemachineMM/StringType [EDataType]"}
530
+ ]
531
+ context = build_context <<-END
532
+ EPackage StatemachineMM {
533
+ EClass State, abstract: true {
534
+ EAttribute name, eType: /StatemachineMM/StringTyp|e
535
+ END
536
+ assert_link_targets context, :begin => 29, :end => 54, :targets => [
537
+ {"file"=> File.expand_path(@infile),
538
+ "line"=>14,
539
+ "display"=>"/StatemachineMM/StringType [EDataType]"}
540
+ ]
541
+ context = build_context <<-END
542
+ EPackage StatemachineMM {
543
+ EClass State, abstract: true {
544
+ EAttribute name, eType: /StatemachineMM/StringType|
545
+ END
546
+ assert_link_targets context, :begin => nil, :end => nil, :targets => []
547
+ context = build_context <<-END
548
+ EPackage StatemachineMM {
549
+ EClass State, abstract: true {
550
+ EAttribute name, eType:| /StatemachineMM/StringType
551
+ END
552
+ assert_link_targets context, :begin => nil, :end => nil, :targets => []
553
+ # backward ref
554
+ context = build_context <<-END
555
+ EPackage StatemachineMM {
556
+ E|Class State, abstract: true {
557
+ END
558
+ assert_link_targets context, :begin => 3, :end => 8, :targets => [
559
+ {"file"=> File.expand_path(@infile),
560
+ "line"=>6,
561
+ "display"=>"/StatemachineMM/SimpleState [EClass]"},
562
+ {"file"=> File.expand_path(@infile),
563
+ "line"=>7,
564
+ "display"=>"/StatemachineMM/CompositeState [EClass]"}
565
+ ]
566
+ context = build_context <<-END
567
+ EPackage StatemachineMM {
568
+ EClass State, abstract: true {
569
+ EAttribute name, eType: /StatemachineMM/StringType
570
+ EReference parent, eType: /StatemachineMM/CompositeState, eOpposite: /StatemachineMM/CompositeState/substates
571
+ }
572
+ |EClass SimpleState, eSuperTypes: [/StatemachineMM/State]
573
+ END
574
+ assert_link_targets context, :begin => 3, :end => 8, :targets => []
575
+ end
576
+
577
+ def test_link_targets_no_text_after_name
578
+ setup_connector(ModelFile)
579
+ load_model
580
+ context = build_context({:infile => ModelFile2}, <<-END
581
+ EPackage StatemachineMM2 {
582
+ ECl|ass State
583
+ END
584
+ )
585
+ assert_link_targets context, :file => ModelFile2, :begin => 3, :end => 8, :targets => [
586
+ {"file"=> File.expand_path(ModelFile2),
587
+ "line"=>3,
588
+ "display"=>"/StatemachineMM2/SimpleState [EClass]"}
589
+ ]
590
+ end
591
+
592
+ def test_find_elements
593
+ setup_connector(ModelFile)
594
+ load_model
595
+ response = @con.execute_command(
596
+ {"command" => "find_elements", "search_pattern" => "Sta"})
597
+ assert_equal \
598
+ [{"display"=>"State [EClass] - /StatemachineMM",
599
+ "file"=> File.expand_path(@infile),
600
+ "line"=>2},
601
+ {"display"=>"State [EClass] - /StatemachineMM2",
602
+ "file"=> File.expand_path(ModelFile2),
603
+ "line"=>2},
604
+ {"display"=>"StatemachineMM [EPackage] - /StatemachineMM",
605
+ "file"=> File.expand_path(@infile),
606
+ "line"=>1},
607
+ {"display"=>"StatemachineMM2 [EPackage] - /StatemachineMM2",
608
+ "file"=> File.expand_path(ModelFile2),
609
+ "line"=>1}], response["elements"]
610
+ response = @con.execute_command(
611
+ {"command" => "find_elements", "search_pattern" => "target"})
612
+ assert_equal \
613
+ [{"display"=>"target [EReference] - /StatemachineMM/Transition",
614
+ "file"=> File.expand_path(@infile),
615
+ "line"=>11}], response["elements"]
616
+ response = @con.execute_command(
617
+ {"command" => "find_elements", "search_pattern" => ""})
618
+ assert_equal [], response["elements"]
619
+ response = @con.execute_command(
620
+ {"command" => "find_elements", "search_pattern" => "xxx"})
621
+ assert_equal [], response["elements"]
622
+ end
623
+
624
+ TestContext = Struct.new(:line, :col)
625
+
626
+ def build_context(text, text2=nil)
627
+ if text.is_a?(Hash)
628
+ context_lines = text2.split("\n")
629
+ pos_in_line = text[:col] || context_lines.last.index("|") + 1
630
+ infile = text[:infile] || @infile
631
+ else
632
+ context_lines = text.split("\n")
633
+ pos_in_line = context_lines.last.index("|") + 1
634
+ infile = @infile
635
+ end
636
+ context_lines.last.sub!("|", "")
637
+
638
+ # check that the context data actally matches the real file in the filesystem
639
+ content = File.open(infile, "rb"){|f| f.read}
640
+ ref_lines = content.split(/\r?\n/)[0..context_lines.size-1]
641
+ raise "inconsistent test data, expected\n:#{ref_lines.join("\n")}\ngot:\n#{context_lines.join("\n")}\n" \
642
+ unless ref_lines == context_lines
643
+
644
+ # column numbers start at 1
645
+ TestContext.new(context_lines.size, pos_in_line)
646
+ end
647
+
648
+ def assert_link_targets(context, options)
649
+ infile = options[:file] || @infile
650
+ content = File.open(infile, "rb") {|f| f.read}
651
+ lines = content.split(/\r?\n/)[0..context.line-1]
652
+ lines = RText::Frontend::Context.extract(lines)
653
+ response = @con.execute_command(
654
+ {"command" => "link_targets", "context" => lines, "column" => context.col})
655
+ assert_equal options[:targets], response["targets"]
656
+ assert_equal options[:begin], response["begin_column"]
657
+ assert_equal options[:end], response["end_column"]
658
+ end
659
+
660
+ def assert_completions(context, expected)
661
+ content = File.open(@infile, "rb"){|f| f.read}
662
+ lines = content.split(/\r?\n/)[0..context.line-1]
663
+ lines = RText::Frontend::Context.extract(lines)
664
+ response = @con.execute_command(
665
+ {"command" => "content_complete", "context" => lines, "column" => context.col})
666
+ assert_equal expected, response["options"].collect{|o| o["insert"]}
667
+ end
668
+
669
+ def load_model
670
+ done = false
671
+ response = nil
672
+ while !done
673
+ response = @con.execute_command({"command" => "load_model"})
674
+ if response == :connecting && !@connection_timeout
675
+ sleep(0.1)
676
+ @con.resume
677
+ else
678
+ done = true
679
+ end
680
+ end
681
+ response
682
+ end
683
+
684
+ end