import { codeInfoString, parseCodeInfo } from "@src/lib/markdown/tree/code-info";
import { describe, expect, it } from "vitest";

describe("parseCodeInfo", () => {
    it("returns an empty language and attributes for a blank info string", () => {
        expect(parseCodeInfo("")).toEqual({ language: "", attributes: {} });
        expect(parseCodeInfo("   ")).toEqual({ language: "", attributes: {} });
    });

    it("reads the language as the first token, lower-cased", () => {
        expect(parseCodeInfo("TypeScript")).toEqual({
            language: "typescript",
            attributes: {},
        });
    });

    it("resolves loose flags to true", () => {
        const parsed = parseCodeInfo("surql runnable");
        expect(parsed.language).toBe("surql");
        expect(parsed.attributes.runnable).toBe(true);
    });

    it("parses double- and single-quoted values", () => {
        const parsed = parseCodeInfo(`js title="My Example" label='other'`);
        expect(parsed.attributes.title).toBe("My Example");
        expect(parsed.attributes.label).toBe("other");
    });

    it("keeps an empty string value for empty quotes", () => {
        const parsed = parseCodeInfo(`js title=""`);
        expect(parsed.attributes.title).toBe("");
    });

    it("parses bare unquoted values", () => {
        const parsed = parseCodeInfo("ts height=200");
        expect(parsed.attributes.height).toBe("200");
    });

    it("parses braced expression values", () => {
        const parsed = parseCodeInfo("surql runnable={SELECT 1}");
        expect(parsed.attributes.runnable).toBe("{SELECT 1}");
    });

    it("mixes loose flags and key/value pairs", () => {
        const parsed = parseCodeInfo(`surql runnable title="Demo"`);
        expect(parsed).toEqual({
            language: "surql",
            attributes: { runnable: true, title: "Demo" },
        });
    });

    it("preserves attribute value casing", () => {
        const parsed = parseCodeInfo(`surql runnable="SELECT 1"`);
        expect(parsed.attributes.runnable).toBe("SELECT 1");
    });

    it("codeInfoString returns string values and undefined for flags", () => {
        const parsed = parseCodeInfo(`surql runnable title="Demo"`);
        expect(codeInfoString(parsed, "title")).toBe("Demo");
        expect(codeInfoString(parsed, "runnable")).toBeUndefined();
        expect(codeInfoString(parsed, "missing")).toBeUndefined();
    });
});
