X-Git-Url: https://git.ladys.computer/Pisces/blobdiff_plain/20911ecea4d7c09ac104d4e059975444bb4238d7..fb3e0d562e2dbe9e3ea911a80bfdabc8851f92b2:/string.test.js diff --git a/string.test.js b/string.test.js index 0af3e32..6407d94 100644 --- a/string.test.js +++ b/string.test.js @@ -10,10 +10,13 @@ import { assert, assertEquals, + assertSpyCall, + assertSpyCalls, assertStrictEquals, assertThrows, describe, it, + spy, } from "./dev-deps.js"; import { asciiLowercase, @@ -60,6 +63,10 @@ describe("Matcher", () => { assert(new Matcher("") instanceof RegExp); }); + it("[[Construct]] throws when provided with a noncallable, nonĀ·null third argument", () => { + assertThrows(() => new Matcher("", undefined, "failure")); + }); + describe("::dotAll", () => { it("[[Get]] returns true when the dotAll flag is present", () => { assertStrictEquals(new Matcher(/(?:)/su).dotAll, true); @@ -76,10 +83,47 @@ describe("Matcher", () => { [...new Matcher(/.(?(?:.(?=.))*)(.)?/u).exec("success")], ["success", "ucces", "s"], ); + assertEquals( + [...new Matcher( + /.(?(?:.(?=.))*)(.)?/u, + undefined, + ($) => $ === "success", + ).exec("success")], + ["success", "ucces", "s"], + ); + }); + + it("[[Call]] calls the constraint if the match succeeds", () => { + const constraint = spy((_) => true); + const matcher = new Matcher("(.).*", undefined, constraint); + const result = matcher.exec({ + toString() { + return "etaoin"; + }, + }); + assertSpyCalls(constraint, 1); + assertSpyCall(constraint, 0, { + args: ["etaoin", result, matcher], + self: undefined, + }); + }); + + it("[[Call]] does not call the constraint if the match fails", () => { + const constraint = spy((_) => true); + const matcher = new Matcher("", undefined, constraint); + matcher.exec("failure"); + assertSpyCalls(constraint, 0); }); it("[[Call]] returns null given a partial match", () => { - assertEquals(new Matcher("").exec("failure"), null); + assertStrictEquals(new Matcher("").exec("failure"), null); + }); + + it("[[Call]] returns null if the constraint fails", () => { + assertStrictEquals( + new Matcher(".*", undefined, () => false).exec(""), + null, + ); }); }); @@ -150,12 +194,43 @@ describe("Matcher", () => { it("[[Call]] returns true for a complete match", () => { assertStrictEquals(new Matcher("")(""), true); assertStrictEquals(new Matcher(/.*/su)("success\nyay"), true); + assertStrictEquals( + new Matcher(/.*/su, undefined, ($) => $ === "success")( + "success", + ), + true, + ); + }); + + it("[[Call]] calls the constraint if the match succeeds", () => { + const constraint = spy((_) => true); + const matcher = new Matcher("(.).*", undefined, constraint); + matcher("etaoin"); + assertSpyCalls(constraint, 1); + assertEquals(constraint.calls[0].args[0], "etaoin"); + assertEquals([...constraint.calls[0].args[1]], ["etaoin", "e"]); + assertEquals(constraint.calls[0].args[2], matcher); + assertEquals(constraint.calls[0].self, undefined); + }); + + it("[[Call]] does not call the constraint if the match fails", () => { + const constraint = spy((_) => true); + const matcher = new Matcher("", undefined, constraint); + matcher("failure"); + assertSpyCalls(constraint, 0); }); it("[[Call]] returns false for a partial match", () => { assertStrictEquals(new Matcher("")("failure"), false); assertStrictEquals(new Matcher(/.*/u)("failure\nno"), false); }); + + it("[[Call]] returns false if the constraint fails", () => { + assertStrictEquals( + new Matcher(".*", undefined, () => false)(""), + false, + ); + }); }); describe("~lastIndex", () => {