Skip to content

Commit

Permalink
test: refactor to reuse some code
Browse files Browse the repository at this point in the history
  • Loading branch information
fabianhjr committed Oct 2, 2024
1 parent c3bf5bb commit 8c673bc
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 49 deletions.
2 changes: 1 addition & 1 deletion src/parsers/ParserResult.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class Success<t> implements ParserResult<t> {
) {}
}

abstract class Failure<t> implements ParserResult<t> {}
export abstract class Failure<t> implements ParserResult<t> {}

export class EndOfFileFailure<t> extends Failure<t> {}

Expand Down
43 changes: 19 additions & 24 deletions test/parsers/CondCharParser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>('(input) => input === "a"', "b", 1),
);
});

describe("CondCharParser Property", () => {
Expand Down
33 changes: 9 additions & 24 deletions test/parsers/MatchParser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
37 changes: 37 additions & 0 deletions test/parsers/TestHelpers.ts
Original file line number Diff line number Diff line change
@@ -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<t>(
parser: Parser<t>,
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<t, f extends Failure<t>>(
parser: Parser<t>,
input: string,
expectedFailure: f,
) {
const result = parser.parse(input);
expect(result).toBeInstanceOf(expectedFailure.constructor);
if (result instanceof expectedFailure.constructor) {
expect(result).toEqual(expectedFailure);
}
}

0 comments on commit 8c673bc

Please sign in to comment.