clarity-pattern-parser 3.0.15 → 4.0.0

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.
Files changed (168) hide show
  1. package/README.md +0 -191
  2. package/dist/ast/Node.d.ts +4 -5
  3. package/dist/index.browser.js +476 -731
  4. package/dist/index.browser.js.map +1 -1
  5. package/dist/index.d.ts +10 -18
  6. package/dist/index.esm.js +469 -716
  7. package/dist/index.esm.js.map +1 -1
  8. package/dist/index.js +476 -731
  9. package/dist/index.js.map +1 -1
  10. package/dist/patterns/And.d.ts +24 -0
  11. package/dist/patterns/Literal.d.ts +19 -0
  12. package/dist/patterns/LookAhead.d.ts +8 -0
  13. package/dist/patterns/Not.d.ts +11 -0
  14. package/dist/patterns/Or.d.ts +22 -0
  15. package/dist/patterns/Pattern.d.ts +6 -7
  16. package/dist/patterns/{RecursivePattern.d.ts → Recursive.d.ts} +4 -4
  17. package/dist/patterns/Reference.d.ts +14 -0
  18. package/dist/patterns/Regex.d.ts +21 -0
  19. package/dist/patterns/Repeat.d.ts +20 -0
  20. package/package.json +1 -1
  21. package/src/CursorHistory.ts +1 -1
  22. package/src/ast/Node.ts +20 -17
  23. package/src/ast/Visitor.ts +14 -18
  24. package/src/index.ts +17 -33
  25. package/src/patterns/And.ts +178 -0
  26. package/src/patterns/Literal.ts +91 -0
  27. package/src/patterns/LookAhead.ts +32 -0
  28. package/src/patterns/Not.ts +50 -0
  29. package/src/patterns/Or.ts +132 -0
  30. package/src/patterns/Pattern.ts +31 -47
  31. package/src/patterns/Recursive.ts +92 -0
  32. package/src/patterns/Reference.ts +127 -0
  33. package/src/patterns/Regex.ts +123 -0
  34. package/src/patterns/Repeat.ts +155 -0
  35. package/src/tests/{AndValue.test.ts → And.test.ts} +31 -41
  36. package/src/tests/CursorHistory.test.ts +6 -6
  37. package/src/tests/Cusor.test.ts +7 -10
  38. package/src/tests/Literal.test.ts +3 -5
  39. package/src/tests/LookAhead.test.ts +44 -0
  40. package/src/tests/Not.test.ts +51 -0
  41. package/src/tests/Or.test.ts +113 -0
  42. package/src/tests/Pattern.test.ts +41 -141
  43. package/src/tests/{RecursivePattern.test.ts → Recursive.test.ts} +10 -8
  44. package/src/tests/Reference.test.ts +16 -0
  45. package/src/tests/{RepeatValue.test.ts → Repeat.test.ts} +10 -42
  46. package/src/tests/TextSuggester.test.ts +20 -28
  47. package/src/tests/{NodeVisitor.test.ts → Visitor.test.ts} +42 -21
  48. package/src/tests/cssPatterns/cssValue.ts +2 -2
  49. package/src/tests/cssPatterns/divider.ts +2 -2
  50. package/src/tests/cssPatterns/hex.ts +2 -2
  51. package/src/tests/cssPatterns/method.ts +7 -9
  52. package/src/tests/cssPatterns/name.ts +2 -2
  53. package/src/tests/cssPatterns/number.ts +2 -2
  54. package/src/tests/cssPatterns/optionalSpaces.ts +1 -2
  55. package/src/tests/cssPatterns/spaces.ts +2 -2
  56. package/src/tests/cssPatterns/unit.ts +3 -3
  57. package/src/tests/cssPatterns/value.ts +2 -2
  58. package/src/tests/cssPatterns/values.ts +2 -2
  59. package/src/tests/htmlPatterns/element.ts +18 -33
  60. package/src/tests/javascriptPatterns/boolean.ts +2 -3
  61. package/src/tests/javascriptPatterns/json.ts +14 -24
  62. package/src/tests/javascriptPatterns/name.ts +3 -20
  63. package/src/tests/javascriptPatterns/number.ts +2 -2
  64. package/src/tests/javascriptPatterns/objectLiteral.ts +9 -16
  65. package/src/tests/javascriptPatterns/string.ts +26 -24
  66. package/src/tests/javascriptPatterns/unit.ts +3 -6
  67. package/src/tests/javascriptPatterns/whitespace.ts +8 -12
  68. package/src/tests/naturalLanguage/filter.ts +16 -33
  69. package/src/tests/patterns/sentence.ts +8 -8
  70. package/dist/Cursor.js +0 -105
  71. package/dist/Cursor.js.map +0 -1
  72. package/dist/CursorHistory.js +0 -104
  73. package/dist/CursorHistory.js.map +0 -1
  74. package/dist/Permutor.d.ts +0 -13
  75. package/dist/Permutor.js +0 -52
  76. package/dist/Permutor.js.map +0 -1
  77. package/dist/TextSuggester.js +0 -244
  78. package/dist/TextSuggester.js.map +0 -1
  79. package/dist/ast/CompositeNode.d.ts +0 -6
  80. package/dist/ast/CompositeNode.js +0 -17
  81. package/dist/ast/CompositeNode.js.map +0 -1
  82. package/dist/ast/Node.js +0 -16
  83. package/dist/ast/Node.js.map +0 -1
  84. package/dist/ast/NodeVisitor.d.ts +0 -31
  85. package/dist/ast/ValueNode.d.ts +0 -6
  86. package/dist/ast/ValueNode.js +0 -14
  87. package/dist/ast/ValueNode.js.map +0 -1
  88. package/dist/ast/Visitor.js +0 -209
  89. package/dist/ast/Visitor.js.map +0 -1
  90. package/dist/patterns/ParseError.js +0 -9
  91. package/dist/patterns/ParseError.js.map +0 -1
  92. package/dist/patterns/Pattern.js +0 -127
  93. package/dist/patterns/Pattern.js.map +0 -1
  94. package/dist/patterns/RecursivePattern.js +0 -65
  95. package/dist/patterns/RecursivePattern.js.map +0 -1
  96. package/dist/patterns/composite/AndComposite.d.ts +0 -22
  97. package/dist/patterns/composite/AndComposite.js +0 -117
  98. package/dist/patterns/composite/AndComposite.js.map +0 -1
  99. package/dist/patterns/composite/CompositePattern.d.ts +0 -4
  100. package/dist/patterns/composite/CompositePattern.js +0 -7
  101. package/dist/patterns/composite/CompositePattern.js.map +0 -1
  102. package/dist/patterns/composite/OptionalComposite.d.ts +0 -10
  103. package/dist/patterns/composite/OptionalComposite.js +0 -29
  104. package/dist/patterns/composite/OptionalComposite.js.map +0 -1
  105. package/dist/patterns/composite/OrComposite.d.ts +0 -16
  106. package/dist/patterns/composite/OrComposite.js +0 -69
  107. package/dist/patterns/composite/OrComposite.js.map +0 -1
  108. package/dist/patterns/composite/RepeatComposite.d.ts +0 -21
  109. package/dist/patterns/composite/RepeatComposite.js +0 -88
  110. package/dist/patterns/composite/RepeatComposite.js.map +0 -1
  111. package/dist/patterns/value/AndValue.d.ts +0 -21
  112. package/dist/patterns/value/AndValue.js +0 -118
  113. package/dist/patterns/value/AndValue.js.map +0 -1
  114. package/dist/patterns/value/AnyOfThese.d.ts +0 -18
  115. package/dist/patterns/value/AnyOfThese.js +0 -59
  116. package/dist/patterns/value/AnyOfThese.js.map +0 -1
  117. package/dist/patterns/value/Literal.d.ts +0 -20
  118. package/dist/patterns/value/Literal.js +0 -63
  119. package/dist/patterns/value/Literal.js.map +0 -1
  120. package/dist/patterns/value/NotValue.d.ts +0 -17
  121. package/dist/patterns/value/NotValue.js +0 -70
  122. package/dist/patterns/value/NotValue.js.map +0 -1
  123. package/dist/patterns/value/OptionalValue.d.ts +0 -9
  124. package/dist/patterns/value/OptionalValue.js +0 -32
  125. package/dist/patterns/value/OptionalValue.js.map +0 -1
  126. package/dist/patterns/value/OrValue.d.ts +0 -19
  127. package/dist/patterns/value/OrValue.js +0 -73
  128. package/dist/patterns/value/OrValue.js.map +0 -1
  129. package/dist/patterns/value/RegexValue.d.ts +0 -19
  130. package/dist/patterns/value/RegexValue.js +0 -69
  131. package/dist/patterns/value/RegexValue.js.map +0 -1
  132. package/dist/patterns/value/RepeatValue.d.ts +0 -19
  133. package/dist/patterns/value/RepeatValue.js +0 -89
  134. package/dist/patterns/value/RepeatValue.js.map +0 -1
  135. package/dist/patterns/value/ValuePattern.d.ts +0 -5
  136. package/dist/patterns/value/ValuePattern.js +0 -7
  137. package/dist/patterns/value/ValuePattern.js.map +0 -1
  138. package/src/Permutor.ts +0 -64
  139. package/src/ast/CompositeNode.ts +0 -26
  140. package/src/ast/ValueNode.ts +0 -28
  141. package/src/patterns/RecursivePattern.ts +0 -86
  142. package/src/patterns/composite/AndComposite.ts +0 -159
  143. package/src/patterns/composite/CompositePattern.ts +0 -7
  144. package/src/patterns/composite/OptionalComposite.ts +0 -37
  145. package/src/patterns/composite/OrComposite.ts +0 -96
  146. package/src/patterns/composite/RepeatComposite.ts +0 -130
  147. package/src/patterns/value/AndValue.ts +0 -153
  148. package/src/patterns/value/AnyOfThese.ts +0 -81
  149. package/src/patterns/value/Literal.ts +0 -92
  150. package/src/patterns/value/NotValue.ts +0 -95
  151. package/src/patterns/value/OptionalValue.ts +0 -39
  152. package/src/patterns/value/OrValue.ts +0 -103
  153. package/src/patterns/value/RegexValue.ts +0 -103
  154. package/src/patterns/value/RepeatValue.ts +0 -131
  155. package/src/patterns/value/ValuePattern.ts +0 -8
  156. package/src/tests/AndComposite.test.ts +0 -102
  157. package/src/tests/AnyOfThese.test.ts +0 -74
  158. package/src/tests/CompositeNode.test.ts +0 -33
  159. package/src/tests/NotValue.test.ts +0 -69
  160. package/src/tests/OptionalValue.test.ts +0 -50
  161. package/src/tests/OrComposite.test.ts +0 -75
  162. package/src/tests/OrValue.test.ts +0 -171
  163. package/src/tests/Permutor.test.ts +0 -30
  164. package/src/tests/RegexValue.test.ts +0 -22
  165. package/src/tests/RepeatComposite.test.ts +0 -58
  166. package/src/tests/ValueNode.test.ts +0 -24
  167. package/src/tests/javascriptPatterns/varStatement.ts +0 -0
  168. package/src/tests/readmeDemo.test.ts +0 -124
@@ -1,103 +0,0 @@
1
- import ParseError from "../ParseError";
2
- import ValueNode from "../../ast/ValueNode";
3
- import ValuePattern from "./ValuePattern";
4
- import Cursor from "../../Cursor";
5
-
6
- export default class RegexValue extends ValuePattern {
7
- public regexString: string;
8
- public regex: RegExp;
9
- public node: ValueNode | null = null;
10
- public cursor!: Cursor;
11
- public substring: string = "";
12
-
13
- constructor(name: string, regex: string) {
14
- super("regex-value", name);
15
- this.regexString = regex;
16
- this.regex = new RegExp(`^${regex}`, "g");
17
- this._assertArguments();
18
- }
19
-
20
- private _assertArguments() {
21
- if (typeof this.regexString !== "string") {
22
- throw new Error(
23
- "Invalid Arguments: The regex argument needs to be a string of regex."
24
- );
25
- }
26
-
27
- if (this.regexString.length < 1) {
28
- throw new Error(
29
- "Invalid Arguments: The regex string argument needs to be at least one character long."
30
- );
31
- }
32
-
33
- if (this.regexString.charAt(0) === "^") {
34
- throw new Error(
35
- "Invalid Arguments: The regex string cannot start with a '^' because it is expected to be in the middle of a string."
36
- );
37
- }
38
-
39
- if (this.regexString.charAt(this.regexString.length - 1) === "$") {
40
- throw new Error(
41
- "Invalid Arguments: The regex string cannot end with a '$' because it is expected to be in the middle of a string."
42
- );
43
- }
44
- }
45
-
46
- parse(cursor: Cursor) {
47
- this._reset(cursor);
48
- this._tryPattern();
49
-
50
- return this.node;
51
- }
52
-
53
- private _reset(cursor: Cursor) {
54
- this.cursor = cursor;
55
- this.regex.lastIndex = 0;
56
- this.substring = this.cursor.text.substr(this.cursor.getIndex());
57
- this.node = null;
58
- }
59
-
60
- private _tryPattern() {
61
- const result = this.regex.exec(this.substring);
62
-
63
- if (result != null && result.index === 0) {
64
- const currentIndex = this.cursor.getIndex();
65
- const newIndex = currentIndex + result[0].length - 1;
66
-
67
- this.node = new ValueNode(
68
- "regex-value",
69
- this.name,
70
- result[0],
71
- currentIndex,
72
- newIndex
73
- );
74
-
75
- this.cursor.index = newIndex;
76
- this.cursor.addMatch(this, this.node);
77
- } else {
78
- this._processError();
79
- }
80
- }
81
-
82
- private _processError() {
83
- const message = `ParseError: Expected regex pattern of '${this.regexString}' but found '${this.substring}'.`;
84
- const parseError = new ParseError(message, this.cursor.getIndex(), this);
85
-
86
- this.cursor.throwError(parseError);
87
- }
88
-
89
- clone(name: string) {
90
- if (typeof name !== "string") {
91
- name = this.name;
92
- }
93
- return new RegexValue(name, this.regexString);
94
- }
95
-
96
- getTokenValue() {
97
- return this.name;
98
- }
99
-
100
- getTokens() {
101
- return [this.name];
102
- }
103
- }
@@ -1,131 +0,0 @@
1
- import ValuePattern from "./ValuePattern";
2
- import ValueNode from "../../ast/ValueNode";
3
- import ParseError from "../ParseError";
4
- import OptionalValue from "./OptionalValue";
5
- import Pattern from "../Pattern";
6
- import Cursor from "../../Cursor";
7
-
8
- export default class RepeatValue extends ValuePattern {
9
- public _pattern: ValuePattern;
10
- public _divider: ValuePattern;
11
- public nodes: ValueNode[] = [];
12
- public cursor!: Cursor;
13
- public mark: number = 0;
14
- public node: ValueNode | null = null;
15
-
16
- constructor(name: string, pattern: ValuePattern, divider?: ValuePattern) {
17
- super(
18
- "repeat-value",
19
- name,
20
- divider != null ? [pattern, divider] : [pattern]
21
- );
22
-
23
- this._pattern = this.children[0] as ValuePattern;
24
- this._divider = this.children[1] as ValuePattern;
25
-
26
- this._assertArguments();
27
- }
28
-
29
- private _assertArguments() {
30
- if (this._pattern instanceof OptionalValue) {
31
- throw new Error(
32
- "Invalid Arguments: The pattern cannot be a optional pattern."
33
- );
34
- }
35
- }
36
-
37
- private _reset(cursor: Cursor) {
38
- this.nodes = [];
39
- this.cursor = cursor;
40
- this.mark = this.cursor.mark();
41
- }
42
-
43
- parse(cursor: Cursor) {
44
- this._reset(cursor);
45
- this._tryPattern();
46
-
47
- return this.node;
48
- }
49
-
50
- private _tryPattern() {
51
- while (true) {
52
- const node = this._pattern.parse(this.cursor) as ValueNode;
53
-
54
- if (this.cursor.hasUnresolvedError()) {
55
- this._processMatch();
56
- break;
57
- } else {
58
- this.nodes.push(node);
59
-
60
- if (node.endIndex === this.cursor.lastIndex()) {
61
- this._processMatch();
62
- break;
63
- }
64
-
65
- this.cursor.next();
66
-
67
- if (this._divider != null) {
68
- const mark = this.cursor.mark();
69
- const node = this._divider.parse(this.cursor) as ValueNode;
70
-
71
- if (this.cursor.hasUnresolvedError()) {
72
- this.cursor.moveToMark(mark);
73
- this._processMatch();
74
- break;
75
- } else {
76
- this.nodes.push(node);
77
-
78
- if (node.endIndex === this.cursor.lastIndex()) {
79
- this._processMatch();
80
- break;
81
- }
82
-
83
- this.cursor.next();
84
- }
85
- }
86
- }
87
- }
88
- }
89
-
90
- private _processMatch() {
91
- const endsOnDivider = this.nodes.length % 2 === 0;
92
- const noMatch = this.nodes.length === 0;
93
- const hasDivider = this._divider != null;
94
-
95
- this.cursor.resolveError();
96
-
97
- if ((hasDivider && endsOnDivider) || noMatch) {
98
- const parseError = new ParseError(
99
- `Did not find a repeating match of ${this.name}.`,
100
- this.mark,
101
- this
102
- );
103
- this.cursor.throwError(parseError);
104
- this.node = null;
105
- } else {
106
- const value = this.nodes.map((node) => node.value).join("");
107
-
108
- this.node = new ValueNode(
109
- "repeat-value",
110
- this.name,
111
- value,
112
- this.nodes[0].startIndex,
113
- this.nodes[this.nodes.length - 1].endIndex
114
- );
115
-
116
- this.cursor.index = this.node.endIndex;
117
- this.cursor.addMatch(this, this.node);
118
- }
119
- }
120
-
121
- clone(name?: string) {
122
- if (typeof name !== "string") {
123
- name = this.name;
124
- }
125
- return new RepeatValue(name, this._pattern, this._divider);
126
- }
127
-
128
- getTokens() {
129
- return this._pattern.getTokens();
130
- }
131
- }
@@ -1,8 +0,0 @@
1
- import Pattern from "../Pattern";
2
-
3
- export default abstract class ValuePattern extends Pattern {
4
- constructor(type: string, name: string, children: ValuePattern[] = []) {
5
- super(type, name, children);
6
- }
7
- abstract clone(name?: string): ValuePattern;
8
- }
@@ -1,102 +0,0 @@
1
- /** @jest-environment node */
2
- import AndComposite from "../patterns/composite/AndComposite";
3
- import Literal from "../patterns/value/Literal";
4
- import OptionalValue from "../patterns/value/OptionalValue";
5
- import Cursor from "../Cursor";
6
-
7
- describe("AndComposite", () => {
8
- test("Match", () => {
9
- const john = new Literal("john", "John");
10
- const doe = new Literal("doe", "Doe");
11
- const cursor = new Cursor("JohnDoe");
12
- const name = new AndComposite("name", [john, doe]);
13
-
14
- const node = name.parse(cursor);
15
-
16
- expect(node?.name).toBe("name");
17
- expect(node?.children[0].name).toBe("john");
18
- expect(node?.children[1].name).toBe("doe");
19
- expect(node?.children[0].value).toBe("John");
20
- expect(node?.children[1].value).toBe("Doe");
21
- });
22
-
23
- test("AndComposite: No Match", () => {
24
- const john = new Literal("john", "John");
25
- const doe = new Literal("doe", "Doe");
26
- const cursor = new Cursor("JohnSmith");
27
- const name = new AndComposite("name", [john, doe]);
28
-
29
- const node = name.parse(cursor);
30
-
31
- expect(node).toBe(null);
32
- expect(cursor.getIndex()).toBe(0);
33
- expect(cursor.hasUnresolvedError()).toBe(true);
34
- expect(cursor.parseError?.message).toBe(
35
- "ParseError: Expected 'Doe' but found 'Smi'."
36
- );
37
- });
38
-
39
- test("AndComposite: test.", () => {
40
- const john = new Literal("john", "John");
41
- const doe = new Literal("doe", "Doe");
42
- const name = new AndComposite("name", [john, doe]);
43
- const isMatch = name.test("JohnDoe");
44
-
45
- expect(isMatch).toBe(true);
46
- });
47
-
48
- test("AndComposite: no children.", () => {
49
- expect(() => {
50
- new AndComposite("name");
51
- }).toThrow();
52
- });
53
-
54
- test("AndComposite: string runs out before match is done.", () => {
55
- const first = new Literal("first", "John");
56
- const last = new Literal("last", "Doe");
57
- const name = new AndComposite("name", [first, last]);
58
- const cursor = new Cursor("JohnDo");
59
- const result = name.parse(cursor);
60
- });
61
-
62
- test("AndComposite: last name is optional.", () => {
63
- const first = new Literal("first", "John");
64
- const last = new OptionalValue(new Literal("last", "Boe"));
65
- const name = new AndComposite("name", [first, last]);
66
- const cursor = new Cursor("JohnDo");
67
- const result = name.parse(cursor);
68
-
69
- expect(result?.name).toBe("name");
70
- expect(result?.type).toBe("and-composite");
71
- expect(result?.children[0].value).toBe("John");
72
- expect(result?.children[0].name).toBe("first");
73
- expect(result?.children[0].type).toBe("literal");
74
- });
75
-
76
- test("AndComposite: three non-optional patterns.", () => {
77
- const first = new Literal("first", "John");
78
- const middle = new Literal("middle", "Smith");
79
- const last = new Literal("last", "Doe");
80
- const name = new AndComposite("name", [first, middle, last]);
81
- const cursor = new Cursor("JohnDoe");
82
- const result = name.parse(cursor);
83
- });
84
-
85
- test("AndComposite: full name, middle optional, and last name isn't.", () => {
86
- const first = new Literal("first", "John");
87
- const middle = new OptionalValue(new Literal("middle", "Smith"));
88
- const last = new Literal("last", "Doe");
89
- const name = new AndComposite("name", [first, middle, last]);
90
- const cursor = new Cursor("JohnDoe");
91
- const result = name.parse(cursor);
92
- });
93
-
94
- test("AndComposite: clone.", () => {
95
- const john = new Literal("john", "John");
96
- const doe = new Literal("doe", "Doe");
97
- const name = new AndComposite("name", [john, doe]);
98
- const clone = name.clone("name2");
99
-
100
- expect(clone.name).toBe("name2");
101
- });
102
- });
@@ -1,74 +0,0 @@
1
- /** @jest-environment node */
2
- import AnyOfThese from "../patterns/value/AnyOfThese";
3
- import Cursor from "../Cursor";
4
-
5
- describe("AnyOfThese", () => {
6
- test("Empty string provided as characters.", () => {
7
- expect(() => {
8
- new AnyOfThese("no-characters", "");
9
- }).toThrow();
10
- });
11
-
12
- test("Single character.", () => {
13
- const lowerCaseA = new AnyOfThese("lower-case-a", "a");
14
- const cursor = new Cursor("a");
15
- const node = lowerCaseA.parse(cursor);
16
-
17
- expect(node?.name).toBe("lower-case-a");
18
- expect(node?.value).toBe("a");
19
- expect(node?.startIndex).toBe(0);
20
- expect(node?.endIndex).toBe(0);
21
- expect(cursor.isAtEnd()).toBe(true);
22
- expect(cursor.getChar()).toBe("a");
23
- });
24
-
25
- test("Uppercase A and lowercase A.", () => {
26
- const letterA = new AnyOfThese("letter-a", "Aa");
27
- const lowerCaseCursor = new Cursor("a");
28
- const upperCaseCursor = new Cursor("A");
29
- const lowerCaseNode = letterA.parse(lowerCaseCursor);
30
- const upperCaseNode = letterA.parse(upperCaseCursor);
31
-
32
- expect(lowerCaseNode?.name).toBe("letter-a");
33
- expect(lowerCaseNode?.value).toBe("a");
34
- expect(lowerCaseNode?.startIndex).toBe(0);
35
- expect(lowerCaseNode?.endIndex).toBe(0);
36
-
37
- expect(upperCaseNode?.name).toBe("letter-a");
38
- expect(upperCaseNode?.value).toBe("A");
39
- expect(upperCaseNode?.startIndex).toBe(0);
40
- expect(upperCaseNode?.endIndex).toBe(0);
41
-
42
- expect(upperCaseCursor.getChar()).toBe("A");
43
- expect(upperCaseCursor.isAtEnd()).toBe(true);
44
-
45
- expect(lowerCaseCursor.getChar()).toBe("a");
46
- expect(lowerCaseCursor.isAtEnd()).toBe(true);
47
- });
48
-
49
- test("Match with long cursor.", () => {
50
- const letterA = new AnyOfThese("letter-a", "Aa");
51
- const cursor = new Cursor("a12345");
52
- const node = letterA.parse(cursor);
53
-
54
- expect(node?.name).toBe("letter-a");
55
- expect(node?.value).toBe("a");
56
- expect(cursor.getChar()).toBe("a");
57
- expect(cursor.getIndex()).toBe(0);
58
- });
59
-
60
- test("No match.", () => {
61
- const letterA = new AnyOfThese("letter-a", "Aa");
62
- const cursor = new Cursor("12345");
63
- const node = letterA.parse(cursor);
64
-
65
- expect(node).toBe(null);
66
- });
67
-
68
- test("Pattern Methods.", () => {
69
- const letterA = new AnyOfThese("letter-a", "Aa");
70
-
71
- expect(letterA.name).toBe("letter-a");
72
- expect(letterA.children.length).toBe(0);
73
- });
74
- });
@@ -1,33 +0,0 @@
1
- /** @jest-environment node */
2
- import CompositeNode from "../ast/CompositeNode";
3
- import { ValueNode } from "../index";
4
-
5
- describe("CompositeNode", () => {
6
- test("CompositeNode: clone", () => {
7
- const node = new CompositeNode("type", "name", 0, 0);
8
- const valueNode = new ValueNode("value-type", "value-name", "t", 0, 0);
9
-
10
- node.children.push(valueNode);
11
-
12
- const clone = node.clone();
13
-
14
- expect(clone.type).toBe("type");
15
- expect(clone.name).toBe("name");
16
- expect(clone.children.length).toBe(1);
17
- expect(clone.children[0].type).toBe("value-type");
18
- expect(clone.children[0].name).toBe("value-name");
19
- });
20
-
21
- test("CompositeNode: constructor without default indexes.", () => {
22
- const node = new CompositeNode("type", "name");
23
- const valueNode = new ValueNode("value-type", "value-name", "t", 0, 0);
24
-
25
- node.children.push(valueNode);
26
-
27
- expect(node.type).toBe("type");
28
- expect(node.name).toBe("name");
29
- expect(node.children.length).toBe(1);
30
- expect(node.children[0].type).toBe("value-type");
31
- expect(node.children[0].name).toBe("value-name");
32
- });
33
- });
@@ -1,69 +0,0 @@
1
- /** @jest-environment node */
2
- import NotValue from "../patterns/value/NotValue";
3
- import Literal from "../patterns/value/Literal";
4
- import Cursor from "../Cursor";
5
-
6
- describe("NotValue", () => {
7
- test("Empty Constructor.", () => {
8
- expect(() => {
9
- new (NotValue as any)();
10
- }).toThrow();
11
- });
12
-
13
- test("Invalid name.", () => {
14
- expect(() => {
15
- new (NotValue as any)([], new Literal("blah", "Blah"));
16
- }).toThrow();
17
- });
18
-
19
- test("No patterns", () => {
20
- expect(() => {
21
- new (NotValue as any)("and-value");
22
- }).toThrow();
23
- });
24
-
25
- test("Empty patterns", () => {
26
- expect(() => {
27
- new (NotValue as any)("and-value", null);
28
- }).toThrow();
29
- });
30
-
31
- test("Invalid patterns", () => {
32
- expect(() => {
33
- new (NotValue as any)("and-value", {});
34
- }).toThrow();
35
- });
36
-
37
- test("No Match", () => {
38
- const john = new Literal("john", "John");
39
- const notJohn = new NotValue("not-john", john);
40
- const cursor = new Cursor("John");
41
-
42
- notJohn.parse(cursor);
43
- expect(cursor.hasUnresolvedError()).toBe(true);
44
- expect(cursor.parseError?.message).toBe(
45
- "Didn't find any characters that didn't match the john pattern."
46
- );
47
- });
48
-
49
- test("Success", () => {
50
- const john = new Literal("john", "John");
51
- const notJohn = new NotValue("not-john", john);
52
- const cursor = new Cursor("Jane");
53
- const node = notJohn.parse(cursor);
54
-
55
- expect(node?.name).toBe("not-john");
56
- expect(node?.value).toBe("J");
57
- expect(node?.startIndex).toBe(0);
58
- expect(node?.endIndex).toBe(0);
59
- expect(cursor.getIndex()).toBe(0);
60
- });
61
-
62
- test("Clone.", () => {
63
- const john = new Literal("john", "John");
64
- const notJohn = new NotValue("not-john", john);
65
- const clone = notJohn.clone();
66
-
67
- expect(notJohn.name).toBe(clone.name);
68
- });
69
- });
@@ -1,50 +0,0 @@
1
- /** @jest-environment node */
2
- import Literal from "../patterns/value/Literal";
3
- import OptionalValue from "../patterns/value/OptionalValue";
4
- import Cursor from "../Cursor";
5
-
6
- describe("OptionalValue", () => {
7
- test("Empty constructor.", () => {
8
- expect(() => {
9
- new (OptionalValue as any)();
10
- }).toThrow();
11
- });
12
-
13
- test("Empty pattern.", () => {
14
- expect(() => {
15
- new (OptionalValue as any)();
16
- }).toThrow();
17
- });
18
-
19
- test("Invalid pattern.", () => {
20
- expect(() => {
21
- new (OptionalValue as any)({});
22
- }).toThrow();
23
- });
24
-
25
- test("Match pattern.", () => {
26
- const john = new Literal("john", "John");
27
- const optionalValue = new OptionalValue(john);
28
- const cursor = new Cursor("John");
29
- const node = optionalValue.parse(cursor);
30
-
31
- expect(node?.name).toBe("john");
32
- expect(node?.value).toBe("John");
33
- });
34
-
35
- test("No Match pattern.", () => {
36
- const john = new Literal("john", "John");
37
- const optionalValue = new OptionalValue(john);
38
- const cursor = new Cursor("Jane");
39
- const node = optionalValue.parse(cursor);
40
-
41
- expect(node).toBe(null);
42
- });
43
-
44
- test("Name", () => {
45
- const john = new Literal("john", "John");
46
- const optionalValue = new OptionalValue(john);
47
-
48
- expect(optionalValue.name).toBe("optional-value");
49
- });
50
- });
@@ -1,75 +0,0 @@
1
- /** @jest-environment node */
2
- import OrComposite from "../patterns/composite/OrComposite";
3
- import Literal from "../patterns/value/Literal";
4
- import OptionalValue from "../patterns/value/OptionalValue";
5
- import { Cursor } from "../index";
6
-
7
- describe("OrComposite", ()=>{
8
- test("Match.", () => {
9
- const john = new Literal("john", "John");
10
- const jane = new Literal("jane", "Jane");
11
- const cursor = new Cursor("John");
12
- const name = new OrComposite("name", [john, jane]);
13
-
14
- const node = name.parse(cursor);
15
-
16
- expect(node.name).toBe("john");
17
- expect(node.value).toBe("John");
18
- });
19
-
20
- test("No Match", () => {
21
- const john = new Literal("john", "John");
22
- const jane = new Literal("jane", "Jane");
23
- const cursor = new Cursor("Jeffrey");
24
- const name = new OrComposite("name", [john, jane]);
25
-
26
- const node = name.parse(cursor);
27
-
28
- expect(node).toBe(null);
29
- expect(cursor.getIndex()).toBe(0);
30
- expect(cursor.hasUnresolvedError()).toBe(true);
31
- });
32
-
33
- test("Supplied only one option.", () => {
34
- const john = new Literal("john", "John");
35
-
36
- expect(() => {
37
- new OrComposite("name", [john]);
38
- }).toThrow();
39
- });
40
-
41
- test("Optional Children.", () => {
42
- const john = new Literal("john", "John");
43
- const jane = new Literal("jane", "Jane");
44
-
45
- expect(() => {
46
- new OrComposite("name", [new OptionalValue(john), new OptionalValue(jane)]);
47
- }).toThrow();
48
- });
49
-
50
- test("parse with null cursor.", () => {
51
- const john = new Literal("john", "John");
52
- const jane = new Literal("jane", "Jane");
53
- const cursor = new Cursor("John");
54
- const name = new OrComposite("name", [john, jane]);
55
-
56
- const node = name.parse(cursor);
57
-
58
- expect(node.name).toBe("john");
59
- expect(node.value).toBe("John");
60
- });
61
-
62
- test("clone.", () => {
63
- const john = new Literal("john", "John");
64
- const jane = new Literal("jane", "Jane");
65
-
66
- const name = new OrComposite("name", [john, jane]);
67
- const clone = name.clone("name2");
68
-
69
- expect(clone.name).toBe("name2");
70
- expect(clone.children.length).toBe(2);
71
- expect(clone.children[0].name).toBe("john");
72
- expect(clone.children[1].name).toBe("jane");
73
- });
74
-
75
- });