This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
// 起動に失敗したとき、その理由が画面に出ることを守るテスト (#1235)。
|
||||
//
|
||||
// 起動を断る判定は 3 行以上の本文で「なぜ止めたか」と「どう直すか」を書く。
|
||||
// ところが致命的な例外は `src/main.ts` の最上位ハンドラが `err.stack` ごと
|
||||
// 1 レコードで書き出すので、記録の並びは【本文】→【呼び出し位置の羅列】になる。
|
||||
// `scripts/server.sh` が末尾 5 行しか出さないと、出るのは呼び出し位置だけで、
|
||||
// 肝心の本文は画面から溢れる。直し方が書いてあるのに管理者には見えない。
|
||||
//
|
||||
// だからここで守るのは「行数の数字」ではなく、**本文が収まる幅が残っていること**。
|
||||
// 末尾の行数を減らす変更は、ここで落ちる。
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { dirname, join } from 'node:path';
|
||||
|
||||
const repoRoot = join(dirname(fileURLToPath(import.meta.url)), '..');
|
||||
|
||||
/** 起動失敗の案内は最長で 4 行。加えてスタックの見出しと呼び出し位置が続く。 */
|
||||
const MIN_TAIL_LINES = 20;
|
||||
|
||||
describe('起動失敗時の出力 (#1235)', () => {
|
||||
it('server.sh の起動失敗は、案内の本文が収まる行数を出す', () => {
|
||||
const sh = readFileSync(join(repoRoot, 'scripts', 'server.sh'), 'utf8');
|
||||
const failureBlock = sh.slice(sh.indexOf('Server failed to start'));
|
||||
const tail = /tail\s+(?:-n\s*)?-?(\d+)\s+"\$LOG_FILE"/.exec(failureBlock);
|
||||
expect(tail).not.toBeNull();
|
||||
expect(Number(tail![1])).toBeGreaterThanOrEqual(MIN_TAIL_LINES);
|
||||
});
|
||||
|
||||
it('起動を断る本文とスタックの合計が、その行数に収まる', () => {
|
||||
// 本文の行数は実物から数える。文面を伸ばしたときに、この歯止めが
|
||||
// 一緒に見直されるようにするため。
|
||||
const src = readFileSync(join(repoRoot, 'src', 'worker-bootstrap.ts'), 'utf8');
|
||||
// throw new Error(`...`) のテンプレートリテラルに含まれる改行の数。
|
||||
const refusals = src.match(/throw new Error\(\s*`[\s\S]*?\)\s*;/g) ?? [];
|
||||
expect(refusals.length).toBeGreaterThan(0);
|
||||
const longest = Math.max(...refusals.map((r) => (r.match(/\\n/g) ?? []).length + 1));
|
||||
// スタックの見出し 1 行 + 呼び出し位置の余裕。
|
||||
expect(longest + 10).toBeLessThanOrEqual(MIN_TAIL_LINES);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user