diff --git a/src/parsers/ParserResult.ts b/src/parsers/ParserResult.ts index 50376ec..3fe7bee 100644 --- a/src/parsers/ParserResult.ts +++ b/src/parsers/ParserResult.ts @@ -9,7 +9,7 @@ export class Success implements ParserResult { ) {} } -abstract class Failure implements ParserResult {} +export abstract class Failure implements ParserResult {} export class EndOfFileFailure extends Failure {} diff --git a/test/parsers/CondCharParser.test.ts b/test/parsers/CondCharParser.test.ts index f58b8fc..6284e6c 100644 --- a/test/parsers/CondCharParser.test.ts +++ b/test/parsers/CondCharParser.test.ts @@ -8,32 +8,27 @@ import { CondFailure, } from "../../src/parsers/ParserResult.ts"; +import { testParserSuccess, testParserFailure } from "./TestHelpers.ts"; + describe("CondCharParser Unit", () => { - it("should successfully parse matching input", () => { - const parser = CondCharParser.new((input) => input === "a"); - const result = parser.parse("a"); - expect(result).toBeInstanceOf(Success); - if (result instanceof Success) { - expect(result.value).toBe("a"); - expect(result.pos).toBe(1); - } - }); + testParserSuccess( + CondCharParser.new((input) => input === "a"), + "a", + "a", + 1, + ); - it("should fail with EndOfFileFailure on empty input", () => { - const parser = CondCharParser.new((input) => input === "a"); - const result = parser.parse(""); - expect(result).toBeInstanceOf(EndOfFileFailure); - }); - it("should fail with CondFailure on non-matching input", () => { - const parser = CondCharParser.new((input) => input === "a"); - const result = parser.parse("b"); - expect(result).toBeInstanceOf(CondFailure); - if (result instanceof CondFailure) { - expect(result.cond).toBe('(input) => input === "a"'); - expect(result.actual).toBe("b"); - expect(result.pos).toBe(1); - } - }); + testParserFailure( + CondCharParser.new((input) => input === "a"), + "", + new EndOfFileFailure(), + ); + + testParserFailure( + CondCharParser.new((input) => input === "a"), + "b", + new CondFailure('(input) => input === "a"', "b", 1), + ); }); describe("CondCharParser Property", () => { diff --git a/test/parsers/MatchParser.test.ts b/test/parsers/MatchParser.test.ts index 645d29f..b235ca3 100644 --- a/test/parsers/MatchParser.test.ts +++ b/test/parsers/MatchParser.test.ts @@ -8,33 +8,18 @@ import { MatchFailure, } from "../../src/parsers/ParserResult.ts"; +import { testParserSuccess, testParserFailure } from "./TestHelpers.ts"; + describe("MatchParser Unit", () => { - it("should successfully parse matching input", () => { - const parser = MatchParser.new("test"); - const result = parser.parse("test input"); - expect(result).toBeInstanceOf(Success); - if (result instanceof Success) { - expect(result.value).toBeUndefined(); - expect(result.pos).toBe(4); - } - }); + testParserSuccess(MatchParser.new("test"), "test input", undefined, 4); - it("should fail with EndOfFileFailure on empty input", () => { - const parser = MatchParser.new("test"); - const result = parser.parse(""); - expect(result).toBeInstanceOf(EndOfFileFailure); - }); + testParserFailure(MatchParser.new("test"), "", new EndOfFileFailure()); - it("should fail with MatchFailure on non-matching input", () => { - const parser = MatchParser.new("test"); - const result = parser.parse("fail input"); - expect(result).toBeInstanceOf(MatchFailure); - if (result instanceof MatchFailure) { - expect(result.expected).toBe("test"); - expect(result.actual).toBe("fail"); - expect(result.pos).toBe(0); - } - }); + testParserFailure( + MatchParser.new("test"), + "fail input", + new MatchFailure("test", "fail", 0), + ); it("should fail to construct with empty string", () => { expect(() => MatchParser.new("")).toThrowError( diff --git a/test/parsers/TestHelpers.ts b/test/parsers/TestHelpers.ts new file mode 100644 index 0000000..40830ff --- /dev/null +++ b/test/parsers/TestHelpers.ts @@ -0,0 +1,37 @@ +import { describe, it, expect } from "@jest/globals"; +import { assert, property, string } from "fast-check"; + +import { + Failure, + Success, + EndOfFileFailure, + CondFailure, + MatchFailure, +} from "../../src/parsers/ParserResult.ts"; +import { Parser } from "../../src/parsers/Parser.ts"; + +export function testParserSuccess( + parser: Parser, + input: string, + expectedValue: t, + expectedPos: number, +) { + const result = parser.parse(input); + expect(result).toBeInstanceOf(Success); + if (result instanceof Success) { + expect(result.value).toBe(expectedValue); + expect(result.pos).toBe(expectedPos); + } +} + +export function testParserFailure>( + parser: Parser, + input: string, + expectedFailure: f, +) { + const result = parser.parse(input); + expect(result).toBeInstanceOf(expectedFailure.constructor); + if (result instanceof expectedFailure.constructor) { + expect(result).toEqual(expectedFailure); + } +}