clarity-pattern-parser 11.3.9 → 11.3.11
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.
- package/.yarn/install-state.gz +0 -0
- package/dist/index.browser.js +205 -120
- package/dist/index.browser.js.map +1 -1
- package/dist/index.esm.js +205 -120
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +205 -120
- package/dist/index.js.map +1 -1
- package/dist/intellisense/AutoComplete.d.ts +26 -8
- package/dist/intellisense/SuggestionOption.d.ts +18 -2
- package/dist/patterns/InfiniteRepeat.d.ts +1 -0
- package/jest.config.js +2 -0
- package/jest.coverage.config.js +2 -0
- package/package.json +7 -6
- package/src/generator/delete.ts +88 -0
- package/src/generator/generator.test.ts +1 -0
- package/src/generator/generator.ts +3 -0
- package/src/generator/ivisitor.ts +1 -0
- package/src/generator/typescriptVisitor.ts +24 -3
- package/src/grammar/Grammar.test.ts +1 -0
- package/src/grammar/Grammar.ts +2 -0
- package/src/grammar/patterns.test.ts +36 -0
- package/src/grammar/spec.md +233 -84
- package/src/intellisense/AutoComplete.test.ts +629 -156
- package/src/intellisense/AutoComplete.ts +232 -109
- package/src/intellisense/SuggestionOption.ts +25 -2
- package/src/patterns/Expression.ts +4 -2
- package/src/patterns/FiniteRepeat.ts +4 -6
- package/src/patterns/InfiniteRepeat.ts +7 -1
- package/src/patterns/Literal.test.ts +1 -1
- package/src/patterns/Options.test.ts +1 -1
- package/src/patterns/PrecedenceTree.ts +31 -7
- package/src/patterns/Reference.test.ts +1 -1
- package/src/patterns/Regex.test.ts +3 -3
- package/src/patterns/Sequence.test.ts +1 -1
|
@@ -7,6 +7,19 @@ import { Regex } from "../patterns/Regex";
|
|
|
7
7
|
import { Repeat } from "../patterns/Repeat";
|
|
8
8
|
import { AutoComplete, AutoCompleteOptions } from "./AutoComplete";
|
|
9
9
|
import { Optional } from "../patterns/Optional";
|
|
10
|
+
import { SuggestionOption } from "./SuggestionOption";
|
|
11
|
+
|
|
12
|
+
interface ExpectedOption {
|
|
13
|
+
text: string;
|
|
14
|
+
startIndex: number;
|
|
15
|
+
subElements: ExpectedSubElement[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface ExpectedSubElement {
|
|
19
|
+
text: string;
|
|
20
|
+
// maps to the name of the pattern
|
|
21
|
+
pattern: string;
|
|
22
|
+
}
|
|
10
23
|
|
|
11
24
|
function generateFlagFromList(flagNames: string[]) {
|
|
12
25
|
return flagNames.map(flagName => {
|
|
@@ -24,6 +37,26 @@ function generateFlagPattern(flagNames: string[]): Pattern {
|
|
|
24
37
|
return flagPattern;
|
|
25
38
|
}
|
|
26
39
|
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
function optionsMatchExpected(resultOptions: SuggestionOption[], expectedOptions: ExpectedOption[]) {
|
|
43
|
+
|
|
44
|
+
const expectedOptionsPatternNames = expectedOptions.map(e => e.subElements.map(s => s.pattern));
|
|
45
|
+
const resultOptionsPatternNames = resultOptions.map(r => r.suggestionSequence.map(s => s.pattern.name));
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
expect(resultOptions.length).toBe(expectedOptions.length);
|
|
49
|
+
resultOptions.forEach((resultOption, index) => {
|
|
50
|
+
expect(resultOption.text).toBe(expectedOptions[index].text);
|
|
51
|
+
expect(resultOption.startIndex).toBe(expectedOptions[index].startIndex);
|
|
52
|
+
expect(resultOption.suggestionSequence.length).toBe(expectedOptions[index].subElements.length);
|
|
53
|
+
expect(expectedOptionsPatternNames).toEqual(resultOptionsPatternNames);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
27
60
|
export function generateExpression(flagNames: string[]): Repeat {
|
|
28
61
|
if (flagNames.length === 0) {
|
|
29
62
|
// regex is purposefully impossible to satisfy
|
|
@@ -103,21 +136,35 @@ describe("AutoComplete", () => {
|
|
|
103
136
|
const space = new Literal("space", " ");
|
|
104
137
|
const doe = new Literal("doe", "Doe");
|
|
105
138
|
const smith = new Literal("smith", "Smith");
|
|
106
|
-
const
|
|
139
|
+
const lastNameOptions = new Options("last-name", [smith, doe]);
|
|
140
|
+
const name = new Sequence("name", [john, space, lastNameOptions]);
|
|
107
141
|
|
|
108
|
-
const text = "John "
|
|
109
142
|
const autoComplete = new AutoComplete(name);
|
|
143
|
+
|
|
144
|
+
const text = "John "
|
|
110
145
|
const result = autoComplete.suggestFor(text);
|
|
111
|
-
|
|
146
|
+
|
|
147
|
+
const expectedOptions = [
|
|
148
|
+
{
|
|
112
149
|
text: "Doe",
|
|
113
|
-
startIndex: 5
|
|
114
|
-
|
|
150
|
+
startIndex: 5,
|
|
151
|
+
subElements: [{
|
|
152
|
+
text: "Doe",
|
|
153
|
+
pattern: 'doe'
|
|
154
|
+
}]
|
|
155
|
+
},
|
|
156
|
+
{
|
|
115
157
|
text: "Smith",
|
|
116
|
-
startIndex: 5
|
|
117
|
-
|
|
158
|
+
startIndex: 5,
|
|
159
|
+
subElements: [{
|
|
160
|
+
text: "Smith",
|
|
161
|
+
pattern: smith.name
|
|
162
|
+
}]
|
|
163
|
+
}
|
|
164
|
+
];
|
|
118
165
|
|
|
119
166
|
expect(result.ast).toBeNull();
|
|
120
|
-
|
|
167
|
+
optionsMatchExpected(result.options, expectedOptions);
|
|
121
168
|
expect(result.errorAtIndex).toBe(text.length);
|
|
122
169
|
expect(result.isComplete).toBeFalsy();
|
|
123
170
|
expect(result.cursor).not.toBeNull();
|
|
@@ -129,18 +176,24 @@ describe("AutoComplete", () => {
|
|
|
129
176
|
const space = new Literal("space", " ");
|
|
130
177
|
const doe = new Literal("doe", "Doe");
|
|
131
178
|
const smith = new Literal("smith", "Smith");
|
|
132
|
-
const
|
|
179
|
+
const lastNameOptions = new Options("last-name", [smith, doe]);
|
|
180
|
+
const name = new Sequence("name", [john, space, lastNameOptions]);
|
|
133
181
|
|
|
134
182
|
const text = "John Smi"
|
|
135
183
|
const autoComplete = new AutoComplete(name);
|
|
136
184
|
const result = autoComplete.suggestFor(text);
|
|
185
|
+
|
|
137
186
|
const expectedOptions = [{
|
|
138
187
|
text: "th",
|
|
139
|
-
startIndex: 8
|
|
188
|
+
startIndex: 8,
|
|
189
|
+
subElements: [{
|
|
190
|
+
text: "Smith",
|
|
191
|
+
pattern: smith.name
|
|
192
|
+
}]
|
|
140
193
|
}];
|
|
141
194
|
|
|
142
195
|
expect(result.ast).toBeNull();
|
|
143
|
-
|
|
196
|
+
optionsMatchExpected(result.options, expectedOptions);
|
|
144
197
|
expect(result.errorAtIndex).toBe(text.length);
|
|
145
198
|
expect(result.isComplete).toBeFalsy();
|
|
146
199
|
expect(result.cursor).not.toBeNull();
|
|
@@ -161,12 +214,18 @@ describe("AutoComplete", () => {
|
|
|
161
214
|
});
|
|
162
215
|
const result = autoComplete.suggestFor("luke");
|
|
163
216
|
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
217
|
+
const expectedOptions = [{
|
|
218
|
+
text: " skywalker",
|
|
219
|
+
startIndex: 4,
|
|
220
|
+
subElements: [{
|
|
221
|
+
text: " skywalker",
|
|
222
|
+
pattern: freeTextPattern.name
|
|
223
|
+
}]
|
|
224
|
+
}];
|
|
225
|
+
|
|
226
|
+
|
|
168
227
|
expect(result.ast?.value).toBe("luke");
|
|
169
|
-
|
|
228
|
+
optionsMatchExpected(result.options, expectedOptions);
|
|
170
229
|
expect(result.errorAtIndex).toBeNull()
|
|
171
230
|
expect(result.isComplete).toBeTruthy();
|
|
172
231
|
expect(result.cursor).not.toBeNull();
|
|
@@ -192,11 +251,15 @@ describe("AutoComplete", () => {
|
|
|
192
251
|
const result = autoComplete.suggestFor("jedi luke sky");
|
|
193
252
|
|
|
194
253
|
const expected = [
|
|
195
|
-
{ text: "walker", startIndex: 13
|
|
254
|
+
{ text: "walker", startIndex: 13, subElements: [{
|
|
255
|
+
text: "walker",
|
|
256
|
+
startIndex: 13,
|
|
257
|
+
pattern: freeTextPattern.name
|
|
258
|
+
}] },
|
|
196
259
|
];
|
|
197
260
|
|
|
198
261
|
expect(result.ast?.value).toBe("jedi luke sky");
|
|
199
|
-
|
|
262
|
+
optionsMatchExpected(result.options, expected);
|
|
200
263
|
expect(result.errorAtIndex).toBeNull()
|
|
201
264
|
expect(result.isComplete).toBeTruthy();
|
|
202
265
|
expect(result.cursor).not.toBeNull();
|
|
@@ -215,15 +278,20 @@ describe("AutoComplete", () => {
|
|
|
215
278
|
divider.setTokens([", "])
|
|
216
279
|
|
|
217
280
|
const text = "John Doe";
|
|
218
|
-
const
|
|
281
|
+
const repeat = new Repeat("last-names", name, { divider });
|
|
282
|
+
const autoComplete = new AutoComplete(repeat);
|
|
219
283
|
const result = autoComplete.suggestFor(text);
|
|
220
284
|
const expectedOptions = [{
|
|
221
285
|
text: ", ",
|
|
222
|
-
startIndex: 8
|
|
286
|
+
startIndex: 8,
|
|
287
|
+
subElements: [{
|
|
288
|
+
text: ", ",
|
|
289
|
+
pattern: 'divider'
|
|
290
|
+
}]
|
|
223
291
|
}];
|
|
224
292
|
|
|
225
293
|
expect(result.ast?.value).toBe(text);
|
|
226
|
-
|
|
294
|
+
optionsMatchExpected(result.options, expectedOptions);
|
|
227
295
|
expect(result.errorAtIndex).toBeNull()
|
|
228
296
|
expect(result.isComplete).toBeTruthy();
|
|
229
297
|
expect(result.cursor).not.toBeNull();
|
|
@@ -236,11 +304,15 @@ describe("AutoComplete", () => {
|
|
|
236
304
|
const result = autoComplete.suggestFor("Na");
|
|
237
305
|
const expectedOptions = [{
|
|
238
306
|
text: "me",
|
|
239
|
-
startIndex: 2
|
|
307
|
+
startIndex: 2,
|
|
308
|
+
subElements: [{
|
|
309
|
+
text: "me",
|
|
310
|
+
pattern: 'name'
|
|
311
|
+
}]
|
|
240
312
|
}];
|
|
241
313
|
|
|
242
314
|
expect(result.ast).toBeNull();
|
|
243
|
-
|
|
315
|
+
optionsMatchExpected(result.options, expectedOptions);
|
|
244
316
|
expect(result.errorAtIndex).toBe(2);
|
|
245
317
|
expect(result.isComplete).toBeFalsy();
|
|
246
318
|
expect(result.cursor).not.toBeNull();
|
|
@@ -253,11 +325,15 @@ describe("AutoComplete", () => {
|
|
|
253
325
|
|
|
254
326
|
const expectedOptions = [{
|
|
255
327
|
text: "ame",
|
|
256
|
-
startIndex: 1
|
|
328
|
+
startIndex: 1,
|
|
329
|
+
subElements: [{
|
|
330
|
+
text: "ame",
|
|
331
|
+
pattern: 'name'
|
|
332
|
+
}]
|
|
257
333
|
}];
|
|
258
334
|
|
|
259
335
|
expect(result.ast).toBeNull();
|
|
260
|
-
|
|
336
|
+
optionsMatchExpected(result.options, expectedOptions);
|
|
261
337
|
expect(result.errorAtIndex).toBe(1);
|
|
262
338
|
expect(result.isComplete).toBeFalsy();
|
|
263
339
|
expect(result.cursor).not.toBeNull();
|
|
@@ -270,7 +346,7 @@ describe("AutoComplete", () => {
|
|
|
270
346
|
const result = autoComplete.suggestFor(text);
|
|
271
347
|
|
|
272
348
|
expect(result.ast?.value).toBe(text);
|
|
273
|
-
|
|
349
|
+
optionsMatchExpected(result.options, []);
|
|
274
350
|
expect(result.errorAtIndex).toBeNull();
|
|
275
351
|
expect(result.isComplete).toBeTruthy();
|
|
276
352
|
expect(result.cursor).not.toBeNull();
|
|
@@ -295,29 +371,41 @@ describe("AutoComplete", () => {
|
|
|
295
371
|
|
|
296
372
|
const text = "Jack";
|
|
297
373
|
const autoComplete = new AutoComplete(fullName, autoCompleteOptions);
|
|
298
|
-
const
|
|
374
|
+
const result = autoComplete.suggestFor(text);
|
|
299
375
|
|
|
300
|
-
const expectedOptions = [
|
|
301
|
-
{ text: " Doe", startIndex: 4
|
|
302
|
-
|
|
303
|
-
|
|
376
|
+
const expectedOptions:ExpectedOption[] = [
|
|
377
|
+
{ text: " Doe", startIndex: 4, subElements: [{
|
|
378
|
+
text: " ",
|
|
379
|
+
pattern: space.name
|
|
380
|
+
},{
|
|
381
|
+
text: "Doe",
|
|
382
|
+
pattern: doe.name
|
|
383
|
+
}] },
|
|
384
|
+
{ text: " Smith", startIndex: 4, subElements: [{
|
|
385
|
+
text: " ",
|
|
386
|
+
pattern: space.name
|
|
387
|
+
},{
|
|
388
|
+
text: "Smith",
|
|
389
|
+
pattern: smith.name
|
|
390
|
+
}] },
|
|
391
|
+
{ text: " Sparrow", startIndex: 4, subElements: [{
|
|
392
|
+
text: " ",
|
|
393
|
+
pattern: space.name
|
|
394
|
+
},{
|
|
395
|
+
text: "Sparrow",
|
|
396
|
+
pattern: "last-name"
|
|
397
|
+
}] },
|
|
304
398
|
];
|
|
305
399
|
|
|
306
|
-
const results = expectedOptions.map(o => text.slice(0, o.startIndex) + o.text);
|
|
307
|
-
const expectedResults = [
|
|
308
|
-
"Jack Doe",
|
|
309
|
-
"Jack Smith",
|
|
310
|
-
"Jack Sparrow",
|
|
311
|
-
]
|
|
312
400
|
|
|
313
|
-
expect(ast).toBeNull();
|
|
314
|
-
expect(errorAtIndex).toBe(4);
|
|
315
|
-
|
|
316
|
-
expect(results).toEqual(expectedResults);
|
|
401
|
+
expect(result.ast).toBeNull();
|
|
402
|
+
expect(result.errorAtIndex).toBe(4);
|
|
403
|
+
optionsMatchExpected(result.options, expectedOptions);
|
|
317
404
|
|
|
318
405
|
});
|
|
319
406
|
|
|
320
407
|
|
|
408
|
+
|
|
321
409
|
test("Options AutoComplete on Root Pattern", () => {
|
|
322
410
|
|
|
323
411
|
const jack = new Literal("first-name", "Jack");
|
|
@@ -327,25 +415,43 @@ describe("AutoComplete", () => {
|
|
|
327
415
|
const divider = new Literal('divider', ', ');
|
|
328
416
|
const repeat = new Repeat('name-list', names, { divider, trimDivider: true });
|
|
329
417
|
|
|
330
|
-
const text = ''
|
|
331
|
-
|
|
332
418
|
const autoCompleteOptions: AutoCompleteOptions = {
|
|
333
419
|
customTokens: {
|
|
334
420
|
'first-name': ["James"]
|
|
335
|
-
}
|
|
421
|
+
},
|
|
422
|
+
disableDedupe: true
|
|
336
423
|
};
|
|
337
424
|
const autoComplete = new AutoComplete(repeat,autoCompleteOptions);
|
|
338
|
-
|
|
339
|
-
const
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
425
|
+
|
|
426
|
+
const text = ''
|
|
427
|
+
const results = autoComplete.suggestFor(text)
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
const expectedOptions:ExpectedOption[] = [
|
|
431
|
+
|
|
432
|
+
{ text: "Jack", startIndex: 0, subElements: [{
|
|
433
|
+
text: "Jack",
|
|
434
|
+
pattern: jack.name
|
|
435
|
+
}] },
|
|
436
|
+
{ text: "James", startIndex: 0, subElements: [{
|
|
437
|
+
text: "James",
|
|
438
|
+
pattern: 'first-name'
|
|
439
|
+
}] },
|
|
440
|
+
{ text: "James", startIndex: 0, subElements: [{
|
|
441
|
+
text: "James",
|
|
442
|
+
pattern: 'first-name'
|
|
443
|
+
}] },
|
|
444
|
+
{ text: "John", startIndex: 0, subElements: [{
|
|
445
|
+
text: "John",
|
|
446
|
+
pattern: john.name
|
|
447
|
+
}] },
|
|
345
448
|
];
|
|
346
449
|
|
|
347
|
-
|
|
348
|
-
|
|
450
|
+
optionsMatchExpected(results.options, expectedOptions);
|
|
451
|
+
// because autoCompleteOptions specifies "last-name" which is shared by two literals, we get two suggestions each mapping to a respective pattern of that name
|
|
452
|
+
expect(results.options[0].suggestionSequence[0].pattern.id).toBe(jack.id);
|
|
453
|
+
expect(results.options[2].suggestionSequence[0].pattern.id).toBe(john.id);
|
|
454
|
+
|
|
349
455
|
})
|
|
350
456
|
|
|
351
457
|
test("Options AutoComplete On Leaf Pattern", () => {
|
|
@@ -367,26 +473,41 @@ describe("AutoComplete", () => {
|
|
|
367
473
|
|
|
368
474
|
const text = "Jack";
|
|
369
475
|
const autoComplete = new AutoComplete(fullName, autoCompleteOptions);
|
|
370
|
-
const
|
|
371
|
-
const expectedOptions = [
|
|
372
|
-
{ text: " Doe", startIndex: 4
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
476
|
+
const results = autoComplete.suggestFor(text);
|
|
477
|
+
const expectedOptions:ExpectedOption[] = [
|
|
478
|
+
{ text: " Doe", startIndex: 4, subElements: [{
|
|
479
|
+
text: " ",
|
|
480
|
+
pattern: space.name
|
|
481
|
+
},{
|
|
482
|
+
text: "Doe",
|
|
483
|
+
pattern: doe.name
|
|
484
|
+
}] },
|
|
485
|
+
{ text: " Smith", startIndex: 4, subElements: [{
|
|
486
|
+
text: " ",
|
|
487
|
+
pattern: space.name
|
|
488
|
+
},{
|
|
489
|
+
text: "Smith",
|
|
490
|
+
pattern: smith.name
|
|
491
|
+
}] },
|
|
492
|
+
{ text: " Doe", startIndex: 4, subElements: [{
|
|
493
|
+
text: " ",
|
|
494
|
+
pattern: space.name
|
|
495
|
+
},{
|
|
496
|
+
text: "Doe",
|
|
497
|
+
pattern: doe.name
|
|
498
|
+
}] },
|
|
499
|
+
{ text: " Smith", startIndex: 4, subElements: [{
|
|
500
|
+
text: " ",
|
|
501
|
+
pattern: space.name
|
|
502
|
+
},{
|
|
503
|
+
text: "Smith",
|
|
504
|
+
pattern: smith.name
|
|
505
|
+
}] },
|
|
376
506
|
];
|
|
377
507
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
"Jack Smith",
|
|
382
|
-
"Jack Doe",
|
|
383
|
-
"Jack Smith",
|
|
384
|
-
]
|
|
385
|
-
|
|
386
|
-
expect(ast).toBeNull();
|
|
387
|
-
expect(errorAtIndex).toBe(4);
|
|
388
|
-
expect(options).toEqual(expectedOptions);
|
|
389
|
-
expect(results).toEqual(expectedResults)
|
|
508
|
+
expect(results.ast).toBeNull();
|
|
509
|
+
expect(results.errorAtIndex).toBe(4);
|
|
510
|
+
optionsMatchExpected(results.options, expectedOptions);
|
|
390
511
|
|
|
391
512
|
});
|
|
392
513
|
|
|
@@ -401,96 +522,170 @@ describe("AutoComplete", () => {
|
|
|
401
522
|
const both = new Options("both", [first, second]);
|
|
402
523
|
|
|
403
524
|
const autoComplete = new AutoComplete(both);
|
|
404
|
-
|
|
405
|
-
const
|
|
406
|
-
|
|
407
|
-
|
|
525
|
+
|
|
526
|
+
const text = "John went to a gas station.";
|
|
527
|
+
const result = autoComplete.suggestFor(text);
|
|
528
|
+
|
|
529
|
+
const expected:ExpectedOption[] = [
|
|
530
|
+
{ text: "the store.", startIndex: 12, subElements: [{
|
|
531
|
+
text: "the",
|
|
532
|
+
pattern: the.name
|
|
533
|
+
},] },
|
|
534
|
+
{ text: "a bank.", startIndex: 12, subElements: [{
|
|
535
|
+
text: "a",
|
|
536
|
+
pattern: a.name
|
|
537
|
+
}] }
|
|
408
538
|
];
|
|
409
|
-
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
optionsMatchExpected(result.options, expected);
|
|
410
542
|
});
|
|
411
543
|
|
|
412
544
|
test("Options on errors because of string ending, with match", () => {
|
|
545
|
+
|
|
546
|
+
const large = new Literal("large", "kahnnnnnn");
|
|
547
|
+
const medium = new Literal("medium", "kahnnnnn");
|
|
548
|
+
const small = new Literal("small", "kahn");
|
|
549
|
+
|
|
550
|
+
|
|
413
551
|
const smalls = new Options("kahns", [
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
552
|
+
large,
|
|
553
|
+
medium,
|
|
554
|
+
small,
|
|
417
555
|
]);
|
|
418
556
|
|
|
419
557
|
const autoComplete = new AutoComplete(smalls);
|
|
420
558
|
const result = autoComplete.suggestFor("kahn");
|
|
421
559
|
|
|
422
|
-
const expected = [
|
|
423
|
-
{ text: "nnnnn", startIndex: 4
|
|
424
|
-
|
|
560
|
+
const expected:ExpectedOption[] = [
|
|
561
|
+
{ text: "nnnnn", startIndex: 4, subElements: [{
|
|
562
|
+
text: "nnnnn",
|
|
563
|
+
pattern: large.name
|
|
564
|
+
}] },
|
|
565
|
+
{ text: "nnnn", startIndex: 4, subElements: [{
|
|
566
|
+
text: "nnnn",
|
|
567
|
+
pattern: medium.name
|
|
568
|
+
}] }
|
|
425
569
|
];
|
|
426
570
|
|
|
427
|
-
|
|
571
|
+
optionsMatchExpected(result.options, expected);
|
|
572
|
+
|
|
428
573
|
expect(result.isComplete).toBeTruthy();
|
|
429
574
|
});
|
|
430
575
|
|
|
576
|
+
|
|
431
577
|
test("Options on errors because of string ending, between matches", () => {
|
|
578
|
+
|
|
579
|
+
const large = new Literal("large", "kahnnnnnn");
|
|
580
|
+
const medium = new Literal("medium", "kahnnnnn");
|
|
581
|
+
const small = new Literal("small", "kahn");
|
|
582
|
+
|
|
583
|
+
|
|
432
584
|
const smalls = new Options("kahns", [
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
585
|
+
large,
|
|
586
|
+
medium,
|
|
587
|
+
small,
|
|
436
588
|
]);
|
|
437
589
|
|
|
438
590
|
const autoComplete = new AutoComplete(smalls);
|
|
439
591
|
const result = autoComplete.suggestFor("kahnn");
|
|
440
592
|
|
|
441
|
-
const expected = [
|
|
442
|
-
{ text: "nnnn", startIndex: 5
|
|
443
|
-
|
|
593
|
+
const expected:ExpectedOption[] = [
|
|
594
|
+
{ text: "nnnn", startIndex: 5, subElements: [{
|
|
595
|
+
text: "nnnn",
|
|
596
|
+
pattern: large.name
|
|
597
|
+
}] },
|
|
598
|
+
{ text: "nnn", startIndex: 5, subElements: [{
|
|
599
|
+
text: "nnn",
|
|
600
|
+
pattern: medium.name
|
|
601
|
+
}] }
|
|
444
602
|
];
|
|
445
603
|
|
|
446
|
-
|
|
604
|
+
|
|
605
|
+
optionsMatchExpected(result.options, expected);
|
|
447
606
|
expect(result.isComplete).toBeFalsy();
|
|
448
607
|
});
|
|
449
608
|
|
|
450
609
|
test("Options on errors because of string ending, match middle", () => {
|
|
610
|
+
const large = new Literal("large", "kahnnnnnn");
|
|
611
|
+
const medium = new Literal("medium", "kahnnnnn");
|
|
612
|
+
const small = new Literal("small", "kahn");
|
|
451
613
|
const smalls = new Options("kahns", [
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
614
|
+
large,
|
|
615
|
+
medium,
|
|
616
|
+
small,
|
|
455
617
|
]);
|
|
456
618
|
|
|
457
619
|
const autoComplete = new AutoComplete(smalls);
|
|
458
620
|
const result = autoComplete.suggestFor("kahnnnnn");
|
|
459
621
|
|
|
460
|
-
const expected = [
|
|
461
|
-
{ text: "n", startIndex: 8
|
|
622
|
+
const expected:ExpectedOption[] = [
|
|
623
|
+
{ text: "n", startIndex: 8, subElements: [{
|
|
624
|
+
text: "n",
|
|
625
|
+
pattern: large.name
|
|
626
|
+
}] },
|
|
462
627
|
];
|
|
463
628
|
|
|
464
|
-
|
|
629
|
+
optionsMatchExpected(result.options, expected);
|
|
630
|
+
|
|
465
631
|
expect(result.isComplete).toBeTruthy();
|
|
466
632
|
});
|
|
467
633
|
|
|
468
634
|
|
|
469
635
|
test("Options on errors because of string ending on a variety, with match", () => {
|
|
636
|
+
const different3 = new Literal("different-3", "kahnnnnnnn3");
|
|
637
|
+
const different21 = new Literal("different-21", "kahnnnnnn21");
|
|
638
|
+
const different22 = new Literal("different-22", "kahnnnnnn22");
|
|
639
|
+
const different2 = new Literal("different-2", "kahnnnnnn2");
|
|
640
|
+
const different1 = new Literal("different", "kahnnnnnn1");
|
|
641
|
+
const large = new Literal("large", "kahnnnnnn");
|
|
642
|
+
const small = new Literal("small", "kahn");
|
|
643
|
+
const medium = new Literal("medium", "kahnnnnn");
|
|
644
|
+
|
|
470
645
|
const smalls = new Options("kahns", [
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
646
|
+
different3,
|
|
647
|
+
different21,
|
|
648
|
+
different22,
|
|
649
|
+
different2,
|
|
650
|
+
different1,
|
|
651
|
+
large,
|
|
652
|
+
medium,
|
|
653
|
+
small,
|
|
479
654
|
]);
|
|
480
655
|
|
|
481
656
|
const autoComplete = new AutoComplete(smalls);
|
|
482
657
|
const result = autoComplete.suggestFor("kahnnnnn");
|
|
483
658
|
|
|
484
|
-
const expected
|
|
485
|
-
{ text: "nn3", startIndex: 8
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
659
|
+
const expected:ExpectedOption[] = [
|
|
660
|
+
{ text: "nn3", startIndex: 8, subElements: [{
|
|
661
|
+
text: "nn3",
|
|
662
|
+
pattern: different3.name
|
|
663
|
+
}] },
|
|
664
|
+
{ text: "n21", startIndex: 8, subElements: [{
|
|
665
|
+
text: "n21",
|
|
666
|
+
pattern: different21.name
|
|
667
|
+
}] },
|
|
668
|
+
{ text: "n22", startIndex: 8 , subElements: [{
|
|
669
|
+
text: "n22",
|
|
670
|
+
pattern: different22.name
|
|
671
|
+
}] },
|
|
672
|
+
{ text: "n2", startIndex: 8, subElements: [{
|
|
673
|
+
text: "n2",
|
|
674
|
+
pattern: different2.name
|
|
675
|
+
}] },
|
|
676
|
+
{ text: "n1", startIndex: 8, subElements: [{
|
|
677
|
+
text: "n1",
|
|
678
|
+
pattern: different1.name
|
|
679
|
+
}] },
|
|
680
|
+
{ text: "n", startIndex: 8, subElements: [{
|
|
681
|
+
text: "n",
|
|
682
|
+
pattern: large.name
|
|
683
|
+
}] },
|
|
491
684
|
];
|
|
492
685
|
|
|
493
|
-
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
optionsMatchExpected(result.options, expected);
|
|
494
689
|
expect(result.isComplete).toBeTruthy();
|
|
495
690
|
});
|
|
496
691
|
|
|
@@ -505,13 +700,23 @@ describe("AutoComplete", () => {
|
|
|
505
700
|
const autoComplete = new AutoComplete(smalls);
|
|
506
701
|
const result = autoComplete.suggestFor("kahn");
|
|
507
702
|
|
|
508
|
-
const expected = [
|
|
509
|
-
{ text: "2", startIndex: 4
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
703
|
+
const expected:ExpectedOption[] = [
|
|
704
|
+
{ text: "2", startIndex: 4, subElements: [{
|
|
705
|
+
text: "2",
|
|
706
|
+
pattern: "two"
|
|
707
|
+
}] },
|
|
708
|
+
{ text: "1", startIndex: 4, subElements: [{
|
|
709
|
+
text: "1",
|
|
710
|
+
pattern: "one"
|
|
711
|
+
}] },
|
|
712
|
+
{ text: "3", startIndex: 4, subElements: [{
|
|
713
|
+
text: "3",
|
|
714
|
+
pattern: "three"
|
|
715
|
+
}] },
|
|
716
|
+
];
|
|
717
|
+
|
|
718
|
+
|
|
719
|
+
optionsMatchExpected(result.options, expected);
|
|
515
720
|
expect(result.isComplete).toBeTruthy();
|
|
516
721
|
});
|
|
517
722
|
|
|
@@ -520,15 +725,57 @@ describe("AutoComplete", () => {
|
|
|
520
725
|
const autoComplete = new AutoComplete(repeat);
|
|
521
726
|
const result = autoComplete.suggestFor("a|a|");
|
|
522
727
|
|
|
523
|
-
|
|
728
|
+
const expected:ExpectedOption[] = [
|
|
729
|
+
{ text: "a", startIndex: 4, subElements: [{
|
|
730
|
+
text: "a",
|
|
731
|
+
pattern: "a"
|
|
732
|
+
}] },
|
|
733
|
+
];
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
optionsMatchExpected(result.options, expected);
|
|
737
|
+
|
|
524
738
|
});
|
|
525
739
|
|
|
740
|
+
test("Remove options divider", () => {
|
|
741
|
+
const jediLuke = new Literal(`jedi`, 'luke');
|
|
742
|
+
const names = new Options('names', [jediLuke]);
|
|
743
|
+
const literalA = new Literal('literal-a', 'a');
|
|
744
|
+
const literalB = new Literal('literal-b', 'b');
|
|
745
|
+
|
|
746
|
+
const optionsDivider = new Options('options-divider', [literalA, literalB]);
|
|
747
|
+
|
|
748
|
+
// control to prove the pattern works without trimDivider
|
|
749
|
+
const controlPattern = new Repeat('name-list', names, { divider: optionsDivider });
|
|
750
|
+
const controlAutoComplete = new AutoComplete(controlPattern);
|
|
751
|
+
const controlResult = controlAutoComplete.suggestFor('lukea');
|
|
752
|
+
expect(controlResult.isComplete).toEqual(true);
|
|
753
|
+
|
|
754
|
+
const trimPattern = new Repeat('name-list', names, { divider: optionsDivider, trimDivider: true });
|
|
755
|
+
const trimAutoComplete = new AutoComplete(trimPattern);
|
|
756
|
+
|
|
757
|
+
const trimResult = trimAutoComplete.suggestFor('lukea');
|
|
758
|
+
expect(trimResult.isComplete).toEqual(false);
|
|
759
|
+
})
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
|
|
526
764
|
test("Expect Divider", () => {
|
|
527
765
|
const repeat = new Repeat("repeat", new Literal("a", "a"), { divider: new Literal("pipe", "|") });
|
|
528
766
|
const autoComplete = new AutoComplete(repeat);
|
|
529
767
|
const result = autoComplete.suggestFor("a|a");
|
|
530
768
|
|
|
531
|
-
|
|
769
|
+
|
|
770
|
+
const expected:ExpectedOption[] = [
|
|
771
|
+
{ text: '|', startIndex: 3, subElements: [{
|
|
772
|
+
text: '|',
|
|
773
|
+
pattern: 'pipe'
|
|
774
|
+
}] }
|
|
775
|
+
];
|
|
776
|
+
|
|
777
|
+
optionsMatchExpected(result.options, expected);
|
|
778
|
+
|
|
532
779
|
});
|
|
533
780
|
|
|
534
781
|
test("Repeat with bad second repeat", () => {
|
|
@@ -536,7 +783,16 @@ describe("AutoComplete", () => {
|
|
|
536
783
|
const autoComplete = new AutoComplete(repeat);
|
|
537
784
|
const result = autoComplete.suggestFor("a|b");
|
|
538
785
|
|
|
539
|
-
|
|
786
|
+
|
|
787
|
+
const expected:ExpectedOption[] = [
|
|
788
|
+
{ text: "a", startIndex: 2, subElements: [{
|
|
789
|
+
text: "a",
|
|
790
|
+
pattern: "a"
|
|
791
|
+
}] },
|
|
792
|
+
];
|
|
793
|
+
|
|
794
|
+
optionsMatchExpected(result.options, expected);
|
|
795
|
+
|
|
540
796
|
});
|
|
541
797
|
|
|
542
798
|
test("Repeat with bad trailing content", () => {
|
|
@@ -565,29 +821,48 @@ describe("AutoComplete", () => {
|
|
|
565
821
|
|
|
566
822
|
const autoComplete = new AutoComplete(names);
|
|
567
823
|
const results = autoComplete.suggestFor("John ");
|
|
568
|
-
const expected = [
|
|
824
|
+
const expected:ExpectedOption[] = [
|
|
569
825
|
{
|
|
570
826
|
text: "Doe",
|
|
571
827
|
startIndex: 5,
|
|
828
|
+
subElements: [{
|
|
829
|
+
text: "Doe",
|
|
830
|
+
pattern: "doe"
|
|
831
|
+
}]
|
|
572
832
|
},
|
|
573
833
|
{
|
|
574
834
|
text: "Smith",
|
|
575
835
|
startIndex: 5,
|
|
836
|
+
subElements: [{
|
|
837
|
+
text: "Smith",
|
|
838
|
+
pattern: "smith"
|
|
839
|
+
}]
|
|
576
840
|
},
|
|
577
841
|
{
|
|
578
842
|
text: "Stockton",
|
|
579
843
|
startIndex: 5,
|
|
844
|
+
subElements: [{
|
|
845
|
+
text: "Stockton",
|
|
846
|
+
pattern: "john-stockton"
|
|
847
|
+
}]
|
|
580
848
|
},
|
|
581
849
|
{
|
|
582
850
|
text: "Johnson",
|
|
583
|
-
startIndex: 5,
|
|
851
|
+
startIndex: 5,
|
|
852
|
+
subElements: [{
|
|
853
|
+
text: "Johnson",
|
|
854
|
+
pattern: "john-johnson"
|
|
855
|
+
}]
|
|
584
856
|
},
|
|
585
857
|
];
|
|
586
|
-
|
|
858
|
+
|
|
859
|
+
|
|
860
|
+
optionsMatchExpected(results.options, expected);
|
|
587
861
|
expect(results.ast).toBeNull();
|
|
588
862
|
expect(results.errorAtIndex).toBe(5);
|
|
589
863
|
});
|
|
590
864
|
|
|
865
|
+
|
|
591
866
|
test("Dedup suggestions", () => {
|
|
592
867
|
const branchOne = new Sequence("branch-1", [new Literal("space", " "), new Literal("A", "A")]);
|
|
593
868
|
const branchTwo = new Sequence("branch-2", [new Literal("space", " "), new Literal("B", "B")]);
|
|
@@ -595,11 +870,16 @@ describe("AutoComplete", () => {
|
|
|
595
870
|
|
|
596
871
|
const autoComplete = new AutoComplete(eitherBranch);
|
|
597
872
|
const results = autoComplete.suggestFor("");
|
|
598
|
-
const expected = [{
|
|
873
|
+
const expected:ExpectedOption[] = [{
|
|
599
874
|
startIndex: 0,
|
|
600
|
-
text: " "
|
|
875
|
+
text: " ",
|
|
876
|
+
subElements: [{
|
|
877
|
+
text: " ",
|
|
878
|
+
pattern: "space"
|
|
879
|
+
}]
|
|
601
880
|
}];
|
|
602
|
-
|
|
881
|
+
|
|
882
|
+
optionsMatchExpected(results.options, expected);
|
|
603
883
|
});
|
|
604
884
|
|
|
605
885
|
test("Multiple Complex Branches", () => {
|
|
@@ -624,12 +904,23 @@ describe("AutoComplete", () => {
|
|
|
624
904
|
|
|
625
905
|
const autoComplete = new AutoComplete(eitherBranch);
|
|
626
906
|
const results = autoComplete.suggestFor(" B");
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
{ startIndex: 3, text: "
|
|
630
|
-
|
|
907
|
+
|
|
908
|
+
const expected:ExpectedOption[] = [
|
|
909
|
+
{ startIndex: 3, text: "A", subElements: [{
|
|
910
|
+
text: "A",
|
|
911
|
+
pattern: "BA"
|
|
912
|
+
}] },
|
|
913
|
+
{ startIndex: 3, text: "B", subElements: [{
|
|
914
|
+
text: "B",
|
|
915
|
+
pattern: "BB"
|
|
916
|
+
}] },
|
|
917
|
+
{ startIndex: 3, text: "C", subElements: [{
|
|
918
|
+
text: "C",
|
|
919
|
+
pattern: "BC"
|
|
920
|
+
}] },
|
|
631
921
|
];
|
|
632
|
-
|
|
922
|
+
|
|
923
|
+
optionsMatchExpected(results.options, expected);
|
|
633
924
|
});
|
|
634
925
|
|
|
635
926
|
|
|
@@ -644,9 +935,15 @@ describe("AutoComplete", () => {
|
|
|
644
935
|
const autoComplete = new AutoComplete(names);
|
|
645
936
|
const suggestion = autoComplete.suggestFor("Jo");
|
|
646
937
|
|
|
647
|
-
|
|
648
|
-
{ text: 'hn', startIndex: 2
|
|
649
|
-
|
|
938
|
+
const expected:ExpectedOption[] = [
|
|
939
|
+
{ text: 'hn', startIndex: 2, subElements: [{
|
|
940
|
+
text: 'hn',
|
|
941
|
+
pattern: "john"
|
|
942
|
+
}] },
|
|
943
|
+
];
|
|
944
|
+
|
|
945
|
+
optionsMatchExpected(suggestion.options, expected);
|
|
946
|
+
|
|
650
947
|
expect(suggestion.error?.lastIndex).toBe(2);
|
|
651
948
|
});
|
|
652
949
|
|
|
@@ -679,13 +976,26 @@ describe("AutoComplete", () => {
|
|
|
679
976
|
});
|
|
680
977
|
const suggestion = autoComplete.suggestFor("John");
|
|
681
978
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
"startIndex
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
979
|
+
|
|
980
|
+
const expected:ExpectedOption[] = [
|
|
981
|
+
{ text: " Doe", startIndex: 4, subElements: [{
|
|
982
|
+
text: " ",
|
|
983
|
+
pattern: "space"
|
|
984
|
+
},{
|
|
985
|
+
text: "Doe",
|
|
986
|
+
pattern: "doe"
|
|
987
|
+
}] },
|
|
988
|
+
{ text: " Smith", startIndex: 4, subElements: [{
|
|
989
|
+
text: " ",
|
|
990
|
+
pattern: "space"
|
|
991
|
+
},{
|
|
992
|
+
text: "Smith",
|
|
993
|
+
pattern: "smith"
|
|
994
|
+
}] },
|
|
995
|
+
];
|
|
996
|
+
|
|
997
|
+
optionsMatchExpected(suggestion.options, expected);
|
|
998
|
+
|
|
689
999
|
});
|
|
690
1000
|
|
|
691
1001
|
test("Repeat With Options", () => {
|
|
@@ -701,6 +1011,7 @@ describe("AutoComplete", () => {
|
|
|
701
1011
|
const autoComplete = new AutoComplete(list);
|
|
702
1012
|
const suggestion = autoComplete.suggestFor("John, ");
|
|
703
1013
|
|
|
1014
|
+
|
|
704
1015
|
expect(suggestion).toBe(suggestion);
|
|
705
1016
|
});
|
|
706
1017
|
|
|
@@ -724,6 +1035,7 @@ describe("AutoComplete", () => {
|
|
|
724
1035
|
expect(suggestion).toBe(suggestion);
|
|
725
1036
|
});
|
|
726
1037
|
|
|
1038
|
+
|
|
727
1039
|
test("Mid sequence suggestion", () => {
|
|
728
1040
|
const operator = new Options("operator", [
|
|
729
1041
|
new Literal("==", "=="),
|
|
@@ -746,19 +1058,35 @@ describe("AutoComplete", () => {
|
|
|
746
1058
|
);
|
|
747
1059
|
const result = autoComplete.suggestFor("variable1 ==");
|
|
748
1060
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
startIndex: 12,
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
text: "variable4",
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
1061
|
+
|
|
1062
|
+
const expected:ExpectedOption[] = [
|
|
1063
|
+
{ text: " variable3", startIndex: 12, subElements: [{
|
|
1064
|
+
text: " ",
|
|
1065
|
+
pattern: "space"
|
|
1066
|
+
},{
|
|
1067
|
+
text: "variable3",
|
|
1068
|
+
pattern: "variable-3"
|
|
1069
|
+
}] },
|
|
1070
|
+
{ text: " variable4", startIndex: 12, subElements: [{
|
|
1071
|
+
text: " ",
|
|
1072
|
+
pattern: "space"
|
|
1073
|
+
},{
|
|
1074
|
+
text: "variable4",
|
|
1075
|
+
pattern: "variable-4"
|
|
1076
|
+
}] },
|
|
1077
|
+
{ text: "variable3", startIndex: 12, subElements: [{
|
|
1078
|
+
text: "variable3",
|
|
1079
|
+
pattern: "variable-3"
|
|
1080
|
+
}] },
|
|
1081
|
+
{ text: "variable4", startIndex: 12, subElements: [{
|
|
1082
|
+
text: "variable4",
|
|
1083
|
+
pattern: "variable-4"
|
|
1084
|
+
}] },
|
|
1085
|
+
|
|
1086
|
+
];
|
|
1087
|
+
|
|
1088
|
+
optionsMatchExpected(result.options, expected);
|
|
1089
|
+
|
|
762
1090
|
});
|
|
763
1091
|
|
|
764
1092
|
|
|
@@ -787,6 +1115,151 @@ describe("AutoComplete", () => {
|
|
|
787
1115
|
expect(customTokensMap).toEqual(copiedCustomTokensMap)
|
|
788
1116
|
})
|
|
789
1117
|
|
|
1118
|
+
|
|
1119
|
+
test("Suggests entire greedy node, with appended successive nodes", () => {
|
|
1120
|
+
|
|
1121
|
+
const start = new Literal("start", "start");
|
|
1122
|
+
const separator = new Literal("separator", '==');
|
|
1123
|
+
|
|
1124
|
+
const aLiteral = new Literal("letter", "A");
|
|
1125
|
+
const bLiteral = new Literal("letter", "B");
|
|
1126
|
+
const cLiteral = new Literal("letter", "C");
|
|
1127
|
+
const abcOptions = new Options("letters-options", [aLiteral, bLiteral, cLiteral]);
|
|
1128
|
+
|
|
1129
|
+
const fullSequence = new Sequence("full-sequence", [start, separator, abcOptions]);
|
|
1130
|
+
|
|
1131
|
+
const autoCompleteOptions: AutoCompleteOptions = {
|
|
1132
|
+
greedyPatternNames: ["separator"],
|
|
1133
|
+
};
|
|
1134
|
+
const autoComplete = new AutoComplete(fullSequence, autoCompleteOptions);
|
|
1135
|
+
|
|
1136
|
+
const text = "start";
|
|
1137
|
+
const results = autoComplete.suggestFor(text);
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
const expectedOptions:ExpectedOption[] = [
|
|
1141
|
+
{ text: "==A", startIndex: 5, subElements: [{
|
|
1142
|
+
text: "==",
|
|
1143
|
+
pattern: separator.name
|
|
1144
|
+
},{
|
|
1145
|
+
text: "A",
|
|
1146
|
+
pattern: aLiteral.name
|
|
1147
|
+
}] },
|
|
1148
|
+
{ text: "==B", startIndex: 5, subElements: [{
|
|
1149
|
+
text: "==",
|
|
1150
|
+
pattern: separator.name
|
|
1151
|
+
},{
|
|
1152
|
+
text: "B",
|
|
1153
|
+
pattern: bLiteral.name
|
|
1154
|
+
}] },
|
|
1155
|
+
{ text: "==C", startIndex: 5, subElements: [{
|
|
1156
|
+
text: "==",
|
|
1157
|
+
pattern: separator.name
|
|
1158
|
+
},{
|
|
1159
|
+
text: "C",
|
|
1160
|
+
pattern: cLiteral.name
|
|
1161
|
+
}] },
|
|
1162
|
+
];
|
|
1163
|
+
|
|
1164
|
+
optionsMatchExpected(results.options, expectedOptions);
|
|
1165
|
+
|
|
1166
|
+
});
|
|
1167
|
+
|
|
1168
|
+
test("incomplete greedy text, suggests node completion with appended successive nodes", () => {
|
|
1169
|
+
|
|
1170
|
+
const start = new Literal("start", "start");
|
|
1171
|
+
const separator = new Literal("separator", '==');
|
|
1172
|
+
|
|
1173
|
+
const aLiteral = new Literal("letter", "A");
|
|
1174
|
+
const bLiteral = new Literal("letter", "B");
|
|
1175
|
+
const cLiteral = new Literal("letter", "C");
|
|
1176
|
+
const abcOptions = new Options("letters-options", [aLiteral, bLiteral, cLiteral]);
|
|
1177
|
+
|
|
1178
|
+
const fullSequence = new Sequence("full-sequence", [start, separator, abcOptions]);
|
|
1179
|
+
|
|
1180
|
+
const autoCompleteOptions: AutoCompleteOptions = {
|
|
1181
|
+
greedyPatternNames: ["separator"],
|
|
1182
|
+
};
|
|
1183
|
+
const autoComplete = new AutoComplete(fullSequence, autoCompleteOptions);
|
|
1184
|
+
|
|
1185
|
+
const text = "start=";
|
|
1186
|
+
const results = autoComplete.suggestFor(text);
|
|
1187
|
+
|
|
1188
|
+
const expectedOptions:ExpectedOption[] = [
|
|
1189
|
+
{ text: "=A", startIndex: 6, subElements: [{
|
|
1190
|
+
text: "=",
|
|
1191
|
+
pattern: separator.name
|
|
1192
|
+
},{
|
|
1193
|
+
text: "A",
|
|
1194
|
+
pattern: aLiteral.name
|
|
1195
|
+
}] },
|
|
1196
|
+
{ text: "=B", startIndex: 6, subElements: [{
|
|
1197
|
+
text: "=",
|
|
1198
|
+
pattern: separator.name
|
|
1199
|
+
},{
|
|
1200
|
+
text: "B",
|
|
1201
|
+
pattern: bLiteral.name
|
|
1202
|
+
}] },
|
|
1203
|
+
{ text: "=C", startIndex: 6, subElements: [{
|
|
1204
|
+
text: "=",
|
|
1205
|
+
pattern: separator.name
|
|
1206
|
+
},{
|
|
1207
|
+
text: "C",
|
|
1208
|
+
pattern: cLiteral.name
|
|
1209
|
+
}] },
|
|
1210
|
+
];
|
|
1211
|
+
|
|
1212
|
+
optionsMatchExpected(results.options, expectedOptions);
|
|
1213
|
+
|
|
1214
|
+
});
|
|
1215
|
+
|
|
1216
|
+
test("greedy root node", () => {
|
|
1217
|
+
const separator = new Literal("separator", '==');
|
|
1218
|
+
|
|
1219
|
+
const aLiteral = new Literal("letter", "A");
|
|
1220
|
+
const bLiteral = new Literal("letter", "B");
|
|
1221
|
+
const cLiteral = new Literal("letter", "C");
|
|
1222
|
+
const abcOptions = new Options("letters-options", [aLiteral, bLiteral, cLiteral]);
|
|
1223
|
+
|
|
1224
|
+
const fullSequence = new Sequence("full-sequence", [separator, abcOptions]);
|
|
1225
|
+
|
|
1226
|
+
const autoCompleteOptions: AutoCompleteOptions = {
|
|
1227
|
+
greedyPatternNames: ["separator"],
|
|
1228
|
+
};
|
|
1229
|
+
const autoComplete = new AutoComplete(fullSequence, autoCompleteOptions);
|
|
1230
|
+
|
|
1231
|
+
const text = "";
|
|
1232
|
+
const results = autoComplete.suggestFor(text);
|
|
1233
|
+
|
|
1234
|
+
const expectedOptions:ExpectedOption[] = [
|
|
1235
|
+
{ text: "==A", startIndex: 0, subElements: [{
|
|
1236
|
+
text: "==",
|
|
1237
|
+
pattern: separator.name
|
|
1238
|
+
},{
|
|
1239
|
+
text: "A",
|
|
1240
|
+
pattern: aLiteral.name
|
|
1241
|
+
}] },
|
|
1242
|
+
{ text: "==B", startIndex: 0, subElements: [{
|
|
1243
|
+
text: "==",
|
|
1244
|
+
pattern: separator.name
|
|
1245
|
+
},{
|
|
1246
|
+
text: "B",
|
|
1247
|
+
pattern: bLiteral.name
|
|
1248
|
+
}] },
|
|
1249
|
+
{ text: "==C", startIndex: 0, subElements: [{
|
|
1250
|
+
text: "==",
|
|
1251
|
+
pattern: separator.name
|
|
1252
|
+
},{
|
|
1253
|
+
text: "C",
|
|
1254
|
+
pattern: cLiteral.name
|
|
1255
|
+
}] },
|
|
1256
|
+
];
|
|
1257
|
+
|
|
1258
|
+
optionsMatchExpected(results.options, expectedOptions);
|
|
1259
|
+
});
|
|
1260
|
+
|
|
1261
|
+
|
|
1262
|
+
|
|
790
1263
|
});
|
|
791
1264
|
|
|
792
1265
|
|