summaryrefslogtreecommitdiff
path: root/tests/paca.mjs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tests/paca.mjs261
1 files changed, 229 insertions, 32 deletions
diff --git a/tests/paca.mjs b/tests/paca.mjs
index 55185f7..06b3c8b 100644
--- a/tests/paca.mjs
+++ b/tests/paca.mjs
@@ -22,13 +22,16 @@ import {
toPostfixStep,
toPostfix,
emptyNFA,
- baseNFA,
+ literal,
concat,
union,
zeroOrMore,
oneOrMore,
zeroOrOne,
+ characterClass,
+ wildcard,
OPERATORS_FNS,
+ baseNFA,
buildNFAStep,
buildNFA,
allDirects,
@@ -355,8 +358,9 @@ const test_classStateStep = t => {
);
const expected = {
out: [ 1, 2, 3, {
- meta: "class",
- set: [ 4, 5, 6 ],
+ meta: "class",
+ set: [ 4, 5, 6 ],
+ caret: false,
}],
state: "accepting",
context: null,
@@ -911,22 +915,25 @@ const test_tokenizeRegexStep = t => {
},
}, {
out: [caret, {
- meta: "class",
- set: [ "b", "e", "h", "i", "l", "o", "s" ],
+ meta: "class",
+ set: [ "b", "e", "h", "i", "l", "o", "s" ],
+ caret: false,
}],
state: "accepting",
context: null,
}, {
out: [caret, {
- meta: "class",
- set: [ "b", "e", "h", "i", "l", "o", "s" ],
+ meta: "class",
+ set: [ "b", "e", "h", "i", "l", "o", "s" ],
+ caret: false,
}, star],
state: "accepting",
context: null,
}, {
out: [caret, {
- meta: "class",
- set: [ "b", "e", "h", "i", "l", "o", "s" ],
+ meta: "class",
+ set: [ "b", "e", "h", "i", "l", "o", "s" ],
+ caret: false,
}, star, dollar],
state: "accepting",
context: null,
@@ -1768,8 +1775,8 @@ const test_emptyNFA = t => {
});
};
-const test_baseNFA = t => {
- t.start("baseNFA()");
+const test_literal = t => {
+ t.start("literal()");
t.testing("the given edge connects the nodes", () => {
const expected = {
@@ -1787,17 +1794,17 @@ const test_baseNFA = t => {
},
},
};
- t.assertEq(baseNFA("X", 123), expected);
+ t.assertEq(literal("X", 123), expected);
});
};
const test_concat = t => {
t.start("concat()");
- t.testing("on baseNFA() and on more complex NFAs", () => {
- const a = baseNFA("a", 1);
- const b = baseNFA("b", a.nextID);
- const a_ = baseNFA("a", b.nextID);
+ t.testing("on literal() and on more complex NFAs", () => {
+ const a = literal("a", 1);
+ const b = literal("b", a.nextID);
+ const a_ = literal("a", b.nextID);
const expected1 = {
start: 1,
end: 4,
@@ -1861,9 +1868,9 @@ const test_concat = t => {
const test_union = t => {
t.start("union()");
- t.testing("on baseNFA() and on more complex NFAs", () => {
- const a = baseNFA("a", 1);
- const b = baseNFA("b", a.nextID);
+ t.testing("on literal() and on more complex NFAs", () => {
+ const a = literal("a", 1);
+ const b = literal("b", a.nextID);
const expected1 = {
start: 5,
end: 6,
@@ -1897,7 +1904,7 @@ const test_union = t => {
};
t.assertEq(union(a, b), expected1);
- const c = baseNFA("c", expected1.nextID);
+ const c = literal("c", expected1.nextID);
const expected2 = {
start: 9,
end: 10,
@@ -1952,8 +1959,8 @@ const test_union = t => {
const test_zeroOrMore = t => {
t.start("zeroOrMore()");
- t.testing("on baseNFA()", () => {
- const a = baseNFA("a", 1);
+ t.testing("on literal()", () => {
+ const a = literal("a", 1);
const expected = {
start: 3,
end: 4,
@@ -1984,8 +1991,8 @@ const test_zeroOrMore = t => {
const test_oneOrMore = t => {
t.start("oneOrMore()");
- t.testing("on baseNFA()", () => {
- const a = baseNFA("a", 1);
+ t.testing("on literal()", () => {
+ const a = literal("a", 1);
const expected = {
start: 1,
end: 4,
@@ -2016,8 +2023,8 @@ const test_oneOrMore = t => {
const test_zeroOrOne = t => {
t.start("zeroOrOne()");
- t.testing("on baseNFA()", () => {
- const a = baseNFA("a", 1);
+ t.testing("on literal()", () => {
+ const a = literal("a", 1);
const expected = {
start: 3,
end: 4,
@@ -2045,6 +2052,109 @@ const test_zeroOrOne = t => {
});
};
+const test_characterClass = t => {
+ t.start("characterClass()");
+
+ t.testing("when caret is true, op is excludes", () => {
+ const expected = {
+ start: 3,
+ end: 4,
+ nextID: 5,
+ nodes: {
+ 3: {
+ direct: [],
+ transitions: {},
+ meta: {
+ op: "excludes",
+ to: 4,
+ matches: new Set([
+ "-", "a", "b", "c",
+ ".", "_", "$", "^",
+ ]),
+ ranges: {
+ 102: 112,
+ 116: 122,
+ },
+ },
+ },
+ 4: {
+ direct: [],
+ transitions: {},
+ },
+ },
+ };
+ t.assertEq(characterClass({
+ set: [
+ "-", "a", "b", "c", { from: "f", to: "p" }, ".",
+ { from: "t", to: "z" }, "_", "$", "^", "a", "_",
+ ],
+ caret: true,
+ }, 3), expected);
+ });
+
+ t.testing("when caret is false, op is includes", () => {
+ const expected = {
+ start: 7,
+ end: 8,
+ nextID: 9,
+ nodes: {
+ 7: {
+ direct: [],
+ transitions: {},
+ meta: {
+ op: "includes",
+ to: 8,
+ matches: new Set([]),
+ ranges: {
+ 48: 57,
+ 65: 90,
+ 97: 122,
+ },
+ },
+ },
+ 8: {
+ direct: [],
+ transitions: {},
+ },
+ },
+ };
+ t.assertEq(characterClass({
+ set: [
+ { from: "a", to: "z" },
+ { from: "A", to: "Z" },
+ { from: "0", to: "9" },
+ ],
+ }, 7), expected);
+ });
+};
+
+const test_wildcard = t => {
+ t.start("wildcard()");
+
+ t.testing("the returned nfa always matches", () => {
+ const expected = {
+ start: 5,
+ end: 6,
+ nextID: 7,
+ nodes: {
+ 5: {
+ direct: [],
+ transitions: {},
+ meta: {
+ op: true,
+ to: 6,
+ }
+ },
+ 6: {
+ direct: [],
+ transitions: {},
+ },
+ },
+ };
+ t.assertEq(wildcard("IGNORED", 5), expected);
+ });
+};
+
const test_OPERATORS_FNS = t => {
t.start("OPERATORS_FNS");
@@ -2105,6 +2215,49 @@ const test_OPERATORS_FNS = t => {
});
};
+const test_baseNFA = t => {
+ t.start("baseNFA()");
+
+ t.testing("decide between metacharacter and literal", () => {
+ const expected1 = {
+ start: 1,
+ end: 2,
+ nextID: 3,
+ nodes: {
+ 1: {
+ direct: [],
+ transitions: { a: 2 },
+ },
+ 2: {
+ direct: [],
+ transitions: {},
+ },
+ },
+ };
+ const expected2 = {
+ start: 1,
+ end: 2,
+ nextID: 3,
+ nodes: {
+ 1: {
+ direct: [],
+ transitions: {},
+ meta: {
+ op: true,
+ to: 2,
+ },
+ },
+ 2: {
+ direct: [],
+ transitions: {},
+ },
+ },
+ };
+ t.assertEq(baseNFA("a", 1), expected1);
+ t.assertEq(baseNFA({ meta: "." }, 1), expected2);
+ });
+};
+
const test_buildNFAStep = t => {
t.start("buildNFAStep()");
@@ -2129,7 +2282,7 @@ const test_buildNFAStep = t => {
});
t.testing("literal char with existing nextID", () => {
- const input = baseNFA("a", 1);
+ const input = [ literal("a", 1) ];
const expected = [{
start: 1,
end: 2,
@@ -2159,15 +2312,56 @@ const test_buildNFAStep = t => {
},
},
}];
- t.assertEq(buildNFAStep([input], "b"), expected);
+ t.assertEq(buildNFAStep(input, "b"), expected);
t.assertEq(
- buildNFAStep([input], "b"),
- [ baseNFA("a", 1), baseNFA("b", 3) ]
+ buildNFAStep(input, "b"),
+ [ literal("a", 1), literal("b", 3) ]
+ );
+ });
+
+ t.testing("metacharacter", () => {
+ const input = [ literal("a", 1) ];
+ const expected = [{
+ start: 1,
+ end: 2,
+ nextID: 3,
+ nodes: {
+ 1: {
+ direct: [],
+ transitions: { a: 2 },
+ },
+ 2: {
+ direct: [],
+ transitions: {},
+ },
+ },
+ }, {
+ start: 3,
+ end: 4,
+ nextID: 5,
+ nodes: {
+ 3: {
+ direct: [],
+ transitions: {},
+ meta: {
+ op: true,
+ to: 4,
+ },
+ },
+ 4: {
+ direct: [],
+ transitions: {},
+ },
+ },
+ }];
+ t.assertEq(
+ buildNFAStep(input, { meta: "." }),
+ expected,
);
});
t.testing("operator", () => {
- const input = [ baseNFA("a", 1), baseNFA("b", 3) ];
+ const input = [ literal("a", 1), literal("b", 3) ];
const expected = [{
start: 1,
end: 4,
@@ -3111,13 +3305,16 @@ runTests([
test_toPostfixStep,
test_toPostfix,
test_emptyNFA,
- test_baseNFA,
+ test_literal,
test_concat,
test_union,
test_zeroOrMore,
test_oneOrMore,
test_zeroOrOne,
+ test_characterClass,
+ test_wildcard,
test_OPERATORS_FNS,
+ test_baseNFA,
test_buildNFAStep,
test_buildNFA,
test_allDirects,