49 lines
3.2 KiB
JavaScript
49 lines
3.2 KiB
JavaScript
// Uji otomatis satu perintah (RENCANA 5.4): node tests/all.mjs
|
|
// 1. sintaks node --check untuk semua berkas JS proyek (game, menu, konten, manifest karakter, uji); cepat, tanpa peramban
|
|
// 2. smoke node tests/harness.mjs smoke 7 karakter x easy/hard melawan CPU, gagal bila ada galat halaman
|
|
// 3. pasangan node tests/harness.mjs tests/pairs.mjs 49 pasangan arah dimainkan singkat oleh bot, galat konsol, jurus terpakai, data TIERS, Koleksi
|
|
// Keluar dengan kode 0 bila semuanya lolos, 1 bila ada yang gagal. Tidak mengubah berkas apa pun.
|
|
// Env: ALL_SKIP=sintaks,smoke,pasangan (lewati langkah) PAIRS_SECONDS (detik permainan per pasangan, bawaan 24) PW_CORE, CHROME_BIN, HEADED seperti tests/harness.mjs
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { spawnSync } from 'node:child_process';
|
|
|
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
const skip = new Set((process.env.ALL_SKIP || '').split(',').map(x => x.trim()).filter(Boolean));
|
|
const run = (args, opt = {}) => spawnSync(process.execPath, args, { cwd: root, encoding: 'utf8', maxBuffer: 64 << 20, ...opt });
|
|
const tail = (text, n) => String(text || '').trim().split('\n').slice(-n).join('\n');
|
|
|
|
// berkas JS yang diperiksa sintaksnya: tingkat atas, content/, manifest karakter, dan uji
|
|
function jsFiles() {
|
|
const out = [];
|
|
for (const f of fs.readdirSync(root)) if (/\.(js|mjs)$/.test(f)) out.push(f);
|
|
for (const dir of ['content', 'tests', 'tools']) if (fs.existsSync(path.join(root, dir))) for (const f of fs.readdirSync(path.join(root, dir))) if (/\.(js|mjs)$/.test(f)) out.push(`${dir}/${f}`);
|
|
for (const d of fs.readdirSync(path.join(root, 'assets'))) { const m = `assets/${d}/manifest.js`; if (fs.existsSync(path.join(root, m))) out.push(m); }
|
|
return out.sort();
|
|
}
|
|
|
|
const steps = [
|
|
['sintaks', () => {
|
|
const bad = [], files = jsFiles();
|
|
for (const f of files) { const r = run(['--check', f]); if (r.status !== 0) bad.push(`${f}: ${tail(r.stderr, 3)}`); }
|
|
return { ok: !bad.length, text: bad.length ? bad.join('\n') : `${files.length} berkas JS lolos node --check` };
|
|
}],
|
|
['smoke', () => { const r = run(['tests/harness.mjs', 'smoke']); return { ok: r.status === 0, text: tail(r.stdout + r.stderr, r.status === 0 ? 2 : 25) }; }],
|
|
['pasangan', () => { const r = run(['tests/harness.mjs', 'tests/pairs.mjs']); return { ok: r.status === 0, text: tail(r.stdout + r.stderr, r.status === 0 ? 8 : 30) }; }]
|
|
];
|
|
|
|
const rows = [];
|
|
for (const [name, fn] of steps) {
|
|
if (skip.has(name)) { rows.push([name, 'DILEWATI', 0, '']); continue; }
|
|
const t = Date.now(); let res;
|
|
try { res = fn(); } catch (e) { res = { ok: false, text: String(e.stack || e) }; }
|
|
const dt = (Date.now() - t) / 1000;
|
|
rows.push([name, res.ok ? 'LOLOS' : 'GAGAL', dt, res.text]);
|
|
console.log(`\n== ${name}: ${res.ok ? 'LOLOS' : 'GAGAL'} (${dt.toFixed(1)} dtk)\n${res.text}`);
|
|
}
|
|
const failed = rows.filter(r => r[1] === 'GAGAL');
|
|
console.log('\nRingkasan: ' + rows.map(r => `${r[0]} ${r[1]}${r[1] === 'DILEWATI' ? '' : ` (${r[2].toFixed(1)} dtk)`}`).join(' | '));
|
|
console.log(failed.length ? `ADA YANG GAGAL: ${failed.map(r => r[0]).join(', ')}` : 'SEMUA UJI LOLOS');
|
|
process.exit(failed.length ? 1 : 0);
|