import * as Schema from "effect/Schema"; import { describe, expect, it } from "vite-plus/test"; import { buildT3ProjectFileJsonSchema, parseT3ProjectFile, T3ProjectFileFromJson, } from "./t3ProjectFile.ts"; const decodeJson = Schema.decodeUnknownSync(T3ProjectFileFromJson); describe("buildT3ProjectFileJsonSchema", () => { it("emits a draft 2020-12 schema with the published $id", () => { const schema = buildT3ProjectFileJsonSchema(); expect(schema.$schema).toBe("https://json-schema.org/draft/2020-12/schema"); expect(schema.$id).toBe("https://t3.codes/schema/t3.json"); expect(schema.type).toBe("object"); expect(schema.additionalProperties).toBe(false); }); it("documents every supported field", () => { const schema = buildT3ProjectFileJsonSchema() as { properties: Record< string, { description?: string; items?: { properties: Record; required: ReadonlyArray }; } >; required?: ReadonlyArray; }; expect(Object.keys(schema.properties).sort()).toEqual([ "$schema", "defaultThreadEnvMode", "iconPath", "scripts", ]); expect(schema.required).toBeUndefined(); expect(schema.properties.iconPath?.description).toContain("Workspace-relative path"); expect(schema.properties.defaultThreadEnvMode?.description).toContain("new threads start"); const script = schema.properties.scripts?.items; expect(script?.required).toEqual(["name", "command"]); expect(Object.keys(script?.properties ?? {}).sort()).toEqual([ "autoOpenPreview", "command", "icon", "name", "previewUrl", "runOnWorktreeCreate", ]); }); it("stays JSON-serializable", () => { const schema = buildT3ProjectFileJsonSchema(); expect(JSON.parse(JSON.stringify(schema))).toEqual(schema); }); }); describe("T3ProjectFileFromJson", () => { it("decodes lenient JSONC with comments and trailing commas", () => { const decoded = decodeJson(`{ // team scripts "iconPath": "assets/logo.svg", "scripts": [ { "name": "Dev", "command": "pnpm dev", }, ], }`); expect(decoded.iconPath).toBe("assets/logo.svg"); expect(decoded.scripts?.[0]).toEqual({ name: "Dev", command: "pnpm dev" }); }); it("fails on malformed JSON", () => { expect(() => decodeJson("{ not json")).toThrow(); }); }); describe("parseT3ProjectFile", () => { it("returns the decoded file for valid contents", () => { expect(parseT3ProjectFile('{ "defaultThreadEnvMode": "worktree" }')).toEqual({ defaultThreadEnvMode: "worktree", }); }); it("returns null for malformed or invalid contents", () => { expect(parseT3ProjectFile("{ not json")).toBeNull(); expect(parseT3ProjectFile('{ "defaultThreadEnvMode": "spaceship" }')).toBeNull(); }); });