| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
- import { existsSync } from "node:fs";
- import { tmpdir } from "node:os";
- import { dirname, join, resolve } from "node:path";
- import { describe, expect, it } from "vitest";
- import { runEditorPack } from "../src/pack.js";
- const FIXTURE_FILES: Record<string, string> = {
- "content/time.yaml": [
- "id: default",
- "dayLengthTicks: 240",
- "seasons:",
- " - { name: spring, dayCount: 14 }",
- "start: { day: 1, season: spring }",
- "",
- ].join("\n"),
- "content/maps/farm.yaml": [
- "id: farm",
- "width: 12",
- "height: 12",
- "tilesetRef: farm-tiles",
- "spawn: { x: 2, y: 2 }",
- "walkable:",
- " water: false",
- "layers:",
- " - name: ground",
- " data:",
- ...mapRows(),
- "",
- ].join("\n"),
- "content/items/hoe.yaml": [
- "id: hoe",
- "name: Hoe",
- "kind: tool",
- "stackable: false",
- "price: 100",
- "use: tills a soil tile",
- "",
- ].join("\n"),
- };
- function mapRows(): string[] {
- const rows: string[] = [];
- for (let y = 0; y < 12; y++) {
- const row: string[] = [];
- for (let x = 0; x < 12; x++) {
- row.push(x < 2 && y < 2 ? "water" : "grass");
- }
- rows.push(` - [${row.join(", ")}]`);
- }
- return rows;
- }
- async function fixtureDir(): Promise<string> {
- const dir = await mkdtemp(join(tmpdir(), "editor-pack-"));
- for (const [rel, content] of Object.entries(FIXTURE_FILES)) {
- const target = join(dir, rel);
- await mkdir(dirname(target), { recursive: true });
- await writeFile(target, content, "utf8");
- }
- return dir;
- }
- async function rmRecursive(dir: string): Promise<void> {
- await rm(dir, { recursive: true, force: true });
- }
- function options(overrides: Partial<{ desktop: boolean; installer: boolean; mods: boolean; splitAssets: boolean }> = {}): Parameters<typeof runEditorPack>[1] {
- return {
- name: "Pinefield Valley",
- icon: "",
- desktop: overrides.desktop ?? false,
- installer: overrides.installer ?? false,
- mods: overrides.mods ?? false,
- splitAssets: overrides.splitAssets ?? false,
- outDir: "",
- };
- }
- describe("runEditorPack (E7 package dialog pipeline)", () => {
- it("packs a minimal fixture project into a static site + bundle.json", async () => {
- const dir = await fixtureDir();
- try {
- const result = await runEditorPack(dir, options(), existsSync(join(dir, "mods")));
- expect(result.ok).toBe(true);
- if (!result.ok) return;
- expect(result.outDir).toBe(resolve(dir, "dist-pack"));
- expect(existsSync(join(result.outDir, "bundle.json"))).toBe(true);
- expect(existsSync(join(result.outDir, "index.html"))).toBe(true);
- expect(existsSync(join(result.outDir, "assets"))).toBe(true);
- expect(result.stats.kinds).toBeGreaterThan(0);
- expect(result.stats.defCount).toBeGreaterThan(0);
- expect(result.stats.desktop).toBe(false);
- expect(result.stats.installer).toBe(false);
- } finally {
- await rmRecursive(dir);
- }
- });
- it("desktop mode writes the Electron shell (main.cjs + package.json)", async () => {
- const dir = await fixtureDir();
- try {
- const result = await runEditorPack(dir, options({ desktop: true }), existsSync(join(dir, "mods")));
- expect(result.ok).toBe(true);
- if (!result.ok) return;
- expect(result.stats.desktop).toBe(true);
- expect(existsSync(join(result.outDir, "desktop", "main.cjs"))).toBe(true);
- expect(existsSync(join(result.outDir, "desktop", "package.json"))).toBe(true);
- expect(existsSync(join(result.outDir, "desktop", "README-desktop.md"))).toBe(true);
- } finally {
- await rmRecursive(dir);
- }
- });
- it("installer mode writes electron-builder.yml and copies the site into desktop/", async () => {
- const dir = await fixtureDir();
- try {
- const result = await runEditorPack(dir, options({ installer: true }), existsSync(join(dir, "mods")));
- expect(result.ok).toBe(true);
- if (!result.ok) return;
- expect(result.stats.installer).toBe(true);
- expect(result.stats.desktop).toBe(true);
- expect(existsSync(join(result.outDir, "desktop", "electron-builder.yml"))).toBe(true);
- expect(existsSync(join(result.outDir, "desktop", "index.html"))).toBe(true);
- expect(existsSync(join(result.outDir, "desktop", "bundle.json"))).toBe(true);
- expect(existsSync(join(result.outDir, "desktop", "assets"))).toBe(true);
- } finally {
- await rmRecursive(dir);
- }
- });
- it("surfaces a content-compile failure as {ok: false, error} with the per-def message", async () => {
- const dir = await mkdtemp(join(tmpdir(), "editor-pack-bad-"));
- try {
- await mkdir(join(dir, "content", "maps"), { recursive: true });
- await writeFile(join(dir, "content", "maps", "bad.yaml"), ["id: bad", "width: nope", "height: 2", ""].join("\n"));
- const result = await runEditorPack(dir, options(), false);
- expect(result.ok).toBe(false);
- if (result.ok) return;
- expect(result.error).toContain("validation failed");
- expect(result.error).toContain("map/bad");
- } finally {
- await rmRecursive(dir);
- }
- });
- });
|