Add equipment planner toolbox module
All checks were successful
Deploy Sokko G / deploy (push) Successful in 7s
All checks were successful
Deploy Sokko G / deploy (push) Successful in 7s
This commit is contained in:
parent
ac33a55c8b
commit
d53d4160af
33 changed files with 3522 additions and 20 deletions
|
|
@ -332,6 +332,73 @@ export function validateSiteContent(site) {
|
|||
"toolboxes.modules.taskPlanner.prerequisiteCheckboxLabel",
|
||||
"toolboxes.modules.taskPlanner.removeRelationTitle",
|
||||
"toolboxes.modules.taskPlanner.emptyTasks",
|
||||
"toolboxes.modules.equipmentPlanner.typePlaceholder",
|
||||
"toolboxes.modules.equipmentPlanner.equipmentIconLabel",
|
||||
"toolboxes.modules.equipmentPlanner.equipmentPlaceholder",
|
||||
"toolboxes.modules.equipmentPlanner.addEquipmentButton",
|
||||
"toolboxes.modules.equipmentPlanner.summaryTitle",
|
||||
"toolboxes.modules.equipmentPlanner.activeEquipmentsSingular",
|
||||
"toolboxes.modules.equipmentPlanner.activeEquipmentsPlural",
|
||||
"toolboxes.modules.equipmentPlanner.numericTotalsTitle",
|
||||
"toolboxes.modules.equipmentPlanner.equipmentTotalsTitle",
|
||||
"toolboxes.modules.equipmentPlanner.socketTotalsTitle",
|
||||
"toolboxes.modules.equipmentPlanner.mixedTotalsTitle",
|
||||
"toolboxes.modules.equipmentPlanner.summaryTooltipTitle",
|
||||
"toolboxes.modules.equipmentPlanner.textBonusesTitle",
|
||||
"toolboxes.modules.equipmentPlanner.emptyTotals",
|
||||
"toolboxes.modules.equipmentPlanner.emptyTextBonuses",
|
||||
"toolboxes.modules.equipmentPlanner.emptyEquipments",
|
||||
"toolboxes.modules.equipmentPlanner.activeLabel",
|
||||
"toolboxes.modules.equipmentPlanner.includeInSummaryLabel",
|
||||
"toolboxes.modules.equipmentPlanner.reorderTypeTitle",
|
||||
"toolboxes.modules.equipmentPlanner.renameTypeTitle",
|
||||
"toolboxes.modules.equipmentPlanner.showTypeTitle",
|
||||
"toolboxes.modules.equipmentPlanner.hideTypeTitle",
|
||||
"toolboxes.modules.equipmentPlanner.reorderEquipmentTitle",
|
||||
"toolboxes.modules.equipmentPlanner.renameEquipmentTitle",
|
||||
"toolboxes.modules.equipmentPlanner.showDetailsTitle",
|
||||
"toolboxes.modules.equipmentPlanner.hideDetailsTitle",
|
||||
"toolboxes.modules.equipmentPlanner.deleteEquipmentTitle",
|
||||
"toolboxes.modules.equipmentPlanner.tabsLabel",
|
||||
"toolboxes.modules.equipmentPlanner.statsTab",
|
||||
"toolboxes.modules.equipmentPlanner.socketsTab",
|
||||
"toolboxes.modules.equipmentPlanner.craftTab",
|
||||
"toolboxes.modules.equipmentPlanner.displayStatsTitle",
|
||||
"toolboxes.modules.equipmentPlanner.displaySocketTitle",
|
||||
"toolboxes.modules.equipmentPlanner.editModeTitle",
|
||||
"toolboxes.modules.equipmentPlanner.viewModeTitle",
|
||||
"toolboxes.modules.equipmentPlanner.editModeButton",
|
||||
"toolboxes.modules.equipmentPlanner.viewModeButton",
|
||||
"toolboxes.modules.equipmentPlanner.obtainLabel",
|
||||
"toolboxes.modules.equipmentPlanner.obtainPlaceholder",
|
||||
"toolboxes.modules.equipmentPlanner.emptyObtain",
|
||||
"toolboxes.modules.equipmentPlanner.characteristicsTitle",
|
||||
"toolboxes.modules.equipmentPlanner.traitIconLabel",
|
||||
"toolboxes.modules.equipmentPlanner.categoryPlaceholder",
|
||||
"toolboxes.modules.equipmentPlanner.traitNamePlaceholder",
|
||||
"toolboxes.modules.equipmentPlanner.traitValuePlaceholder",
|
||||
"toolboxes.modules.equipmentPlanner.addTraitButton",
|
||||
"toolboxes.modules.equipmentPlanner.reorderTraitTitle",
|
||||
"toolboxes.modules.equipmentPlanner.reorderCategoryTitle",
|
||||
"toolboxes.modules.equipmentPlanner.deleteTraitTitle",
|
||||
"toolboxes.modules.equipmentPlanner.emptyCharacteristics",
|
||||
"toolboxes.modules.equipmentPlanner.materialsTitle",
|
||||
"toolboxes.modules.equipmentPlanner.materialNamePlaceholder",
|
||||
"toolboxes.modules.equipmentPlanner.materialQtyLabel",
|
||||
"toolboxes.modules.equipmentPlanner.addMaterialButton",
|
||||
"toolboxes.modules.equipmentPlanner.deleteMaterialTitle",
|
||||
"toolboxes.modules.equipmentPlanner.socketItemsTitle",
|
||||
"toolboxes.modules.equipmentPlanner.emptySocketItems",
|
||||
"toolboxes.modules.equipmentPlanner.socketNamePlaceholder",
|
||||
"toolboxes.modules.equipmentPlanner.socketShapeLabel",
|
||||
"toolboxes.modules.equipmentPlanner.socketColorLabel",
|
||||
"toolboxes.modules.equipmentPlanner.addSocketButton",
|
||||
"toolboxes.modules.equipmentPlanner.bonusNamePlaceholder",
|
||||
"toolboxes.modules.equipmentPlanner.addBonusButton",
|
||||
"toolboxes.modules.equipmentPlanner.deleteSocketTitle",
|
||||
"toolboxes.modules.equipmentPlanner.deleteBonusTitle",
|
||||
"toolboxes.modules.equipmentPlanner.addSocketLinkLabel",
|
||||
"toolboxes.modules.equipmentPlanner.deleteSocketLinkTitle",
|
||||
"toolboxes.modules.imageAnnotation.addImage",
|
||||
"toolboxes.modules.imageAnnotation.replaceImage",
|
||||
"toolboxes.modules.imageAnnotation.pastePlaceholder",
|
||||
|
|
@ -432,7 +499,7 @@ export function validateLibraryData(payload) {
|
|||
assert.equal(typeof payload.modules[module.id], "object", `library.modules.${module.id} must be an object`);
|
||||
});
|
||||
|
||||
["notepad", "checklist", "images", "links", "counters", "combos", "calculator", "table", "timer", "taskPlanner", "imageAnnotation"].forEach((type) => {
|
||||
["notepad", "checklist", "images", "links", "counters", "combos", "calculator", "table", "timer", "taskPlanner", "equipmentPlanner", "imageAnnotation"].forEach((type) => {
|
||||
assert.ok(payload.toolbox.modules.some((module) => module.type === type), `library must include a ${type} example`);
|
||||
});
|
||||
|
||||
|
|
@ -451,6 +518,12 @@ export function validateLibraryData(payload) {
|
|||
assert.ok(Array.isArray(taskData.tasks), "library task planner example must contain tasks");
|
||||
assert.ok(Array.isArray(taskData.relations), "library task planner example must contain relations");
|
||||
assert.ok(taskData.relations.length >= 1, "library task planner example must include a parent/child relation");
|
||||
|
||||
const equipmentModule = payload.toolbox.modules.find((module) => module.type === "equipmentPlanner");
|
||||
const equipmentData = payload.modules[equipmentModule.id];
|
||||
assert.ok(Array.isArray(equipmentData.types), "library equipment planner example must contain types");
|
||||
assert.ok(Array.isArray(equipmentData.equipments), "library equipment planner example must contain equipments");
|
||||
assert.ok(equipmentData.equipments.some((equipment) => Array.isArray(equipment.socketItems) && equipment.socketItems.length), "library equipment planner example must include socket items");
|
||||
}
|
||||
|
||||
function assertSnakeCase(value, path) {
|
||||
|
|
|
|||
|
|
@ -66,6 +66,9 @@ test("vite entrypoint and app shell are wired", async () => {
|
|||
assert.match(libraryPage, /export function LibraryPage/);
|
||||
assert.match(libraryPage, /LIBRARY_TOOLBOX_ID/);
|
||||
assert.match(libraryPage, /TaskPlannerModule/);
|
||||
assert.match(libraryPage, /EquipmentPlannerModule/);
|
||||
assert.match(libraryPage, /normalizeEquipmentPlannerData/);
|
||||
assert.match(libraryPage, /summarizeEquipmentPlannerData/);
|
||||
assert.match(bodyScrollLock, /modalLocks/);
|
||||
assert.match(bodyScrollLock, /is-modal-open/);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ test("style entrypoint and theme layers are wired", async () => {
|
|||
assert.match(styleIcons, /ui-icon-grab/);
|
||||
assert.match(styleIcons, /ui-icon-shield/);
|
||||
assert.match(styleIcons, /ui-icon-gun/);
|
||||
assert.match(styleToolboxes, /module-icon-chest-armor/);
|
||||
assert.match(styleToolboxes, /\.combo-hold-controls/);
|
||||
assert.match(styleToolboxes, /\.combo-input-direction/);
|
||||
assert.match(styleToolboxes, /\.combo-device-n64\.combo-value-stick-up/);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ test("toolbox storage, cards and pages are wired", async () => {
|
|||
assert.match(toolboxStorage, /export function normalizeTableData/);
|
||||
assert.match(toolboxStorage, /export function normalizeTimerData/);
|
||||
assert.match(toolboxStorage, /export function normalizeTaskPlannerData/);
|
||||
assert.match(toolboxStorage, /export function normalizeEquipmentPlannerData/);
|
||||
assert.match(toolboxStorage, /export function summarizeEquipmentPlannerData/);
|
||||
assert.match(toolboxStorage, /export function normalizeImageAnnotationData/);
|
||||
assert.match(toolboxStorage, /export function compactModuleDataForStorage\(type, value\)/);
|
||||
assert.match(toolboxStorage, /scrollResults/);
|
||||
|
|
@ -108,6 +110,7 @@ test("toolbox module registry and modules expose expected behavior", async () =>
|
|||
const tableFormulaEngine = await readFile("website/src/features/toolboxes/modules/tableFormulaEngine.js", "utf8");
|
||||
const timerModule = await readFile("website/src/features/toolboxes/modules/TimerModule.jsx", "utf8");
|
||||
const taskPlannerModule = await readFile("website/src/features/toolboxes/modules/TaskPlannerModule.jsx", "utf8");
|
||||
const equipmentPlannerModule = await readFile("website/src/features/toolboxes/modules/EquipmentPlannerModule.jsx", "utf8");
|
||||
const checklistModule = await readFile("website/src/features/toolboxes/modules/ChecklistModule.jsx", "utf8");
|
||||
const imagesModule = await readFile("website/src/features/toolboxes/modules/ImagesModule.jsx", "utf8");
|
||||
const imageAnnotationModule = await readFile("website/src/features/toolboxes/modules/ImageAnnotationModule.jsx", "utf8");
|
||||
|
|
@ -133,6 +136,8 @@ test("toolbox module registry and modules expose expected behavior", async () =>
|
|||
assert.match(moduleRegistry, /table: \{ label: "Tableau", icon: "table", Component: TableModule, editable: false, scrollable: true \}/);
|
||||
assert.match(moduleRegistry, /timer:/);
|
||||
assert.match(moduleRegistry, /taskPlanner:/);
|
||||
assert.match(moduleRegistry, /equipmentPlanner:/);
|
||||
assert.match(moduleRegistry, /Planificateur d'équipements/);
|
||||
assert.match(moduleRegistry, /imageAnnotation:/);
|
||||
assert.match(moduleRegistry, /Annotation d'images/);
|
||||
assert.match(moduleRegistry, /editable: false/);
|
||||
|
|
@ -245,6 +250,13 @@ test("toolbox module registry and modules expose expected behavior", async () =>
|
|||
assert.match(taskPlannerModule, /reorderFeatures/);
|
||||
assert.doesNotMatch(taskPlannerModule, /canMoveItem:/);
|
||||
assert.doesNotMatch(taskPlannerModule, /canMoveGroup:/);
|
||||
assert.match(equipmentPlannerModule, /export function EquipmentPlannerModule/);
|
||||
assert.match(equipmentPlannerModule, /normalizeEquipmentPlannerData/);
|
||||
assert.match(equipmentPlannerModule, /summarizeEquipmentPlannerData/);
|
||||
assert.match(equipmentPlannerModule, /socketItems/);
|
||||
assert.match(equipmentPlannerModule, /socketLinks/);
|
||||
assert.match(equipmentPlannerModule, /useGroupedReorder/);
|
||||
assert.match(equipmentPlannerModule, /reorderFeatures/);
|
||||
assert.match(checklistModule, /export function ChecklistModule/);
|
||||
assert.match(checklistModule, /TextImportModal/);
|
||||
assert.match(checklistModule, /Icon name="import"/);
|
||||
|
|
|
|||
|
|
@ -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, normalizeChecklistData, normalizeCombosData, normalizeNotepadData, normalizeTableData, normalizeTaskPlannerData } from "../website/src/features/toolboxes/storage/toolboxStorage.js";
|
||||
import { compactModuleDataForStorage, createToolboxExportPayload, normalizeChecklistData, normalizeCombosData, normalizeEquipmentPlannerData, normalizeNotepadData, normalizeTableData, normalizeTaskPlannerData, summarizeEquipmentPlannerData } from "../website/src/features/toolboxes/storage/toolboxStorage.js";
|
||||
import { applyGroupedReorderOperation, completeGroupOrder, getBoundaryItemId, getGroupedEntries, moveGroupOrder, moveGroupOrderToEnd, moveGroupOrderToStart, moveItem, moveItemGroup } from "../website/src/hooks/useGroupedReorder.js";
|
||||
|
||||
test("colon text import keeps urls intact after the first separator", () => {
|
||||
|
|
@ -96,6 +96,228 @@ test("table storage clamps dimensions and compacts non-empty cells", () => {
|
|||
assert.equal(compactModuleDataForStorage("table", { rows: 10, columns: 6, cells: {} }), null);
|
||||
});
|
||||
|
||||
test("equipment planner storage normalizes sockets, materials and links", () => {
|
||||
const normalized = normalizeEquipmentPlannerData({
|
||||
types: [
|
||||
{ id: "type1", title: "Armes" },
|
||||
{ id: "empty", title: "Vide" }
|
||||
],
|
||||
equipments: [
|
||||
{
|
||||
id: "eq1",
|
||||
typeId: "type1",
|
||||
name: "Épée",
|
||||
active: false,
|
||||
characteristics: [
|
||||
{ id: "trait1", category: "Stats", name: "Force", value: "12" },
|
||||
{ id: "ignored", category: "Stats", name: "", value: 4 }
|
||||
],
|
||||
materials: [
|
||||
{ id: "mat1", name: "Minerai", qty: 0 }
|
||||
],
|
||||
socketItems: [
|
||||
{
|
||||
id: "socket1",
|
||||
name: "Materia feu",
|
||||
shape: "triangle",
|
||||
color: "invalid",
|
||||
bonuses: [
|
||||
{ id: "bonus1", category: "Stats", name: "Force", value: "3" },
|
||||
{ id: "bonus2", category: "Compétences", name: "", value: 1 }
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "socket2",
|
||||
name: "Materia soin",
|
||||
shape: "ball",
|
||||
color: "cyan",
|
||||
bonuses: [
|
||||
{ id: "bonus3", category: "Sorts", name: "Soin", value: "" }
|
||||
]
|
||||
}
|
||||
],
|
||||
socketLinks: [
|
||||
{ id: "link1", fromSocketItemId: "socket1", toSocketItemId: "socket2" },
|
||||
{ id: "duplicate", fromSocketItemId: "socket2", toSocketItemId: "socket1" },
|
||||
{ id: "invalid", fromSocketItemId: "socket1", toSocketItemId: "missing" }
|
||||
],
|
||||
categoryOrder: ["Compétences", "Stats", "Missing"],
|
||||
collapsedCategories: ["Stats", "Missing"]
|
||||
}
|
||||
],
|
||||
typeOrder: ["empty", "type1"]
|
||||
});
|
||||
|
||||
assert.deepEqual(normalized.types.map((type) => type.id), ["type1"]);
|
||||
assert.equal(normalized.equipments[0].active, false);
|
||||
assert.equal(normalized.equipments[0].materials[0].qty, 1);
|
||||
assert.equal(normalized.equipments[0].characteristics.length, 1);
|
||||
assert.equal(normalized.equipments[0].socketItems[0].shape, "jewel");
|
||||
assert.equal(normalized.equipments[0].socketItems[0].color, "yellow");
|
||||
assert.equal(normalized.equipments[0].socketItems[0].bonuses.length, 1);
|
||||
assert.equal(normalized.equipments[0].socketLinks.length, 1);
|
||||
assert.deepEqual(normalized.equipments[0].categoryOrder, ["Stats", "Sorts"]);
|
||||
assert.deepEqual(normalized.equipments[0].collapsedCategories, ["Stats"]);
|
||||
|
||||
const compact = compactModuleDataForStorage("equipmentPlanner", normalized);
|
||||
assert.equal(compact.equipments[0].active, false);
|
||||
assert.equal(compact.equipments[0].socketItems[0].shape, "jewel");
|
||||
assert.equal(compact.equipments[0].socketLinks.length, 1);
|
||||
assert.equal(compactModuleDataForStorage("equipmentPlanner", { types: [{ id: "empty", title: "Vide" }], equipments: [] }), null);
|
||||
});
|
||||
|
||||
test("equipment planner summary only uses active equipments", () => {
|
||||
const summary = summarizeEquipmentPlannerData({
|
||||
types: [{ id: "type1", title: "Build" }],
|
||||
equipments: [
|
||||
{
|
||||
id: "eq1",
|
||||
typeId: "type1",
|
||||
name: "Casque",
|
||||
active: true,
|
||||
characteristics: [{ id: "trait1", category: "Stats", name: "Force", value: 10 }],
|
||||
socketItems: [{
|
||||
id: "socket1",
|
||||
name: "Joyau attaque",
|
||||
shape: "ball",
|
||||
color: "yellow",
|
||||
bonuses: [
|
||||
{ id: "bonus1", category: "Stats", name: "Force", value: 2 },
|
||||
{ id: "bonus2", category: "Affixes", name: "Brutalité", value: "" }
|
||||
]
|
||||
}]
|
||||
},
|
||||
{
|
||||
id: "eq2",
|
||||
typeId: "type1",
|
||||
name: "Armure",
|
||||
active: false,
|
||||
characteristics: [{ id: "trait2", category: "Stats", name: "Force", value: 99 }]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
assert.equal(summary.activeEquipmentCount, 1);
|
||||
assert.deepEqual(summary.totals, [{
|
||||
name: "Force",
|
||||
icon: "sword",
|
||||
sourceKind: "mixed",
|
||||
contributions: [
|
||||
{ id: "trait1", sourceKind: "direct", equipmentIcon: "shield", equipmentName: "Casque", sourceName: "Casque", value: 10 },
|
||||
{ id: "bonus1", sourceKind: "socket", equipmentIcon: "shield", equipmentName: "Casque", sourceName: "Casque · Joyau attaque", value: 2 }
|
||||
],
|
||||
value: 12
|
||||
}]);
|
||||
assert.deepEqual(summary.equipmentTotals, []);
|
||||
assert.deepEqual(summary.socketTotals, []);
|
||||
assert.deepEqual(summary.mixedTotals, summary.totals);
|
||||
assert.equal(summary.textBonuses.length, 1);
|
||||
assert.equal(summary.textBonuses[0].name, "Brutalité");
|
||||
});
|
||||
|
||||
test("equipment planner summary prioritizes direct stat icons over socket icons", () => {
|
||||
const summary = summarizeEquipmentPlannerData({
|
||||
types: [{ id: "type1", title: "Build" }],
|
||||
equipments: [
|
||||
{
|
||||
id: "eq1",
|
||||
typeId: "type1",
|
||||
name: "Épée",
|
||||
characteristics: [{ id: "trait1", category: "Stats", icon: "shield", name: "Attaque", value: 100 }],
|
||||
socketItems: [{
|
||||
id: "socket1",
|
||||
name: "Joyau rouge",
|
||||
shape: "jewel",
|
||||
color: "red",
|
||||
bonuses: [
|
||||
{ id: "bonus1", category: "Stats", name: "Attaque", value: 10 },
|
||||
{ id: "bonus2", category: "Compétences", name: "Attaque de feu", value: 1 }
|
||||
]
|
||||
}]
|
||||
},
|
||||
{
|
||||
id: "eq2",
|
||||
typeId: "type1",
|
||||
name: "Fusil",
|
||||
characteristics: [
|
||||
{ id: "trait2", category: "Stats", icon: "sword", name: "Défense", value: 10 },
|
||||
{ id: "trait3", category: "Stats", icon: "sword", name: "Défense", value: 20 },
|
||||
{ id: "trait4", category: "Stats", icon: "shield", name: "Défense", value: 30 }
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
assert.deepEqual(summary.totals.find((total) => total.name === "Attaque"), {
|
||||
name: "Attaque",
|
||||
icon: "shield",
|
||||
sourceKind: "mixed",
|
||||
contributions: [
|
||||
{ id: "trait1", sourceKind: "direct", equipmentIcon: "shield", equipmentName: "Épée", sourceName: "Épée", value: 100 },
|
||||
{ id: "bonus1", sourceKind: "socket", equipmentIcon: "shield", equipmentName: "Épée", sourceName: "Épée · Joyau rouge", value: 10 }
|
||||
],
|
||||
value: 110
|
||||
});
|
||||
assert.deepEqual(summary.totals.find((total) => total.name === "Attaque de feu"), {
|
||||
name: "Attaque de feu",
|
||||
icon: "jewel",
|
||||
color: "red",
|
||||
sourceKind: "socket",
|
||||
contributions: [{ id: "bonus2", sourceKind: "socket", equipmentIcon: "shield", equipmentName: "Épée", sourceName: "Épée · Joyau rouge", value: 1 }],
|
||||
value: 1
|
||||
});
|
||||
assert.deepEqual(summary.totals.find((total) => total.name === "Défense"), {
|
||||
name: "Défense",
|
||||
icon: "sword",
|
||||
sourceKind: "direct",
|
||||
contributions: [
|
||||
{ id: "trait2", sourceKind: "direct", equipmentIcon: "shield", equipmentName: "Fusil", sourceName: "Fusil", value: 10 },
|
||||
{ id: "trait3", sourceKind: "direct", equipmentIcon: "shield", equipmentName: "Fusil", sourceName: "Fusil", value: 20 },
|
||||
{ id: "trait4", sourceKind: "direct", equipmentIcon: "shield", equipmentName: "Fusil", sourceName: "Fusil", value: 30 }
|
||||
],
|
||||
value: 60
|
||||
});
|
||||
assert.deepEqual(summary.equipmentTotals.map((total) => total.name), ["Défense"]);
|
||||
assert.deepEqual(summary.socketTotals.map((total) => total.name), ["Attaque de feu"]);
|
||||
assert.deepEqual(summary.mixedTotals.map((total) => total.name), ["Attaque"]);
|
||||
});
|
||||
|
||||
test("equipment planner export remaps nested ids and socket links", () => {
|
||||
const payload = createToolboxExportPayload(
|
||||
{
|
||||
id: "toolbox1",
|
||||
name: "Build",
|
||||
modules: [{ id: "module1", type: "equipmentPlanner" }]
|
||||
},
|
||||
{
|
||||
"toolbox1:module1": {
|
||||
types: [{ id: "type1", title: "Build" }],
|
||||
equipments: [{
|
||||
id: "eq1",
|
||||
typeId: "type1",
|
||||
name: "Casque",
|
||||
characteristics: [{ id: "trait1", name: "Force", value: 1 }],
|
||||
materials: [{ id: "mat1", name: "Minerai", qty: 2 }],
|
||||
socketItems: [
|
||||
{ id: "socket1", name: "Joyau attaque", shape: "ball", color: "yellow", bonuses: [{ id: "bonus1", name: "Attaque", value: 1 }] },
|
||||
{ id: "socket2", name: "Joyau expert", shape: "jewel", color: "cyan", bonuses: [] }
|
||||
],
|
||||
socketLinks: [{ id: "link1", fromSocketItemId: "socket1", toSocketItemId: "socket2" }]
|
||||
}],
|
||||
typeOrder: ["type1"]
|
||||
}
|
||||
}
|
||||
);
|
||||
const moduleId = payload.toolbox.modules[0].id;
|
||||
const exported = payload.modules[moduleId];
|
||||
|
||||
assert.notEqual(exported.types[0].id, "type1");
|
||||
assert.equal(exported.equipments[0].typeId, exported.types[0].id);
|
||||
assert.notEqual(exported.equipments[0].socketItems[0].id, "socket1");
|
||||
assert.equal(exported.equipments[0].socketLinks[0].fromSocketItemId, exported.equipments[0].socketItems[0].id);
|
||||
assert.equal(exported.equipments[0].socketLinks[0].toSocketItemId, exported.equipments[0].socketItems[1].id);
|
||||
});
|
||||
|
||||
test("grouped reorder helpers group flat items and complete group order", () => {
|
||||
const items = [
|
||||
{ id: "a", category: "" },
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue