clarity-pattern-parser 11.3.4 → 11.3.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clarity-pattern-parser",
3
- "version": "11.3.4",
3
+ "version": "11.3.5",
4
4
  "description": "Parsing Library for Typescript and Javascript.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.esm.js",
@@ -1,9 +1,4 @@
1
- import { Context } from "../patterns/Context";
2
- import { Expression } from "../patterns/Expression";
3
- import { Literal } from "../patterns/Literal";
4
1
  import { Pattern } from "../patterns/Pattern";
5
- import { Regex } from "../patterns/Regex";
6
- import { Repeat } from "../patterns/Repeat";
7
2
  import { IVisitor } from "./ivisitor";
8
3
 
9
4
  export class Generator {
@@ -236,6 +236,39 @@ describe("AutoComplete", () => {
236
236
 
237
237
  });
238
238
 
239
+
240
+ test("Options AutoComplete on Root Pattern", () => {
241
+
242
+ const jack = new Literal("first-name", "Jack");
243
+ const john = new Literal("first-name", "John");
244
+
245
+ const names = new Options('names', [jack,john]);
246
+ const divider = new Literal('divider', ', ');
247
+ const repeat = new Repeat('name-list', names, { divider, trimDivider: true });
248
+
249
+ const text = ''
250
+
251
+ const autoCompleteOptions: AutoCompleteOptions = {
252
+ customTokens: {
253
+ 'first-name': ["James"]
254
+ }
255
+ };
256
+ const autoComplete = new AutoComplete(repeat,autoCompleteOptions);
257
+
258
+ const suggestion = autoComplete.suggestFor(text)
259
+
260
+ console.log('suggestion: ',suggestion)
261
+
262
+ const expectedOptions = [
263
+ { text: "Jack", startIndex: 0 },
264
+ { text: "John", startIndex: 0 },
265
+ { text: "James", startIndex: 0 },
266
+ ];
267
+
268
+ expect(suggestion.options).toEqual(expectedOptions)
269
+
270
+ })
271
+
239
272
  test("Options AutoComplete On Leaf Pattern", () => {
240
273
  const autoCompleteOptions: AutoCompleteOptions = {
241
274
  greedyPatternNames: ["space"],
@@ -648,4 +681,33 @@ describe("AutoComplete", () => {
648
681
  }
649
682
  ]);
650
683
  });
651
- });
684
+
685
+
686
+ test("Calling AutoComplete -> _getAllOptions Does not mutate customTokensMap", () => {
687
+
688
+ const jediLuke = new Literal(`jedi`, 'luke');
689
+ const names = new Options('names', [jediLuke]);
690
+ const divider = new Literal('divider', ', ');
691
+ const pattern = new Repeat('name-list', names, { divider, trimDivider: true });
692
+
693
+ const customTokensMap:Record<string, string[]> = {
694
+ 'jedi': ["leia"]
695
+ }
696
+
697
+ const copiedCustomTokensMap:Record<string, string[]> = JSON.parse(JSON.stringify(customTokensMap));
698
+
699
+ const autoCompleteOptions: AutoCompleteOptions = {
700
+ greedyPatternNames:['jedi'],
701
+ customTokens: customTokensMap
702
+ };
703
+ const autoComplete = new AutoComplete(pattern,autoCompleteOptions);
704
+
705
+ // provide a non-empty input to trigger the logic flow that hits _getAllOptions
706
+ autoComplete.suggestFor('l')
707
+
708
+ expect(customTokensMap).toEqual(copiedCustomTokensMap)
709
+ })
710
+
711
+ });
712
+
713
+
@@ -159,7 +159,7 @@ export class AutoComplete {
159
159
 
160
160
  private _createSuggestionsFromRoot(): SuggestionOption[] {
161
161
  const suggestions: SuggestionOption[] = [];
162
- const tokens = this._pattern.getTokens();
162
+ const tokens = [...this._pattern.getTokens(),... this._getTokensForPattern(this._pattern)];
163
163
 
164
164
  for (const token of tokens) {
165
165
  if (suggestions.findIndex(s => s.text === token) === -1) {
@@ -197,21 +197,21 @@ export class AutoComplete {
197
197
 
198
198
  if (this._options.greedyPatternNames != null && this._options.greedyPatternNames.includes(pattern.name)) {
199
199
  const nextPatterns = pattern.getNextPatterns();
200
- const tokens: string[] = [];
201
-
202
200
  const nextPatternTokens = nextPatterns.reduce((acc: string[], pattern) => {
203
201
  acc.push(...this._getTokensForPattern(pattern));
204
202
  return acc;
205
203
  }, []);
206
-
207
- for (let token of augmentedTokens) {
208
- for (let nextPatternToken of nextPatternTokens) {
209
- tokens.push(token + nextPatternToken);
204
+ // using set to prevent duplicates
205
+ const tokens = new Set<string>();
206
+
207
+ for (const token of augmentedTokens) {
208
+ for (const nextPatternToken of nextPatternTokens) {
209
+ tokens.add(token + nextPatternToken);
210
210
  }
211
211
  }
212
212
 
213
- return tokens;
214
- } else {
213
+ return [...tokens]
214
+ } else {
215
215
  return augmentedTokens;
216
216
  }
217
217
  }
@@ -219,14 +219,22 @@ export class AutoComplete {
219
219
  private _getAugmentedTokens(pattern: Pattern) {
220
220
  const customTokensMap: any = this._options.customTokens || {};
221
221
  const leafPatterns = pattern.getPatterns();
222
- const tokens: string[] = customTokensMap[pattern.name] || [];
223
222
 
224
- leafPatterns.forEach(p => {
225
- const augmentedTokens = customTokensMap[p.name] || [];
226
- tokens.push(...p.getTokens(), ...augmentedTokens);
227
- });
223
+ /** Using Set to
224
+ * - prevent duplicates
225
+ * - prevent mutation of original customTokensMap
226
+ */
227
+ const customTokensForPattern = new Set<string>(customTokensMap[pattern.name] ?? []);
228
+
229
+ for (const lp of leafPatterns) {
230
+ const augmentedTokens = customTokensMap[lp.name] ?? [];
231
+ const lpsCombinedTokens = [...lp.getTokens(), ...augmentedTokens];
228
232
 
229
- return tokens;
233
+ for (const token of lpsCombinedTokens) {
234
+ customTokensForPattern.add(token);
235
+ }
236
+ }
237
+ return [...customTokensForPattern];
230
238
  }
231
239
 
232
240
  private _createSuggestions(lastIndex: number, tokens: string[]): SuggestionOption[] {