syntaxai/tdd.md · main · src / c14_request_parse.test.ts

c14_request_parse.test.ts 55 lines · 1668 bytes raw
import { describe, test, expect } from "bun:test";
import { parseUrl, parseJson } from "./c14_request_parse.ts";

describe("c14_request_parse — parseUrl", () => {
  test("returns { ok: true, value } for a well-formed absolute URL", () => {
    const r = parseUrl("https://tdd.md/sama/v2/verify?repo=x/y");
    expect(r.ok).toBe(true);
    if (r.ok) {
      expect(r.value.hostname).toBe("tdd.md");
      expect(r.value.pathname).toBe("/sama/v2/verify");
      expect(r.value.searchParams.get("repo")).toBe("x/y");
    }
  });

  test("returns { ok: false, error } for an invalid URL", () => {
    const r = parseUrl("not a url");
    expect(r.ok).toBe(false);
    if (!r.ok) expect(typeof r.error).toBe("string");
  });

  test("never throws", () => {
    expect(() => parseUrl("")).not.toThrow();
    expect(() => parseUrl("///")).not.toThrow();
  });
});

describe("c14_request_parse — parseJson", () => {
  test("parses a valid JSON object", () => {
    const r = parseJson<{ a: number }>(`{"a": 1}`);
    expect(r.ok).toBe(true);
    if (r.ok) expect(r.value.a).toBe(1);
  });

  test("parses a valid JSON array", () => {
    const r = parseJson<number[]>(`[1, 2, 3]`);
    expect(r.ok).toBe(true);
    if (r.ok) expect(r.value).toEqual([1, 2, 3]);
  });

  test("returns { ok: false, error } for invalid JSON", () => {
    const r = parseJson(`{not json`);
    expect(r.ok).toBe(false);
    if (!r.ok) expect(typeof r.error).toBe("string");
  });

  test("returns { ok: false } for empty input", () => {
    const r = parseJson("");
    expect(r.ok).toBe(false);
  });

  test("never throws", () => {
    expect(() => parseJson("bogus")).not.toThrow();
  });
});