97 lines
4.2 KiB
JavaScript
Executable File
97 lines
4.2 KiB
JavaScript
Executable File
const test = require("node:test");
|
|
const assert = require("node:assert/strict");
|
|
const data = require("../assets/scripts/pages/archive-world-data.js");
|
|
const state = require("../assets/scripts/pages/archive-world-state.js");
|
|
|
|
test("fresh v2 state applies safe defaults", () => {
|
|
const fresh = state.fresh(" Ada ", "moss");
|
|
assert.equal(fresh.version, 2);
|
|
assert.equal(fresh.name, "Ada");
|
|
assert.equal(fresh.palette, "moss");
|
|
assert.equal(fresh.position.area, "town");
|
|
assert.deepEqual(
|
|
{ x: fresh.position.x, y: fresh.position.y },
|
|
data.AREAS.town.safeSpawns.gate
|
|
);
|
|
assert.ok(fresh.position.y > data.AREAS.town.gates[0].y + data.AREAS.town.gates[0].height);
|
|
assert.equal(fresh.health, 100);
|
|
assert.equal(fresh.settings.soundEnabled, false);
|
|
assert.deepEqual(fresh.sigils, []);
|
|
assert.equal(fresh.inventory.find((item) => item.id === "ink_vial").quantity, 2);
|
|
});
|
|
|
|
test("names and palettes are validated", () => {
|
|
assert.equal(state.validateName(" Archive Guest "), "Archive Guest");
|
|
assert.equal(state.validateName(""), null);
|
|
assert.equal(state.validateName("x".repeat(21)), null);
|
|
assert.equal(state.validatePalette("berry"), "berry");
|
|
assert.equal(state.validatePalette("ultraviolet"), null);
|
|
});
|
|
|
|
test("v1 data migrates identity, discoveries, position and sound", () => {
|
|
const migrated = state.migrateV1({
|
|
version: 1,
|
|
name: "Mira",
|
|
palette: "berry",
|
|
discovered: ["gate", "gate", "museum", "missing"],
|
|
complete: false,
|
|
position: { x: 700, y: 850 },
|
|
soundEnabled: true
|
|
});
|
|
assert.equal(migrated.version, 2);
|
|
assert.deepEqual(migrated.discovered, ["gate", "museum"]);
|
|
assert.equal(migrated.position.area, "town");
|
|
assert.equal(migrated.position.x, 700);
|
|
assert.equal(migrated.settings.soundEnabled, true);
|
|
});
|
|
|
|
test("normalization deduplicates and filters restored collections", () => {
|
|
const candidate = state.fresh("Zaine", "brass");
|
|
candidate.discovered = ["gate", "gate", "missing"];
|
|
candidate.sigils = ["garden", "garden", "bad"];
|
|
candidate.inventory.push({ id: "ink_vial", quantity: 99 }, { id: "invalid", quantity: 2 });
|
|
candidate.defeatedBosses = ["sentinel", "sentinel", "fake"];
|
|
candidate.solvedPuzzles = ["gate", "gate", "fake"];
|
|
const restored = state.normalize(candidate);
|
|
assert.deepEqual(restored.discovered, ["gate"]);
|
|
assert.deepEqual(restored.sigils, ["garden"]);
|
|
assert.equal(restored.inventory.find((item) => item.id === "ink_vial").quantity, data.ITEMS.ink_vial.stack);
|
|
assert.deepEqual(restored.defeatedBosses, ["sentinel"]);
|
|
assert.deepEqual(restored.solvedPuzzles, ["gate"]);
|
|
});
|
|
|
|
test("quest restoration accepts only known statuses and bounded counters", () => {
|
|
const candidate = state.fresh("Ada", "brass");
|
|
candidate.quests.gate = { status: "active", step: 200, count: -5 };
|
|
candidate.quests.library = { status: "nonsense", step: 2, count: 3 };
|
|
const restored = state.normalize(candidate);
|
|
assert.deepEqual(restored.quests.gate, { status: "active", step: 20, count: 0 });
|
|
assert.deepEqual(restored.quests.library, { status: "locked", step: 2, count: 3 });
|
|
});
|
|
|
|
test("position, health, settings and unsupported schemas recover safely", () => {
|
|
const candidate = state.fresh("Ada", "brass");
|
|
candidate.position = { area: "missing", x: -100, y: 9000, facing: "downward" };
|
|
candidate.health = 999;
|
|
candidate.settings = { soundEnabled: true, ambience: 9, music: -2, effects: "bad", assist: true };
|
|
const restored = state.normalize(candidate);
|
|
assert.equal(restored.position.area, "town");
|
|
assert.equal(restored.position.x, 24);
|
|
assert.equal(restored.position.y, 1062);
|
|
assert.equal(restored.position.facing, "north");
|
|
assert.equal(restored.health, restored.maxHealth);
|
|
assert.equal(restored.settings.ambience, 1);
|
|
assert.equal(restored.settings.music, 0);
|
|
assert.equal(restored.settings.effects, 0.65);
|
|
assert.equal(state.parse("{"), null);
|
|
assert.equal(state.parse(JSON.stringify({ version: 99 })), null);
|
|
});
|
|
|
|
test("level thresholds and reset-ready fresh state are deterministic", () => {
|
|
assert.equal(state.levelForXp(0), 1);
|
|
assert.equal(state.levelForXp(80), 2);
|
|
assert.equal(state.levelForXp(620), 5);
|
|
assert.deepEqual(state.fresh("Mira", "berry").discovered, []);
|
|
assert.equal(state.fresh("Mira", "berry").quests.gate.status, "locked");
|
|
});
|