60 lines
3.4 KiB
JavaScript
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);
|
|
});
|