This commit is contained in:
parent
025cd4bf22
commit
7b4cfb7dc2
13 changed files with 1829 additions and 2 deletions
|
|
@ -160,6 +160,36 @@ export function validateSiteContent(site) {
|
|||
"toolboxes.modules.counters.incrementLabel",
|
||||
"toolboxes.modules.counters.resetTitle",
|
||||
"toolboxes.modules.counters.deleteTitle",
|
||||
"toolboxes.modules.combos.deviceLabel",
|
||||
"toolboxes.modules.combos.keyboardLayoutLabel",
|
||||
"toolboxes.modules.combos.categoryPlaceholder",
|
||||
"toolboxes.modules.combos.targetCategoryLabel",
|
||||
"toolboxes.modules.combos.noCategoryLabel",
|
||||
"toolboxes.modules.combos.comboNameLabel",
|
||||
"toolboxes.modules.combos.comboNamePlaceholder",
|
||||
"toolboxes.modules.combos.defaultComboName",
|
||||
"toolboxes.modules.combos.emptyDraft",
|
||||
"toolboxes.modules.combos.simultaneousModeTitle",
|
||||
"toolboxes.modules.combos.successiveModeLabel",
|
||||
"toolboxes.modules.combos.simultaneousModeLabel",
|
||||
"toolboxes.modules.combos.removeStepTitle",
|
||||
"toolboxes.modules.combos.removeLastInputTitle",
|
||||
"toolboxes.modules.combos.addComboButton",
|
||||
"toolboxes.modules.combos.saveComboButton",
|
||||
"toolboxes.modules.combos.cancelEditTitle",
|
||||
"toolboxes.modules.combos.cancelEditButton",
|
||||
"toolboxes.modules.combos.paletteLabel",
|
||||
"toolboxes.modules.combos.customKeyPlaceholder",
|
||||
"toolboxes.modules.combos.addCustomKeyButton",
|
||||
"toolboxes.modules.combos.emptyCombos",
|
||||
"toolboxes.modules.combos.emptyCategory",
|
||||
"toolboxes.modules.combos.emptySequence",
|
||||
"toolboxes.modules.combos.showCategoryTitle",
|
||||
"toolboxes.modules.combos.hideCategoryTitle",
|
||||
"toolboxes.modules.combos.reorderCategoryTitle",
|
||||
"toolboxes.modules.combos.reorderComboTitle",
|
||||
"toolboxes.modules.combos.editComboTitle",
|
||||
"toolboxes.modules.combos.deleteComboTitle",
|
||||
"toolboxes.modules.calculator.expressionLabel",
|
||||
"toolboxes.modules.calculator.expressionPlaceholder",
|
||||
"toolboxes.modules.calculator.resultLabel",
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ test("toolbox storage, cards and pages are wired", async () => {
|
|||
assert.match(toolboxStorage, /module\.scrollable/);
|
||||
assert.match(toolboxStorage, /export function normalizeLinksData/);
|
||||
assert.match(toolboxStorage, /export function normalizeCountersData/);
|
||||
assert.match(toolboxStorage, /export function normalizeCombosData/);
|
||||
assert.match(toolboxStorage, /export function normalizeCalculatorData/);
|
||||
assert.match(toolboxStorage, /export function normalizeTableData/);
|
||||
assert.match(toolboxStorage, /export function normalizeTimerData/);
|
||||
|
|
@ -62,6 +63,7 @@ test("toolbox storage, cards and pages are wired", async () => {
|
|||
assert.match(toolboxPages, /#\/toolbox\/\$\{toolbox\.id\}/);
|
||||
assert.match(toolboxPages, /setDrawerGameId\(""\)/);
|
||||
assert.match(toolboxPages, /moduleColumns/);
|
||||
assert.match(toolboxPages, /normalizeCombosData/);
|
||||
assert.match(toolboxPages, /function ToolboxView/);
|
||||
assert.match(toolboxPages, /usePointerReorder/);
|
||||
assert.match(storageQuota, /export function StorageQuota/);
|
||||
|
|
@ -77,6 +79,7 @@ test("toolbox module registry and modules expose expected behavior", async () =>
|
|||
const source = await readFile("website/src/main.jsx", "utf8");
|
||||
const moduleRegistry = await readFile("website/src/features/toolboxes/modules/index.jsx", "utf8");
|
||||
const notepadModule = await readFile("website/src/features/toolboxes/modules/NotepadModule.jsx", "utf8");
|
||||
const combosModule = await readFile("website/src/features/toolboxes/modules/CombosModule.jsx", "utf8");
|
||||
const calculatorModule = await readFile("website/src/features/toolboxes/modules/CalculatorModule.jsx", "utf8");
|
||||
const tableModule = await readFile("website/src/features/toolboxes/modules/TableModule.jsx", "utf8");
|
||||
const tableFormulaEngine = await readFile("website/src/features/toolboxes/modules/tableFormulaEngine.js", "utf8");
|
||||
|
|
@ -100,6 +103,8 @@ test("toolbox module registry and modules expose expected behavior", async () =>
|
|||
assert.match(moduleRegistry, /images:/);
|
||||
assert.match(moduleRegistry, /links:/);
|
||||
assert.match(moduleRegistry, /counters:/);
|
||||
assert.match(moduleRegistry, /combos:/);
|
||||
assert.match(moduleRegistry, /CombosModule/);
|
||||
assert.match(moduleRegistry, /calculator:/);
|
||||
assert.match(moduleRegistry, /table:/);
|
||||
assert.match(moduleRegistry, /table: \{ label: "Tableau", icon: "table", Component: TableModule, editable: false, scrollable: true \}/);
|
||||
|
|
@ -122,6 +127,13 @@ test("toolbox module registry and modules expose expected behavior", async () =>
|
|||
assert.match(moduleRegistry, /CompactDropdown/);
|
||||
assert.doesNotMatch(source, /<select value="" onChange=\{\(event\) => addModule/);
|
||||
assert.match(notepadModule, /export function NotepadModule/);
|
||||
assert.match(combosModule, /export function CombosModule/);
|
||||
assert.match(combosModule, /keyboardMouse/);
|
||||
assert.match(combosModule, /Nintendo 64/);
|
||||
assert.match(combosModule, /ComboInputToken/);
|
||||
assert.match(combosModule, /ComboSequence/);
|
||||
assert.match(combosModule, /keyboardLayout/);
|
||||
assert.match(combosModule, /simultaneousMode/);
|
||||
assert.match(calculatorModule, /export function CalculatorModule/);
|
||||
assert.match(calculatorModule, /calculateExpression/);
|
||||
assert.match(calculatorModule, /activeParentId/);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import assert from "node:assert/strict";
|
|||
import { evaluateTableCell } from "../website/src/features/toolboxes/modules/tableFormulaEngine.js";
|
||||
import { parseColonImportLines } from "../website/src/features/toolboxes/modules/textImport.js";
|
||||
import { getTimePatternRecurrenceMs, getTimePatternTargetMs } from "../website/src/features/toolboxes/modules/timerUtils.js";
|
||||
import { compactModuleDataForStorage, createToolboxExportPayload, normalizeNotepadData, normalizeTableData, normalizeTaskPlannerData } from "../website/src/features/toolboxes/storage/toolboxStorage.js";
|
||||
import { compactModuleDataForStorage, createToolboxExportPayload, normalizeCombosData, normalizeNotepadData, normalizeTableData, normalizeTaskPlannerData } from "../website/src/features/toolboxes/storage/toolboxStorage.js";
|
||||
|
||||
test("colon text import keeps urls intact after the first separator", () => {
|
||||
assert.deepEqual(parseColonImportLines("Build:https://example.com/build?class=rogue\nPotion:10"), [
|
||||
|
|
@ -95,6 +95,82 @@ test("table storage clamps dimensions and compacts non-empty cells", () => {
|
|||
assert.equal(compactModuleDataForStorage("table", { rows: 10, columns: 6, cells: {} }), null);
|
||||
});
|
||||
|
||||
test("combos storage normalizes devices, steps and compact export ids", () => {
|
||||
const longText = "x".repeat(120);
|
||||
const normalized = normalizeCombosData({
|
||||
device: "invalid",
|
||||
combos: [
|
||||
{
|
||||
id: "rootCombo",
|
||||
name: "Root",
|
||||
device: "switch",
|
||||
inputs: [[{ kind: "button", value: "triangle" }]]
|
||||
}
|
||||
],
|
||||
categories: [
|
||||
{
|
||||
id: "category1",
|
||||
title: `${longText} `,
|
||||
collapsed: true,
|
||||
combos: [
|
||||
{
|
||||
id: "combo1",
|
||||
device: "n64",
|
||||
name: `${longText} `,
|
||||
inputs: [
|
||||
[
|
||||
{ kind: "direction", value: "down" },
|
||||
{ kind: "button", value: "cross" },
|
||||
{ kind: "bad", value: "ignored" }
|
||||
],
|
||||
[],
|
||||
[{ kind: "key", value: "space" }]
|
||||
]
|
||||
},
|
||||
{ id: "empty", name: " ", inputs: [] }
|
||||
]
|
||||
},
|
||||
{ id: "emptyCategory", title: " ", combos: [] },
|
||||
{ id: "titledEmptyCategory", title: "Empty", combos: [] }
|
||||
]
|
||||
});
|
||||
|
||||
assert.equal(normalized.device, "playstation");
|
||||
assert.equal(normalized.combos.length, 1);
|
||||
assert.equal(normalized.combos[0].device, "switch");
|
||||
assert.equal(normalized.categories.length, 1);
|
||||
assert.equal(normalized.categories[0].title.length, 80);
|
||||
assert.equal(normalized.categories[0].collapsed, true);
|
||||
assert.equal(normalized.categories[0].combos.length, 1);
|
||||
assert.equal(normalized.categories[0].combos[0].name.length, 80);
|
||||
assert.equal("note" in normalized.categories[0].combos[0], false);
|
||||
assert.deepEqual(normalized.categories[0].combos[0].inputs, [
|
||||
[
|
||||
{ kind: "direction", value: "down" },
|
||||
{ kind: "button", value: "cross" }
|
||||
],
|
||||
[{ kind: "key", value: "space" }]
|
||||
]);
|
||||
|
||||
const compact = compactModuleDataForStorage("combos", { ...normalized, device: "xbox" });
|
||||
assert.equal(compact.device, "xbox");
|
||||
assert.equal(compact.combos[0].id, "rootCombo");
|
||||
assert.equal(compact.combos[0].device, "switch");
|
||||
assert.equal(compact.categories[0].id, "category1");
|
||||
assert.equal(compact.categories[0].combos[0].device, "n64");
|
||||
assert.equal(compact.categories[0].combos[0].id, "combo1");
|
||||
|
||||
const exported = createToolboxExportPayload(
|
||||
{ id: "toolbox1", name: "Combos", modules: [{ id: "module1", type: "combos" }], updatedAt: "2026-01-01T00:00:00.000Z" },
|
||||
{ "toolbox1:module1": compact }
|
||||
);
|
||||
assert.equal(exported.modules.m1.combos[0].id, "o1");
|
||||
assert.equal(exported.modules.m1.combos[0].device, "switch");
|
||||
assert.equal(exported.modules.m1.categories[0].id, "g1");
|
||||
assert.equal(exported.modules.m1.categories[0].combos[0].id, "o2");
|
||||
assert.equal(exported.modules.m1.categories[0].combos[0].device, "n64");
|
||||
});
|
||||
|
||||
test("notepad data migrates text, sanitizes html and compacts drawings", () => {
|
||||
const migrated = normalizeNotepadData({ text: "Boss\nPhase 2" });
|
||||
assert.equal(migrated.text, "Boss\nPhase 2");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue