| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- import { mkdir, mkdtemp, rm } from "node:fs/promises";
- import { tmpdir } from "node:os";
- import { join } from "node:path";
- import { describe, expect, it } from "vitest";
- import {
- PROJECT_YAML_NAME,
- projectYamlSchema,
- readProjectEnabledMods,
- readProjectYaml,
- writeProjectYaml,
- } from "../src/project-yaml.js";
- async function tmpDir(): Promise<string> {
- return mkdtemp(join(tmpdir(), "editor-yaml-"));
- }
- describe("projectYamlSchema", () => {
- it("accepts empty and partial metadata", () => {
- expect(projectYamlSchema.safeParse({}).success).toBe(true);
- expect(projectYamlSchema.safeParse({ name: "Game" }).success).toBe(true);
- expect(
- projectYamlSchema.safeParse({ name: "Game", icon: "icon.png", pack: { installer: true, splitAssets: true } })
- .success,
- ).toBe(true);
- });
- it("accepts the F1 mods field (absent / empty / enabled list)", () => {
- expect(projectYamlSchema.safeParse({ mods: {} }).success).toBe(true);
- expect(projectYamlSchema.safeParse({ mods: { enabled: [] } }).success).toBe(true);
- expect(projectYamlSchema.safeParse({ mods: { enabled: ["a-mod", "b-mod"] } }).success).toBe(true);
- expect(projectYamlSchema.safeParse({ name: "G", mods: { enabled: ["a-mod"] } }).success).toBe(true);
- });
- it("rejects unknown keys and wrong types", () => {
- expect(projectYamlSchema.safeParse({ nmae: "Game" }).success).toBe(false);
- expect(projectYamlSchema.safeParse({ name: 42 }).success).toBe(false);
- expect(projectYamlSchema.safeParse({ pack: { installer: "yes" } }).success).toBe(false);
- expect(projectYamlSchema.safeParse({ pack: { unknown: true } }).success).toBe(false);
- expect(projectYamlSchema.safeParse({ pack: "installed" }).success).toBe(false);
- expect(projectYamlSchema.safeParse({ mods: { enabled: [1] } }).success).toBe(false);
- expect(projectYamlSchema.safeParse({ mods: { enabled: "" } }).success).toBe(false);
- expect(projectYamlSchema.safeParse({ mods: { unknown: true } }).success).toBe(false);
- expect(projectYamlSchema.safeParse({ mods: "all" }).success).toBe(false);
- });
- });
- describe("readProjectYaml / writeProjectYaml", () => {
- it("returns null when project.yaml is absent", async () => {
- const dir = await tmpDir();
- try {
- expect(await readProjectYaml(dir)).toBeNull();
- } finally {
- await rm(dir, { recursive: true, force: true });
- }
- });
- it("roundtrips a written project.yaml", async () => {
- const dir = await tmpDir();
- try {
- const data = { name: "Pinefield", icon: "icon.png", pack: { installer: true, mods: true, splitAssets: true } };
- await writeProjectYaml(dir, data);
- expect(await readProjectYaml(dir)).toEqual(data);
- const { readFile } = await import("node:fs/promises");
- const raw = await readFile(join(dir, PROJECT_YAML_NAME), "utf8");
- expect(raw).toContain("name: Pinefield");
- } finally {
- await rm(dir, { recursive: true, force: true });
- }
- });
- it("roundtrips the mods field losslessly with other fields preserved", async () => {
- const dir = await tmpDir();
- try {
- const data = {
- name: "Pinefield",
- pack: { mods: true },
- mods: { enabled: ["fishing-mod", "weather-mod"] },
- };
- await writeProjectYaml(dir, data);
- expect(await readProjectYaml(dir)).toEqual(data);
- } finally {
- await rm(dir, { recursive: true, force: true });
- }
- });
- it("roundtrips an empty enabled list (all disabled) as distinct from absent", async () => {
- const dir = await tmpDir();
- try {
- await writeProjectYaml(dir, { mods: { enabled: [] } });
- const read = await readProjectYaml(dir);
- expect(read).toEqual({ mods: { enabled: [] } });
- expect(read?.mods?.enabled).toEqual([]);
- } finally {
- await rm(dir, { recursive: true, force: true });
- }
- });
- it("readProjectEnabledMods returns undefined when absent or malformed", async () => {
- const dir = await tmpDir();
- try {
- expect(await readProjectEnabledMods(dir)).toBeUndefined();
- await writeProjectYaml(dir, { mods: { enabled: ["a-mod"] } });
- expect(await readProjectEnabledMods(dir)).toEqual(["a-mod"]);
- await writeProjectYaml(dir, {});
- expect(await readProjectEnabledMods(dir)).toBeUndefined();
- const { writeFile } = await import("node:fs/promises");
- await writeFile(join(dir, PROJECT_YAML_NAME), "name: [broken\n", "utf8");
- expect(await readProjectEnabledMods(dir)).toBeUndefined();
- } finally {
- await rm(dir, { recursive: true, force: true });
- }
- });
- it("throws on malformed yaml and invalid data", async () => {
- const dir = await tmpDir();
- try {
- await mkdir(dir, { recursive: true });
- const { writeFile } = await import("node:fs/promises");
- await writeFile(join(dir, PROJECT_YAML_NAME), "name: [unclosed\n", "utf8");
- await expect(readProjectYaml(dir)).rejects.toThrow(/invalid project.yaml/);
- await expect(writeProjectYaml(dir, { name: 42 } as never)).rejects.toThrow(/invalid project.yaml/);
- } finally {
- await rm(dir, { recursive: true, force: true });
- }
- });
- });
|