完成50%
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
"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);
|
||||
});
|
||||
Reference in New Issue
Block a user