65 lines
3.0 KiB
JavaScript
65 lines
3.0 KiB
JavaScript
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { readFileSync, readdirSync } from "node:fs";
|
|
import { join, dirname } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { validate } from "../schema.mjs";
|
|
import { loadCatalog } from "../lib.mjs";
|
|
|
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
const json = (p) => JSON.parse(readFileSync(p, "utf8"));
|
|
const cardSchema = json(join(here, "../../course/schema/card.schema.json"));
|
|
const levelSchema = json(join(here, "../../course/schema/level.schema.json"));
|
|
const entry = {
|
|
type: "object",
|
|
required: ["name", "kind", "text", "source"],
|
|
properties: { name: { type: "string" }, kind: { enum: ["card", "word"] }, text: { type: "string" } },
|
|
};
|
|
const cardEntry = {
|
|
type: "object",
|
|
required: ["type", "cost"],
|
|
properties: { type: { enum: ["minion", "spell"] }, cost: { type: "integer", minimum: 0 }, attack: { type: "integer" }, health: { type: "integer" } },
|
|
};
|
|
const wordEntry = { type: "object", required: ["role"], properties: { role: { enum: ["noun", "operator", "property", "meta"] } } };
|
|
|
|
test("catalog_valid", () => {
|
|
const cat = loadCatalog();
|
|
assert.ok(Array.isArray(cat) && cat.length > 0);
|
|
const names = new Set();
|
|
for (const e of cat) {
|
|
assert.deepEqual(validate({ ...entry, required: e.fictional ? ["name", "kind", "text"] : entry.required }, e), [], e.name);
|
|
assert.deepEqual(validate(e.kind === "card" ? cardEntry : wordEntry, e), [], e.name);
|
|
assert.ok(!names.has(e.name), `duplicate ${e.name}`);
|
|
names.add(e.name);
|
|
if (e.kind === "card" && !e.fictional) assert.match(e.source, /^https:\/\/hearthstone\.wiki\.gg\//, e.name);
|
|
if (e.kind === "card" && e.name.startsWith("Test ")) assert.equal(e.fictional, true, e.name);
|
|
if (e.fictional) assert.ok(e.name.startsWith("Test "), e.name);
|
|
}
|
|
for (const n of ["Baron Rivendare", "Fleshshape", "Test Echo", "BABA", "IS", "DEATHRATTLE"]) assert.ok(names.has(n), n);
|
|
});
|
|
|
|
test("card_schema_accepts_fixtures", () => {
|
|
const dir = join(here, "fixtures/cards");
|
|
const files = readdirSync(dir).filter((f) => f.endsWith(".json"));
|
|
assert.ok(files.length >= 5);
|
|
const cat = new Map(loadCatalog().map((e) => [e.name, e]));
|
|
for (const f of files) {
|
|
const c = json(join(dir, f));
|
|
assert.deepEqual(validate(cardSchema, c), [], f);
|
|
const m = cat.get(c.name);
|
|
assert.ok(m, `${c.name} in catalog`);
|
|
assert.deepEqual([c.cost, c.attack, c.health], [m.cost, m.attack, m.health], `${f} matches catalog stats`);
|
|
}
|
|
});
|
|
|
|
test("card_schema_rejects_bad", () => {
|
|
const bad = { name: "X", type: "minion", cost: 1, split: 0, text: [{ kind: "trigger", on: "bogus" }] };
|
|
assert.notDeepEqual(validate(cardSchema, bad), []);
|
|
assert.notDeepEqual(validate(cardSchema, { name: "X" }), []);
|
|
});
|
|
|
|
test("level_schema", () => {
|
|
assert.deepEqual(validate(levelSchema, { width: 3, height: 1, objects: [{ kind: "baba", x: 0, y: 0 }] }), []);
|
|
assert.notDeepEqual(validate(levelSchema, { width: 3, height: 1, objects: [{ kind: "baba", x: 0 }] }), []);
|
|
});
|