Files
jiapuapp/tests/generation-poem-runtime-smoke.js
T
2026-07-23 08:24:07 +08:00

255 lines
7.1 KiB
JavaScript

"use strict";
const assert = require("assert");
const fs = require("fs");
const path = require("path");
const run = async () => {
const source = fs.readFileSync(
path.join(__dirname, "../utils/generation-poem.js"),
"utf8",
);
const moduleUrl = `data:text/javascript;base64,${Buffer.from(source).toString("base64")}`;
const {
MAX_GENERATION_NO,
MAX_GENERATION_COUNT,
MAX_GENERATION_TEXT_LENGTH,
MAX_GENERATION_POEM_INPUT_LENGTH,
GENERATION_POEM_STATUS,
normalizeGenerationNumber,
validateGenerationPoemText,
findFirstGenerationGap,
mergeGenerationPoemRows,
} = await import(moduleUrl);
assert.strictEqual(MAX_GENERATION_COUNT, 500);
assert.strictEqual(MAX_GENERATION_TEXT_LENGTH, 50);
assert.strictEqual(MAX_GENERATION_POEM_INPUT_LENGTH, 26000);
assert.deepStrictEqual(GENERATION_POEM_STATUS, {
ACTIVE: "0",
DISABLED: "1",
});
assert.strictEqual(normalizeGenerationNumber(undefined, 12), 12);
assert.strictEqual(normalizeGenerationNumber("300", 12), 300);
for (const invalid of [
"0",
"1.5",
"1e2",
"Infinity",
Infinity,
NaN,
MAX_GENERATION_NO + 1,
]) {
assert.strictEqual(
normalizeGenerationNumber(invalid, 12),
null,
`非法代次未拒绝:${invalid}`,
);
}
assert.deepStrictEqual(validateGenerationPoemText("启宗敦本").generations, [
"启",
"宗",
"敦",
"本",
]);
assert.deepStrictEqual(
validateGenerationPoemText("克勤 克俭,承先;启后、敦本/睦族|传芳").generations,
["克勤", "克俭", "承先", "启后", "敦本", "睦族", "传芳"],
"OpenAPI 声明的分隔符必须统一解析多字字辈",
);
assert.deepStrictEqual(
validateGenerationPoemText("德承家亦\n忠厚传芳").generations,
["德承家亦", "忠厚传芳"],
);
assert.strictEqual(
validateGenerationPoemText("𠀀").valid,
true,
"扩展区字符必须按一个 code point 计数",
);
assert.strictEqual(validateGenerationPoemText("").valid, false);
assert.strictEqual(validateGenerationPoemText("启".repeat(501)).valid, false);
assert.strictEqual(
validateGenerationPoemText(`${"启".repeat(51)} 宗`).valid,
false,
);
assert.strictEqual(
validateGenerationPoemText("启".repeat(MAX_GENERATION_POEM_INPUT_LENGTH + 1)).valid,
false,
);
assert.throws(
() =>
mergeGenerationPoemRows({
existingRows: [],
generationTexts: ["启", "宗"],
startGeneration: MAX_GENERATION_NO,
currentGeneration: MAX_GENERATION_NO,
disableMissing: false,
}),
/超出支持范围/,
);
assert.throws(
() =>
mergeGenerationPoemRows({
existingRows: [],
generationTexts: Array.from({ length: 501 }, () => "启"),
startGeneration: 1,
currentGeneration: 1,
disableMissing: false,
}),
/最多 500 个世代/,
);
assert.throws(
() =>
mergeGenerationPoemRows({
existingRows: [],
generationTexts: ["启"],
startGeneration: 1,
currentGeneration: 1,
disableMissing: "false",
}),
/disableMissing/,
);
const contiguous = [
{ generationNo: 12, generationText: "启", status: "0" },
{ generationNo: 13, generationText: "宗", status: "0" },
{ generationNo: 14, generationText: "敦", status: "0" },
];
assert.strictEqual(findFirstGenerationGap(contiguous, 15), null);
assert.strictEqual(
findFirstGenerationGap([contiguous[0], contiguous[2]], 15),
13,
"历史缺口必须定位到首个缺失世代",
);
assert.strictEqual(
findFirstGenerationGap([{ generationNo: 5, status: "0" }], 6, 1),
1,
"完整序列必须从第一世检查前缀缺口",
);
assert.strictEqual(
findFirstGenerationGap(
[
{ generationNo: 1, status: "0" },
{ generationNo: 2, status: "0" },
{ generationNo: 5, status: "0" },
],
6,
1,
),
3,
"保留后续 ACTIVE 记录时不能留下中间缺口",
);
assert.strictEqual(
findFirstGenerationGap(
[
{ generationNo: 1, status: "0" },
{ generationNo: 2, status: "1" },
{ generationNo: 3, status: "0" },
],
4,
1,
),
2,
"DISABLED 记录不能填补 ACTIVE 序列缺口",
);
assert.throws(
() =>
mergeGenerationPoemRows({
existingRows: [
{ generationNo: 1, generationText: "启", status: "UNKNOWN" },
],
generationTexts: ["宗"],
startGeneration: 2,
currentGeneration: 2,
disableMissing: false,
}),
/GenerationPoemView/,
);
assert.throws(
() =>
mergeGenerationPoemRows({
existingRows: [
{ generationNo: 1, generationText: "启", status: "0" },
{ generationNo: 1, generationText: "宗", status: "1" },
],
generationTexts: ["敦"],
startGeneration: 2,
currentGeneration: 2,
disableMissing: false,
}),
/重复的世代记录/,
"同一世代存在多条记录时必须失败关闭,不能静默 last-wins",
);
const preserved = mergeGenerationPoemRows({
existingRows: [
...contiguous,
{ poemId: "9007199254740993", generationNo: 15, generationText: "本", status: "0" },
{ generationNo: 16, generationText: "继", status: "0" },
],
generationTexts: ["克勤"],
startGeneration: 15,
currentGeneration: 15,
disableMissing: false,
});
assert.deepStrictEqual(
preserved.map(({ generationNo, generationText, status }) => ({
generationNo,
generationText,
status,
})),
[
{ generationNo: 12, generationText: "启", status: "0" },
{ generationNo: 13, generationText: "宗", status: "0" },
{ generationNo: 14, generationText: "敦", status: "0" },
{ generationNo: 15, generationText: "克勤", status: "0" },
{ generationNo: 16, generationText: "继", status: "0" },
],
);
assert.strictEqual(
preserved.find((row) => row.generationNo === 15)?.poemId,
"9007199254740993",
"覆盖文字时必须保留词法 int64 记录身份",
);
const disabled = mergeGenerationPoemRows({
existingRows: preserved,
generationTexts: ["昭穆"],
startGeneration: 15,
currentGeneration: 15,
disableMissing: true,
});
assert.strictEqual(
disabled.find((row) => row.generationNo === 12)?.generationText,
"启",
);
assert.strictEqual(
disabled.find((row) => row.generationNo === 16)?.status,
"1",
);
assert.strictEqual(
disabled.find((row) => row.generationNo === 16)?.generationText,
"继",
);
const maximumBatch = mergeGenerationPoemRows({
existingRows: [],
generationTexts: Array.from({ length: MAX_GENERATION_COUNT }, () => "启"),
startGeneration: 1,
currentGeneration: 500,
disableMissing: false,
});
assert.strictEqual(maximumBatch.length, 500);
assert.strictEqual(maximumBatch[499].generationNo, 500);
assert.strictEqual(maximumBatch[499].current, true);
process.stdout.write("GENERATION-POEM-RUNTIME-SMOKE PASS\n");
};
run().catch((error) => {
process.stderr.write(`${error.stack || error.message}\n`);
process.exit(1);
});