Files

137 lines
6.6 KiB
JavaScript

// Official battlefield scenes in the 0.2.5 asset pack (PR #533, GitHub #532).
// The repository never stores the bundles or the extracted files. The full release zip includes
// public/assets/local/scene when the maintainer extracted it; a lite zip and a source install do not,
// and setup may fetch + extract on that machine. Missing extractor dependencies keep the metal board.
import { test } from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { artPlan, formatSummary, isPlayerFile, isRefused } from '../tools/package.mjs';
import { localGaps, sceneInstallPlan } from '../tools/setup.mjs';
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
test('sceneInstallPlan: fetch only with a client and extractor deps; otherwise the metal board', () => {
const present = sceneInstallPlan({ hasScenes: true, client: false });
assert.equal(present.run, false);
assert.equal(present.state, 'ok');
assert.match(present.detail, /金属地块/);
const check = sceneInstallPlan({ hasScenes: false, check: true, client: true, python: true });
assert.equal(check.run, false);
assert.equal(check.state, 'skip');
assert.match(check.detail, /--scenes/);
assert.match(check.detail, /金属地块/);
const noClient = sceneInstallPlan({ hasScenes: false, client: false, python: true });
assert.equal(noClient.run, false);
assert.equal(noClient.state, 'skip');
assert.match(noClient.detail, /完整包/);
assert.match(noClient.detail, /金属地块/);
const incomplete = sceneInstallPlan({ hasScenes: false, client: 'incomplete', python: true, force: true });
assert.equal(incomplete.run, false);
assert.equal(incomplete.state, 'warn');
assert.match(incomplete.detail, /金属地块/);
const noPy = sceneInstallPlan({ hasScenes: false, client: true, python: false });
assert.equal(noPy.run, false);
assert.equal(noPy.state, 'warn');
assert.match(noPy.detail, /Python/);
assert.match(noPy.detail, /金属地块/);
const noDeps = sceneInstallPlan({ hasScenes: false, client: true, python: true, deps: false });
assert.equal(noDeps.run, false);
assert.equal(noDeps.state, 'warn');
assert.match(noDeps.detail, /UnityPy/);
assert.match(noDeps.detail, /金属地块/);
const declined = sceneInstallPlan({ hasScenes: false, client: true, python: true, declined: true });
assert.equal(declined.run, false);
assert.equal(declined.state, 'skip');
const ask = sceneInstallPlan({ hasScenes: false, client: true, python: true });
assert.equal(ask.run, false);
assert.equal(ask.state, 'ask');
assert.match(ask.detail, /金属地块/);
for (const extra of [{ force: true, declined: true }, { yes: true }]) {
const go = sceneInstallPlan({ hasScenes: false, client: true, python: true, ...extra });
assert.equal(go.run, true, JSON.stringify(extra));
assert.match(go.detail, /金属地块/);
}
});
test('an older extraction is told it lacks the battlefield scenes', () => {
assert.equal(localGaps({ enemySpines: true, tokenSpines: true }), '');
assert.match(localGaps({ enemySpines: true, tokenSpines: true, scenes: false }), /各战场官方场景/);
assert.match(localGaps({ enemySpines: false, tokenSpines: false, scenes: false }), /各战场官方场景/);
});
test('official scene bundles and extracted scenes are not git files; the extractor scripts are', () => {
const gi = fs.readFileSync(path.join(ROOT, '.gitignore'), 'utf8');
assert.match(gi, /^public\/assets\/$/m);
assert.match(gi, /^data\/local-assets\.json$/m);
assert.match(gi, /^\.cache\/$/m);
assert.match(gi, /official-scenes/);
assert.equal(isRefused('.cache/official-scenes/26-04-13-12-31-42_e9b560/scenes/a.ab'), true);
assert.equal(isRefused('public/assets/local/scene/act2autochess_m02/scene.bin'), false);
assert.equal(isPlayerFile('public/assets/local/scene/act2autochess_m02/scene.bin'), false);
assert.equal(isPlayerFile('tools/local-extract/scenes.py'), true);
assert.equal(isPlayerFile('tools/local-extract/fetch_scenes.py'), true);
});
test('the full asset plan ships extracted scenes; the lite plan ships none', () => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'sp-scenes-'));
try {
const sceneDir = path.join(dir, 'public/assets/local/scene/act2autochess_m02');
const texDir = path.join(dir, 'public/assets/local/scene/tex');
fs.mkdirSync(sceneDir, { recursive: true });
fs.mkdirSync(texDir, { recursive: true });
fs.mkdirSync(path.join(dir, 'data'), { recursive: true });
fs.writeFileSync(path.join(dir, 'data/assets.json'), '{}\n');
fs.writeFileSync(path.join(sceneDir, 'scene.bin'), 'mesh-bytes');
fs.writeFileSync(path.join(sceneDir, 'scene.json'), '{}\n');
fs.writeFileSync(path.join(texDir, 'TX_A.webp'), 'webp');
fs.writeFileSync(path.join(dir, 'data/local-assets.json'), JSON.stringify({
version: 1,
groups: {
'scene/act2autochess_m02': {
scene: { path: '/assets/local/scene/act2autochess_m02/scene.json' },
bin: { path: '/assets/local/scene/act2autochess_m02/scene.bin' },
},
'scene/tex': { TX_A: { path: '/assets/local/scene/tex/TX_A.webp' } },
},
}));
const full = artPlan(dir, { lite: false });
for (const f of [
'public/assets/local/scene/act2autochess_m02/scene.bin',
'public/assets/local/scene/act2autochess_m02/scene.json',
'public/assets/local/scene/tex/TX_A.webp',
'data/local-assets.json',
]) assert.ok(full.files.includes(f), f);
assert.ok(full.scenes.includes('public/assets/local/scene/act2autochess_m02/scene.bin'));
assert.equal(full.scenes.length, 3);
const lite = artPlan(dir, { lite: true });
assert.deepEqual(lite.files, []);
assert.deepEqual(lite.scenes, []);
const summary = formatSummary({
lite: false, version: '0.2.5-dev', tracked: [], art: [], localArt: true, generated: [], dropped: {}, orphans: [], held: [],
scanned: 0, names: 0, problems: [], scenes: { files: full.scenes, bytes: 9 + 3 + 4 },
bytes: { tracked: 0, art: 16, modules: 0, vendor: 0, total: 16, leftOut: 0, orphans: 0 },
});
assert.match(summary, /battlefield scenes: 3 files/);
const empty = formatSummary({
lite: false, version: '0.2.5-dev', tracked: [], art: [], localArt: true, generated: [], dropped: {}, orphans: [], held: [],
scanned: 0, names: 0, problems: [], scenes: { files: [], bytes: 0 },
bytes: { tracked: 0, art: 0, modules: 0, vendor: 0, total: 0, leftOut: 0, orphans: 0 },
});
assert.match(empty, /battlefield scenes: none/);
} finally {
fs.rmSync(dir, { recursive: true, force: true });
}
});