clarity-pattern-parser 5.0.0 → 6.0.2
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/README.md +328 -38
- package/TODO.md +63 -7
- package/dist/ast/Node.d.ts +8 -2
- package/dist/index.browser.js +520 -205
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.esm.js +519 -206
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +520 -205
- package/dist/index.js.map +1 -1
- package/dist/intellisense/AutoComplete.d.ts +34 -0
- package/dist/intellisense/Suggestion.d.ts +10 -0
- package/dist/intellisense/SuggestionOption.d.ts +4 -0
- package/dist/patterns/And.d.ts +8 -7
- package/dist/patterns/Cursor.d.ts +6 -4
- package/dist/patterns/CursorHistory.d.ts +2 -2
- package/dist/patterns/Literal.d.ts +8 -8
- package/dist/patterns/Not.d.ts +9 -5
- package/dist/patterns/Or.d.ts +8 -5
- package/dist/patterns/Pattern.d.ts +8 -4
- package/dist/patterns/Reference.d.ts +11 -7
- package/dist/patterns/Regex.d.ts +8 -8
- package/dist/patterns/Repeat.d.ts +8 -7
- package/package.json +1 -1
- package/src/ast/Node.test.ts +116 -0
- package/src/ast/Node.ts +71 -5
- package/src/index.ts +14 -3
- package/src/intellisense/AutoComplete.test.ts +168 -23
- package/src/intellisense/AutoComplete.ts +102 -21
- package/src/intellisense/Suggestion.ts +3 -4
- package/src/intellisense/javascript/Javascript.test.ts +86 -62
- package/src/intellisense/javascript/{expressionStatement.ts → assignment.ts} +7 -8
- package/src/intellisense/javascript/escapedCharacter.ts +0 -1
- package/src/intellisense/javascript/exponent.ts +0 -2
- package/src/intellisense/javascript/expression.ts +44 -26
- package/src/intellisense/javascript/fraction.ts +0 -2
- package/src/intellisense/javascript/infixOperator.ts +6 -2
- package/src/intellisense/javascript/keywords.ts +3 -0
- package/src/intellisense/javascript/objectAccess.ts +9 -0
- package/src/intellisense/javascript/objectLiteral.ts +3 -3
- package/src/intellisense/javascript/propertyAccess.ts +8 -3
- package/src/intellisense/javascript/stringLiteral.ts +16 -8
- package/src/patterns/And.test.ts +74 -50
- package/src/patterns/And.ts +72 -36
- package/src/patterns/Cursor.ts +17 -14
- package/src/patterns/CursorHistory.ts +8 -8
- package/src/patterns/Literal.test.ts +79 -38
- package/src/patterns/Literal.ts +34 -41
- package/src/patterns/Not.test.ts +99 -8
- package/src/patterns/Not.ts +58 -14
- package/src/patterns/Or.test.ts +128 -13
- package/src/patterns/Or.ts +46 -13
- package/src/patterns/Pattern.ts +8 -4
- package/src/patterns/Reference.test.ts +127 -28
- package/src/patterns/Reference.ts +62 -32
- package/src/patterns/Regex.test.ts +76 -35
- package/src/patterns/Regex.ts +35 -43
- package/src/patterns/Repeat.test.ts +72 -41
- package/src/patterns/Repeat.ts +55 -38
- package/src/patterns/getNextPattern.test.ts +0 -39
- package/src/patterns/getNextPattern.ts +0 -18
package/src/ast/Node.test.ts
CHANGED
|
@@ -15,6 +15,25 @@ describe("Node", () => {
|
|
|
15
15
|
expect(node.children.length).toBe(0);
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
+
test("Properties", () => {
|
|
19
|
+
const child = new Node("child", "child", 0, 0, undefined, "Content")
|
|
20
|
+
const parent = new Node("parent", "parent", 0, 0, [
|
|
21
|
+
child,
|
|
22
|
+
]);
|
|
23
|
+
|
|
24
|
+
expect(parent.hasChildren).toBeTruthy();
|
|
25
|
+
expect(child.parent).toBe(parent);
|
|
26
|
+
expect(parent.children[0]).toBe(child);
|
|
27
|
+
expect(child.type).toBe("child");
|
|
28
|
+
expect(parent.value).toBe("Content");
|
|
29
|
+
expect(child.value).toBe("Content");
|
|
30
|
+
expect(child.name).toBe("child");
|
|
31
|
+
expect(child.firstIndex).toBe(0);
|
|
32
|
+
expect(child.lastIndex).toBe(0);
|
|
33
|
+
expect(child.startIndex).toBe(0);
|
|
34
|
+
expect(child.endIndex).toBe(1);
|
|
35
|
+
});
|
|
36
|
+
|
|
18
37
|
test("Create Tree", () => {
|
|
19
38
|
const child = new Node("child", "child", 0, 0, [], "Child");
|
|
20
39
|
const parent = new Node("parent", "parent", 0, 0, [child]);
|
|
@@ -164,6 +183,56 @@ describe("Node", () => {
|
|
|
164
183
|
expect(b.value).toBe("B");
|
|
165
184
|
});
|
|
166
185
|
|
|
186
|
+
test("Next Sibling", () => {
|
|
187
|
+
const a = new Node("a", "a", 0, 0, [], "A");
|
|
188
|
+
const b = new Node("b", "b", 0, 0, [], "B");
|
|
189
|
+
new Node("parent", "parent", 0, 0, [a, b]);
|
|
190
|
+
|
|
191
|
+
const nextSibling = a.nextSibling()
|
|
192
|
+
|
|
193
|
+
expect(nextSibling).toBe(b);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test("Next Sibling (No Parent)", () => {
|
|
197
|
+
const a = new Node("a", "a", 0, 0, [], "A");
|
|
198
|
+
|
|
199
|
+
const nextSibling = a.nextSibling()
|
|
200
|
+
expect(nextSibling).toBeNull;
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test("Next Sibling (Last Child)", () => {
|
|
204
|
+
const a = new Node("a", "a", 0, 0, [], "A");
|
|
205
|
+
const b = new Node("b", "b", 0, 0, [], "B");
|
|
206
|
+
new Node("parent", "parent", 0, 0, [a, b]);
|
|
207
|
+
|
|
208
|
+
const nextSibling = b.nextSibling()
|
|
209
|
+
expect(nextSibling).toBeNull;
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
test("Previous Sibling", () => {
|
|
213
|
+
const a = new Node("a", "a", 0, 0, [], "A");
|
|
214
|
+
const b = new Node("b", "b", 0, 0, [], "B");
|
|
215
|
+
new Node("parent", "parent", 0, 0, [a, b]);
|
|
216
|
+
|
|
217
|
+
const previousSibling = b.previousSibling()
|
|
218
|
+
|
|
219
|
+
expect(previousSibling).toBe(a);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
test("Previous Sibling (No Parent)", () => {
|
|
223
|
+
const a = new Node("a", "a", 0, 0, [], "A");
|
|
224
|
+
const previousSibling = a.previousSibling()
|
|
225
|
+
expect(previousSibling).toBeNull();
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
test("Previous Sibling (First Child)", () => {
|
|
229
|
+
const a = new Node("a", "a", 0, 0, [], "A");
|
|
230
|
+
const b = new Node("b", "b", 0, 0, [], "B");
|
|
231
|
+
new Node("parent", "parent", 0, 0, [a, b]);
|
|
232
|
+
|
|
233
|
+
const previousSibling = a.previousSibling()
|
|
234
|
+
expect(previousSibling).toBeNull;
|
|
235
|
+
});
|
|
167
236
|
|
|
168
237
|
test("Find", () => {
|
|
169
238
|
const a = new Node("a", "a", 0, 0, [], "A");
|
|
@@ -251,4 +320,51 @@ describe("Node", () => {
|
|
|
251
320
|
expect(result).toEqual(expected)
|
|
252
321
|
});
|
|
253
322
|
|
|
323
|
+
test("Reduce", () => {
|
|
324
|
+
const parent = new Node("parent", "parent", 0, 6, [
|
|
325
|
+
new Node("child", "child", 0, 6, undefined, "Content")
|
|
326
|
+
]);
|
|
327
|
+
|
|
328
|
+
parent.reduce();
|
|
329
|
+
|
|
330
|
+
expect(parent.hasChildren).toBeFalsy();
|
|
331
|
+
expect(parent.value).toBe("Content")
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
test("Flatten", () => {
|
|
335
|
+
const a = new Node("a", "a", 0, 0, [], "A");
|
|
336
|
+
const b = new Node("b", "b", 1, 1, [], "B");
|
|
337
|
+
const c = new Node("c", "c", 2, 2, [], "C");
|
|
338
|
+
|
|
339
|
+
const parent = new Node("parent", "parent", 0, 1, [
|
|
340
|
+
a,
|
|
341
|
+
b,
|
|
342
|
+
]);
|
|
343
|
+
|
|
344
|
+
const grandParent = new Node("grand-parent", "grand-parent", 0, 2, [
|
|
345
|
+
parent,
|
|
346
|
+
c,
|
|
347
|
+
]);
|
|
348
|
+
|
|
349
|
+
const nodes = grandParent.flatten();
|
|
350
|
+
const expected = [a, b, c];
|
|
351
|
+
|
|
352
|
+
expect(nodes).toEqual(expected)
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
test("Find Ancester", () => {
|
|
356
|
+
const child = new Node("child", "child", 0, 0, []);
|
|
357
|
+
const parent = new Node("parent", "parent", 0, 0, [child]);
|
|
358
|
+
const grandParent = new Node("grand-parent", "grand-parent", 0, 0, [parent]);
|
|
359
|
+
const result = child.findAncester(p => p.name === "grand-parent")
|
|
360
|
+
|
|
361
|
+
expect(result).toBe(grandParent)
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
test("Find Ancester Without Parent", () => {
|
|
365
|
+
const child = new Node("child", "child", 0, 0, []);
|
|
366
|
+
const result = child.findAncester(p => p.name === "parent")
|
|
367
|
+
expect(result).toBeNull()
|
|
368
|
+
});
|
|
369
|
+
|
|
254
370
|
});
|
package/src/ast/Node.ts
CHANGED
|
@@ -50,6 +50,10 @@ export class Node {
|
|
|
50
50
|
return this._children;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
get hasChildren(): boolean {
|
|
54
|
+
return this._children.length > 0;
|
|
55
|
+
}
|
|
56
|
+
|
|
53
57
|
get value() {
|
|
54
58
|
return this.toString();
|
|
55
59
|
}
|
|
@@ -120,25 +124,69 @@ export class Node {
|
|
|
120
124
|
spliceChildren(index: number, deleteCount: number, ...items: Node[]) {
|
|
121
125
|
const removedItems = this._children.splice(index, deleteCount, ...items);
|
|
122
126
|
|
|
123
|
-
items.forEach(i => i._parent = this);
|
|
124
127
|
removedItems.forEach(i => i._parent = null);
|
|
128
|
+
items.forEach(i => i._parent = this);
|
|
125
129
|
|
|
126
130
|
return removedItems;
|
|
127
131
|
}
|
|
128
132
|
|
|
129
|
-
|
|
130
|
-
|
|
133
|
+
nextSibling() {
|
|
134
|
+
if (this._parent == null) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const children = this._parent._children;
|
|
139
|
+
const index = children.indexOf(this);
|
|
140
|
+
|
|
141
|
+
if (index > -1 && index < children.length - 1) {
|
|
142
|
+
return children[index + 1]
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return null
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
previousSibling() {
|
|
149
|
+
if (this._parent == null) {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const children = this._parent._children;
|
|
154
|
+
const index = children.indexOf(this);
|
|
155
|
+
|
|
156
|
+
if (index > -1 && index > 0) {
|
|
157
|
+
return children[index - 1]
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return null
|
|
131
161
|
}
|
|
132
162
|
|
|
133
|
-
|
|
163
|
+
find(predicate: (node: Node) => boolean): Node | null {
|
|
164
|
+
return this.findAll(predicate)[0] || null
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
findAll(predicate: (node: Node) => boolean): Node[] {
|
|
134
168
|
const matches: Node[] = [];
|
|
135
169
|
this.walkUp(n => {
|
|
136
|
-
if (
|
|
170
|
+
if (predicate(n)) { matches.push(n); }
|
|
137
171
|
})
|
|
138
172
|
|
|
139
173
|
return matches;
|
|
140
174
|
}
|
|
141
175
|
|
|
176
|
+
findAncester(predicate: (node: Node) => boolean){
|
|
177
|
+
let parent = this._parent;
|
|
178
|
+
|
|
179
|
+
while(parent != null){
|
|
180
|
+
if (predicate(parent)){
|
|
181
|
+
return parent;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
parent = parent._parent;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
|
|
142
190
|
walkUp(callback: (node: Node) => void) {
|
|
143
191
|
this.children.forEach(c => c.walkUp(callback))
|
|
144
192
|
callback(this);
|
|
@@ -149,6 +197,24 @@ export class Node {
|
|
|
149
197
|
this.children.forEach(c => c.walkDown(callback))
|
|
150
198
|
}
|
|
151
199
|
|
|
200
|
+
flatten(){
|
|
201
|
+
const nodes: Node[] = [];
|
|
202
|
+
|
|
203
|
+
this.walkDown((node: Node)=>{
|
|
204
|
+
if (!node.hasChildren){
|
|
205
|
+
nodes.push(node);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
return nodes;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
reduce() {
|
|
213
|
+
const value = this.toString();
|
|
214
|
+
this.removeAllChildren();
|
|
215
|
+
this._value = value;
|
|
216
|
+
}
|
|
217
|
+
|
|
152
218
|
clone(): Node {
|
|
153
219
|
return new Node(
|
|
154
220
|
this._type,
|
package/src/index.ts
CHANGED
|
@@ -9,17 +9,28 @@ import { Repeat } from "./patterns/Repeat";
|
|
|
9
9
|
import { ParseError } from "./patterns/ParseError";
|
|
10
10
|
import { Pattern } from "./patterns/Pattern";
|
|
11
11
|
import { Reference } from "./patterns/Reference";
|
|
12
|
+
import { AutoComplete } from './intellisense/AutoComplete';
|
|
13
|
+
import { CursorHistory, Match } from "./patterns/CursorHistory";
|
|
14
|
+
import { ParseResult } from "./patterns/ParseResult";
|
|
15
|
+
import { Suggestion } from "./intellisense/Suggestion";
|
|
16
|
+
import { SuggestionOption } from "./intellisense/SuggestionOption";
|
|
12
17
|
|
|
13
18
|
export {
|
|
14
19
|
Node,
|
|
15
|
-
|
|
16
|
-
|
|
20
|
+
AutoComplete,
|
|
21
|
+
Suggestion,
|
|
22
|
+
SuggestionOption,
|
|
17
23
|
And,
|
|
24
|
+
Cursor,
|
|
25
|
+
CursorHistory,
|
|
26
|
+
Match,
|
|
18
27
|
Literal,
|
|
19
28
|
Not,
|
|
20
29
|
Or,
|
|
21
|
-
Repeat,
|
|
22
30
|
ParseError,
|
|
31
|
+
ParseResult,
|
|
23
32
|
Pattern,
|
|
24
33
|
Reference,
|
|
34
|
+
Regex,
|
|
35
|
+
Repeat,
|
|
25
36
|
};
|
|
@@ -2,17 +2,19 @@ import { And } from "../patterns/And";
|
|
|
2
2
|
import { findPattern } from "../patterns/findPattern";
|
|
3
3
|
import { Literal } from "../patterns/Literal";
|
|
4
4
|
import { Or } from "../patterns/Or";
|
|
5
|
-
import {
|
|
5
|
+
import { Regex } from "../patterns/Regex";
|
|
6
|
+
import { Repeat } from "../patterns/Repeat";
|
|
7
|
+
import { AutoComplete, AutoCompleteOptions } from "./AutoComplete";
|
|
6
8
|
|
|
7
9
|
describe("AutoComplete", () => {
|
|
8
10
|
test("No Text", () => {
|
|
9
11
|
const name = new Literal("name", "Name");
|
|
10
12
|
const autoComplete = new AutoComplete(name);
|
|
11
|
-
let result = autoComplete.
|
|
13
|
+
let result = autoComplete.suggestFor("");
|
|
12
14
|
|
|
13
15
|
expect(result.options[0].text).toBe("Name");
|
|
14
16
|
expect(result.options[0].startIndex).toBe(0);
|
|
15
|
-
expect(result.
|
|
17
|
+
expect(result.errorAtIndex).toBe(0);
|
|
16
18
|
expect(result.isComplete).toBeFalsy();
|
|
17
19
|
});
|
|
18
20
|
|
|
@@ -21,52 +23,195 @@ describe("AutoComplete", () => {
|
|
|
21
23
|
const space = new Literal("space", " ");
|
|
22
24
|
const doe = new Literal("doe", "Doe");
|
|
23
25
|
const smith = new Literal("smith", "Smith");
|
|
26
|
+
const name = new And("name", [john, space, new Or("last-name", [smith, doe])]);
|
|
27
|
+
|
|
28
|
+
const autoComplete = new AutoComplete(name);
|
|
29
|
+
const result = autoComplete.suggestFor("John Doe");
|
|
24
30
|
|
|
25
|
-
|
|
31
|
+
expect(result.ast?.value).toBe("John Doe");
|
|
32
|
+
expect(result.options.length).toBe(0);
|
|
33
|
+
expect(result.errorAtIndex).toBeNull();
|
|
34
|
+
expect(result.isComplete).toBeTruthy();
|
|
35
|
+
expect(result.cursor).not.toBeNull();
|
|
36
|
+
});
|
|
26
37
|
|
|
38
|
+
test("More Than One Option", () => {
|
|
39
|
+
const john = new Literal("john", "John");
|
|
40
|
+
const space = new Literal("space", " ");
|
|
41
|
+
const doe = new Literal("doe", "Doe");
|
|
42
|
+
const smith = new Literal("smith", "Smith");
|
|
27
43
|
const name = new And("name", [john, space, new Or("last-name", [smith, doe])]);
|
|
28
44
|
|
|
45
|
+
const text = "John "
|
|
29
46
|
const autoComplete = new AutoComplete(name);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
47
|
+
const result = autoComplete.suggestFor(text);
|
|
48
|
+
const expectedOptions = [{
|
|
49
|
+
text: "Doe",
|
|
50
|
+
startIndex: 5
|
|
51
|
+
}, {
|
|
52
|
+
text: "Smith",
|
|
53
|
+
startIndex: 5
|
|
54
|
+
}];
|
|
55
|
+
|
|
56
|
+
expect(result.ast).toBeNull();
|
|
57
|
+
expect(result.options).toEqual(expectedOptions);
|
|
58
|
+
expect(result.errorAtIndex).toBe(text.length)
|
|
38
59
|
expect(result.isComplete).toBeFalsy();
|
|
60
|
+
expect(result.cursor).not.toBeNull();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("Full Pattern Match With Root Repeat", () => {
|
|
64
|
+
const john = new Literal("john", "John");
|
|
65
|
+
const space = new Literal("space", " ");
|
|
66
|
+
const doe = new Literal("doe", "Doe");
|
|
67
|
+
const smith = new Literal("smith", "Smith");
|
|
68
|
+
const name = new And("name", [john, space, new Or("last-name", [smith, doe])]);
|
|
69
|
+
const divider = new Regex("divider", "\\s+,\\s+");
|
|
70
|
+
|
|
71
|
+
divider.setTokens([", "])
|
|
72
|
+
|
|
73
|
+
const text = "John Doe";
|
|
74
|
+
const autoComplete = new AutoComplete(new Repeat("last-names", name, divider));
|
|
75
|
+
const result = autoComplete.suggestFor(text);
|
|
76
|
+
const expectedOptions = [{
|
|
77
|
+
text: ", ",
|
|
78
|
+
startIndex: 8
|
|
79
|
+
}];
|
|
80
|
+
|
|
81
|
+
expect(result.ast?.value).toBe(text);
|
|
82
|
+
expect(result.options).toEqual(expectedOptions);
|
|
83
|
+
expect(result.errorAtIndex).toBeNull()
|
|
84
|
+
expect(result.isComplete).toBeTruthy();
|
|
85
|
+
expect(result.cursor).not.toBeNull();
|
|
39
86
|
});
|
|
40
87
|
|
|
41
88
|
test("Partial", () => {
|
|
42
89
|
const name = new Literal("name", "Name");
|
|
43
90
|
const autoComplete = new AutoComplete(name);
|
|
44
|
-
|
|
91
|
+
const result = autoComplete.suggestFor("Na");
|
|
92
|
+
const expectedOptions = [{
|
|
93
|
+
text: "me",
|
|
94
|
+
startIndex: 2
|
|
95
|
+
}];
|
|
45
96
|
|
|
46
|
-
expect(result.
|
|
47
|
-
expect(result.options
|
|
48
|
-
expect(result.
|
|
97
|
+
expect(result.ast).toBeNull();
|
|
98
|
+
expect(result.options).toEqual(expectedOptions);
|
|
99
|
+
expect(result.errorAtIndex).toBe(2);
|
|
49
100
|
expect(result.isComplete).toBeFalsy();
|
|
101
|
+
expect(result.cursor).not.toBeNull();
|
|
50
102
|
});
|
|
51
103
|
|
|
52
104
|
test("Partial Match With Bad Characters", () => {
|
|
53
105
|
const name = new Literal("name", "Name");
|
|
54
106
|
const autoComplete = new AutoComplete(name);
|
|
55
|
-
|
|
107
|
+
const result = autoComplete.suggestFor("Ni");
|
|
108
|
+
|
|
109
|
+
const expectedOptions = [{
|
|
110
|
+
text: "ame",
|
|
111
|
+
startIndex: 1
|
|
112
|
+
}];
|
|
56
113
|
|
|
57
|
-
expect(result.
|
|
58
|
-
expect(result.options
|
|
59
|
-
expect(result.
|
|
114
|
+
expect(result.ast).toBeNull();
|
|
115
|
+
expect(result.options).toEqual(expectedOptions);
|
|
116
|
+
expect(result.errorAtIndex).toBe(1);
|
|
60
117
|
expect(result.isComplete).toBeFalsy();
|
|
118
|
+
expect(result.cursor).not.toBeNull();
|
|
61
119
|
});
|
|
62
120
|
|
|
63
121
|
test("Complete", () => {
|
|
64
122
|
const name = new Literal("name", "Name");
|
|
65
123
|
const autoComplete = new AutoComplete(name);
|
|
66
|
-
|
|
124
|
+
const text = "Name"
|
|
125
|
+
const result = autoComplete.suggestFor(text);
|
|
67
126
|
|
|
68
|
-
expect(result.
|
|
69
|
-
expect(result.
|
|
127
|
+
expect(result.ast?.value).toBe(text);
|
|
128
|
+
expect(result.options).toEqual([]);
|
|
129
|
+
expect(result.errorAtIndex).toBeNull();
|
|
70
130
|
expect(result.isComplete).toBeTruthy();
|
|
131
|
+
expect(result.cursor).not.toBeNull();
|
|
71
132
|
});
|
|
133
|
+
|
|
134
|
+
test("Options AutoComplete on Composing Pattern", () => {
|
|
135
|
+
const autoCompleteOptions: AutoCompleteOptions = {
|
|
136
|
+
greedyPatternNames: ["space"],
|
|
137
|
+
customTokens: {
|
|
138
|
+
"last-name": ["Sparrow"]
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const jack = new Literal("jack", "Jack");
|
|
143
|
+
const john = new Literal("john", "John");
|
|
144
|
+
const space = new Literal("space", " ");
|
|
145
|
+
const doe = new Literal("doe", "Doe");
|
|
146
|
+
const smith = new Literal("smith", "Smith");
|
|
147
|
+
const firstName = new Or("first-name", [jack, john]);
|
|
148
|
+
const lastName = new Or("last-name", [doe, smith]);
|
|
149
|
+
const fullName = new And("full-name", [firstName, space, lastName]);
|
|
150
|
+
|
|
151
|
+
const text = "Jack";
|
|
152
|
+
const autoComplete = new AutoComplete(fullName, autoCompleteOptions);
|
|
153
|
+
const { options, ast, errorAtIndex } = autoComplete.suggestFor(text);
|
|
154
|
+
|
|
155
|
+
const expectedOptions = [
|
|
156
|
+
{ text: " Doe", startIndex: 4 },
|
|
157
|
+
{ text: " Smith", startIndex: 4 },
|
|
158
|
+
{ text: " Sparrow", startIndex: 4 },
|
|
159
|
+
];
|
|
160
|
+
|
|
161
|
+
const results = expectedOptions.map(o => text.slice(0, o.startIndex) + o.text);
|
|
162
|
+
const expectedResults = [
|
|
163
|
+
"Jack Doe",
|
|
164
|
+
"Jack Smith",
|
|
165
|
+
"Jack Sparrow",
|
|
166
|
+
]
|
|
167
|
+
|
|
168
|
+
expect(ast).toBeNull();
|
|
169
|
+
expect(errorAtIndex).toBe(4);
|
|
170
|
+
expect(options).toEqual(expectedOptions);
|
|
171
|
+
expect(results).toEqual(expectedResults);
|
|
172
|
+
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
test("Options AutoComplete On Leaf Pattern", () => {
|
|
176
|
+
const autoCompleteOptions: AutoCompleteOptions = {
|
|
177
|
+
greedyPatternNames: ["space"],
|
|
178
|
+
customTokens: {
|
|
179
|
+
"space": [" "]
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const jack = new Literal("jack", "Jack");
|
|
184
|
+
const john = new Literal("john", "John");
|
|
185
|
+
const space = new Literal("space", " ");
|
|
186
|
+
const doe = new Literal("doe", "Doe");
|
|
187
|
+
const smith = new Literal("smith", "Smith");
|
|
188
|
+
const firstName = new Or("first-name", [jack, john]);
|
|
189
|
+
const lastName = new Or("last-name", [doe, smith]);
|
|
190
|
+
const fullName = new And("full-name", [firstName, space, lastName]);
|
|
191
|
+
|
|
192
|
+
const text = "Jack";
|
|
193
|
+
const autoComplete = new AutoComplete(fullName, autoCompleteOptions);
|
|
194
|
+
const { options, ast, errorAtIndex } = autoComplete.suggestFor(text);
|
|
195
|
+
const expectedOptions = [
|
|
196
|
+
{ text: " Doe", startIndex: 4 },
|
|
197
|
+
{ text: " Smith", startIndex: 4 },
|
|
198
|
+
{ text: " Doe", startIndex: 4 },
|
|
199
|
+
{ text: " Smith", startIndex: 4 },
|
|
200
|
+
];
|
|
201
|
+
|
|
202
|
+
const results = expectedOptions.map(o => text.slice(0, o.startIndex) + o.text);
|
|
203
|
+
const expectedResults = [
|
|
204
|
+
"Jack Doe",
|
|
205
|
+
"Jack Smith",
|
|
206
|
+
"Jack Doe",
|
|
207
|
+
"Jack Smith",
|
|
208
|
+
]
|
|
209
|
+
|
|
210
|
+
expect(ast).toBeNull();
|
|
211
|
+
expect(errorAtIndex).toBe(4);
|
|
212
|
+
expect(options).toEqual(expectedOptions);
|
|
213
|
+
expect(results).toEqual(expectedResults)
|
|
214
|
+
|
|
215
|
+
});
|
|
216
|
+
|
|
72
217
|
});
|