Add import template into tui. Fix tests that fail on macos. Fix some updates.

This commit is contained in:
2026-05-29 18:16:00 +02:00
parent 85746c3306
commit 2f8dad7d8d
20 changed files with 1748 additions and 46 deletions

View File

@@ -0,0 +1,78 @@
import { existsSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import { afterEach, beforeEach, describe, expect, test } from "vitest";
import { parseTemplate } from "@xo-cash/utils";
import {
loadTemplateFromFile,
TemplateLoadError,
} from "../../src/utils/load-template-from-file.js";
import { p2pkhTemplate } from "../cli/mocks/template-p2pkh.js";
describe("loadTemplateFromFile", () => {
let tempRoot: string;
beforeEach(() => {
tempRoot = mkdtempSync(path.join(tmpdir(), "xo-load-template-"));
});
afterEach(() => {
if (existsSync(tempRoot)) {
rmSync(tempRoot, { recursive: true, force: true });
}
});
test("loads JSON templates directly", async () => {
const jsonPath = path.join(tempRoot, "template.json");
writeFileSync(jsonPath, JSON.stringify(p2pkhTemplate));
const contents = await loadTemplateFromFile(jsonPath);
const parsed = parseTemplate(contents);
expect(parsed.name).toBe(p2pkhTemplate.name);
});
test("loads TypeScript templates via child process", async () => {
const tsTemplatePath = path.resolve(
process.cwd(),
"../templates/source/p2pkh.ts",
);
expect(existsSync(tsTemplatePath)).toBe(true);
const contents = await loadTemplateFromFile(tsTemplatePath);
const parsed = parseTemplate(contents);
expect(parsed.name).toBe("Wallet (P2PKH)");
});
test("loads JavaScript templates via child process", async () => {
const jsPath = path.join(tempRoot, "template.mjs");
writeFileSync(
jsPath,
`export default ${JSON.stringify(p2pkhTemplate)};\n`,
"utf8",
);
const contents = await loadTemplateFromFile(jsPath);
const parsed = parseTemplate(contents);
expect(parsed.name).toBe(p2pkhTemplate.name);
});
test("throws TemplateLoadError for missing files", async () => {
await expect(
loadTemplateFromFile(path.join(tempRoot, "missing.json")),
).rejects.toBeInstanceOf(TemplateLoadError);
});
test("throws TemplateLoadError for unsupported extensions", async () => {
const txtPath = path.join(tempRoot, "template.txt");
writeFileSync(txtPath, "hello");
await expect(loadTemplateFromFile(txtPath)).rejects.toThrow(
/Unsupported template file extension/,
);
});
});

View File

@@ -0,0 +1,57 @@
import { describe, expect, test } from "vitest";
import {
isTemplateLike,
pickTemplateExport,
} from "../../src/utils/pick-template-export.js";
const sampleTemplate = {
$schema: "https://libauth.org/schemas/wallet-template-v0.schema.json",
name: "Sample",
roles: { owner: { name: "Owner" } },
};
describe("pickTemplateExport", () => {
test("isTemplateLike accepts objects with schema, name, and roles", () => {
expect(isTemplateLike(sampleTemplate)).toBe(true);
expect(isTemplateLike(null)).toBe(false);
expect(isTemplateLike({ name: "Missing schema" })).toBe(false);
});
test("prefers default export when template-like", () => {
const picked = pickTemplateExport({
default: sampleTemplate,
otherTemplate: {
...sampleTemplate,
name: "Other",
},
});
expect(picked).toBe(sampleTemplate);
});
test("uses a single named export when no default export exists", () => {
const picked = pickTemplateExport({
p2pkhTemplate: sampleTemplate,
});
expect(picked).toBe(sampleTemplate);
});
test("throws when multiple template exports exist", () => {
expect(() =>
pickTemplateExport({
firstTemplate: sampleTemplate,
secondTemplate: { ...sampleTemplate, name: "Second" },
}),
).toThrow(/Multiple template exports found/);
});
test("throws when no template export exists", () => {
expect(() =>
pickTemplateExport({
notATemplate: { foo: "bar" },
}),
).toThrow(/No XOTemplate export found/);
});
});