59 lines
4.3 KiB
JavaScript
59 lines
4.3 KiB
JavaScript
// test/ui/ammo-count.test.js — 设置「弹药数量」 (PR #552 by @IceCodeNew, ported in 0.2.6, DESIGN §31.9): the remaining ammo
|
|
// count under an ammo skill's bar is not part of the official HUD, so it is an option, off by default (the maintainer's
|
|
// decision of 2026-10-13, like 「官方伤害数字」). Settings normalisation, the dialog's toggle and its hint in every language
|
|
// pack, the field view's live setting, the diagnostics line. What the renderer draws: test/render/hud-readouts.test.js.
|
|
// Run: node --test test/ui/ammo-count.test.js
|
|
|
|
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { readFileSync } from 'node:fs';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { sanitizeSettings, DEFAULT_SETTINGS } from '../../public/js/ui/gameLogic.js';
|
|
import { buildDiagnostics } from '../../public/js/diag.js';
|
|
|
|
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
|
|
const read = (p) => readFileSync(path.join(ROOT, p), 'utf8');
|
|
const LABEL = '弹药数量';
|
|
const HINT = '弹药类技能开启时,在弹药条下方显示剩余弹药 / 总弹药数(如 13/14)。官方界面没有这个数字。';
|
|
|
|
test('ammoCount is stored with the other settings: off by default and for a profile saved before it, a boolean kept, junk off', () => {
|
|
assert.equal(DEFAULT_SETTINGS.ammoCount, false);
|
|
assert.equal(sanitizeSettings(null).ammoCount, false);
|
|
assert.equal(sanitizeSettings({ bgm: 0.4, officialDamageNumbers: true }).ammoCount, false, 'a profile saved before 0.2.6');
|
|
assert.equal(sanitizeSettings({ ammoCount: true }).ammoCount, true);
|
|
assert.equal(sanitizeSettings({ ammoCount: false }).ammoCount, false);
|
|
for (const bad of ['true', 1, 0, null, {}, []]) assert.equal(sanitizeSettings({ ammoCount: bad }).ammoCount, false, JSON.stringify(bad));
|
|
// independent of the damage-number switches
|
|
assert.deepEqual(sanitizeSettings({ ammoCount: true, damageNumbers: false, officialDamageNumbers: true }), { ...sanitizeSettings({ damageNumbers: false, officialDamageNumbers: true }), ammoCount: true });
|
|
});
|
|
|
|
test('the settings dialog has the toggle and a hint that the official interface has no such number, in every language pack', () => {
|
|
const src = read('public/js/ui/settings.js');
|
|
assert.match(src, /<\$\{Toggle\} label=\$\{t\('弹药数量'\)\} micro="AMMO COUNT" value=\$\{s\.ammoCount\} onChange=\$\{\(v\) => updateSettings\(\{ ammoCount: v \}\)\} \/>/);
|
|
assert.ok(src.includes(`t('${HINT}')`), 'the hint under it');
|
|
assert.ok(src.indexOf("t('官方伤害数字')") < src.indexOf(`t('${LABEL}')`), 'beside the damage-number options');
|
|
for (const lang of ['en', 'ja', 'ko', 'zh-TW']) {
|
|
const pack = JSON.parse(read(`public/i18n/${lang}.json`));
|
|
for (const id of [LABEL, HINT]) assert.ok(typeof pack[id] === 'string' && pack[id].length > 0, `${lang}: ${id}`);
|
|
assert.match(pack[HINT], /13\/14/, `${lang}: the example count`);
|
|
}
|
|
});
|
|
|
|
test('the field view takes the setting at creation and live (setSettings); the units read it from their shared settings', () => {
|
|
const app = read('public/js/render/app.js');
|
|
assert.match(app, /const settings = \{ damageNumbers: true, officialDamageNumbers: false, ammoCount: false, quality: 'high', \.\.\.\(opts\.settings \|\| \{\}\) \};/);
|
|
assert.match(app, /if \(typeof s\.ammoCount === 'boolean'\) settings\.ammoCount = s\.ammoCount;/);
|
|
const units = read('public/js/render/units.js');
|
|
assert.match(units, /this\._updateAmmoCount\(showSp && !!ammo && this\.ctx\.settings\?\.ammoCount === true, x0 \+ bw \/ 2, rowsTop, s\)/);
|
|
// the simplified board draws no ammo bar (its SP bar is the tuple's SP), so it has nothing to count under
|
|
assert.doesNotMatch(read('public/js/ui/fallbackField.js'), /ammo/);
|
|
});
|
|
|
|
test('the diagnostics name the option when it is on', () => {
|
|
const state = { me: {}, room: null, match: { public: null, battle: null }, connection: { status: 'online' } };
|
|
const line = (settings) => buildDiagnostics({ state, env: {}, settings }).split('\n').find((l) => l.startsWith('settings:'));
|
|
assert.equal(line({ quality: 'high', damageNumbers: true, ammoCount: true }), 'settings: quality high | damage numbers | ammo count');
|
|
assert.equal(line({ quality: 'high', damageNumbers: true, ammoCount: false }), 'settings: quality high | damage numbers');
|
|
});
|