Files
Currency-War-SR/tools/gridfight-extract-node/cwmech.test.mjs
T
2026-10-30 23:54:07 +07:00

60 lines
3.4 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
const read = name => JSON.parse(fs.readFileSync(new URL('../../resources/grid_fight/' + name, import.meta.url)));
const special = read('special-units.raw.json');
const mechanics = read('mechanics-4654.raw.json');
test('CW MECH 4.6.54 decoded Aha family excludes the obsolete three-cost form', () => {
const rows = special.GridFightRoleConfigRow.filter(r => r.AvatarID === 1511 && r.SeasonID === 2);
assert.deepEqual(rows.map(r => [r.ID, r.Rarity]), [[151112, 4], [151122, 5], [151132, 5]]);
const noStars = mechanics.ConstValueCommonRow.find(r => r.ConstValueName === 'GridFight_Aha_No_Star_Role_IDList');
assert.deepEqual(noStars.Value.value.map(r => r.value), [151112, 151122]);
assert.equal(mechanics.ConstValueCommonRow.find(r => r.ConstValueName === 'GridFight_Aha_Level_SavedValueKey').Value.value, 'GP_Avatar_S2_Aha_00');
});
test('CW MECH restaurant menus retain native weights and signature component pairs', () => {
const menus = mechanics.GridFightTraitEquipTemplateConfigRow.filter(r => r.TraitID === 101202);
assert.equal(menus.length, 20);
assert.equal(new Set(menus.map(r => r.TemplateID)).size, 20);
for (const menu of menus) {
assert.ok([25, 50, 100].includes(menu.Weight));
assert.equal(menu.EquipList.length, 2);
for (const id of menu.EquipList) assert.ok(special.GridFightEquipConfigRow.some(e => e.ID === id));
}
assert.ok(special.GridFightRoleConfigRow.find(r => r.ID === 141502).TraitList.includes(101202));
});
test('CW MECH Twin Dragons IDs come from effect 3001022 rather than avatar-ID arithmetic', () => {
const pair = special.GridFightTraitEffectLayerParamConfigRow.find(r => r.ID === 3001022 && r.Layer === 1);
assert.deepEqual(pair.EffectParamList.map(p => p.wire / 2 ** 34), [121302, 141402]);
for (const id of [121302, 141402]) assert.ok(special.GridFightRoleConfigRow.find(r => r.ID === id).TraitList.includes(300102));
});
test('CW MECH additional tables retain complete client-asset round-trip proofs', () => {
const proof = read('mechanics-4654-provenance.json');
assert.equal(proof.game_assembly_sha256, '4aa08a0706f27d2cf9951b61920c179140ece9ea94f7e34422c18e46922939b6');
assert.ok(proof.tables.length >= 7);
for (const p of proof.tables) {
assert.equal(p.round_trip, true);
assert.match(p.asset_sha256, /^[a-f0-9]{64}$/);
}
});
test('CW MECH takeover chip contains stat properties, not a decoded budget or payout specification', () => {
const chip = special.GridFightEquipConfigRow.find(r => r.ID === 353601);
assert.equal(chip.ParamList.length, 6);
assert.equal(chip.GeneralPropertyList.length, 6);
assert.ok(chip.ParamList.every(p => Math.abs(p.wire / 2 ** 34 - 0.99) < 1e-8));
assert.equal(chip.JsonPath, 'Config/Level/GridFight/Equip/GridFightEquip353601.json');
});
test('CW MECH future-node weakening preserves native reduction tiers independently of Trotter data', () => {
for (const [id, reduction] of [[353303, 0.08], [353403, 0.12], [353503, 0.16]]) {
const chip = special.GridFightEquipConfigRow.find(r => r.ID === id);
for (const p of chip.ParamList.slice(1)) assert.ok(Math.abs(p.wire / 2 ** 34 - reduction) < 1e-8);
}
assert.equal(special.GridFightEquipConfigRow.find(r => r.ID === 353405).ParamList.length, 1);
assert.equal(special.GridFightEquipConfigRow.find(r => r.ID === 353505).ParamList.length, 2);
});