diff --git a/api/tests/misc/filter.test.ts b/api/tests/misc/filter.test.ts new file mode 100644 index 00000000..3fbee3f6 --- /dev/null +++ b/api/tests/misc/filter.test.ts @@ -0,0 +1,126 @@ +import { describe, expect, it } from "bun:test"; +import type { ParjsFailure } from "parjs/internal"; +import { type Expression, expression } from "~/models/utils/filters"; + +function parse( + filter: string, +): { ok: true; value: Expression } | { ok: false } { + const ret = expression.parse(filter); + if (ret.isOk) return { ok: true, value: ret.value }; + const fail = ret as ParjsFailure; + console.log(fail.toString()); + return { + ok: false, + reason: fail.reason, + trace: { + ...fail.trace, + location: fail.trace.location, + leftover: fail.trace.input.substring(fail.trace.location.column), + }, + } as any; +} + +describe("Parse filter", () => { + it("Handle eq", () => { + const ret = parse("status eq finished"); + expect(ret).toMatchObject({ + ok: true, + value: { + type: "op", + operator: "eq", + property: "status", + value: { type: "enum", value: "finished" }, + }, + }); + }); + it("Handle lt", () => { + const ret = parse("rating lt 10"); + expect(ret).toMatchObject({ + ok: true, + value: { + type: "op", + operator: "lt", + property: "rating", + value: { type: "int", value: 10 }, + }, + }); + }); + it("Handle dates", () => { + const ret = parse("airDate ge 2022-10-12"); + expect(ret).toMatchObject({ + ok: true, + value: { + type: "op", + operator: "ge", + property: "airDate", + value: { type: "date", value: "2022-10-12" }, + }, + }); + }); + it("Handle not", () => { + const ret = parse("not rating lt 10"); + expect(ret).toMatchObject({ + ok: true, + value: { + type: "not", + expression: { + type: "op", + operator: "lt", + property: "rating", + value: { type: "int", value: 10 }, + }, + }, + }); + }); + it("Handle top level brackets", () => { + const ret = parse("(rating lt 10)"); + expect(ret).toMatchObject({ + ok: true, + value: { + type: "op", + operator: "lt", + property: "rating", + value: { type: "int", value: 10 }, + }, + }); + }); + it("Handle top level brackets with not", () => { + const ret = parse("(not rating lt 10)"); + expect(ret).toMatchObject({ + ok: true, + value: { + type: "not", + expression: { + type: "op", + operator: "lt", + property: "rating", + value: { type: "int", value: 10 }, + }, + }, + }); + }); + it("Handle and", () => { + const ret = parse("not rating lt 10 and rating lt 20"); + expect(ret).toMatchObject({ + ok: true, + value: { + type: "and", + lhs: { + type: "not", + expression: { + type: "op", + operator: "lt", + property: "rating", + value: { type: "int", value: 10 }, + }, + }, + rhs: { + type: "op", + operator: "lt", + property: "rating", + value: { type: "int", value: 20 }, + }, + }, + }); + }); +}); diff --git a/api/tests/get-movies.test.ts b/api/tests/movies/get-movies.test.ts similarity index 100% rename from api/tests/get-movies.test.ts rename to api/tests/movies/get-movies.test.ts diff --git a/api/tests/seed-movies.test.ts b/api/tests/movies/seed-movies.test.ts similarity index 100% rename from api/tests/seed-movies.test.ts rename to api/tests/movies/seed-movies.test.ts