Files
auv/tests/get-stock-board-repro.mjs
T
SakurasanandClaude a6497caf73 fix: 无领涨股题材导致/themes页面崩溃(startsWith null)
东方财富题材列表存在 securityCode 为 null 的题材(如"铟"01726),
getStockBoard(null) 调用 startsWith 抛 TypeError,React 渲染崩溃,
页面被错误边界接管。修复 getStockBoard 使其对空值兜底返回主板,
同时保护全部 8 处调用方;ThemeItem.securityCode/securityName 类型
如实标注为 string|null。新增最小回归脚本复现并验证修复。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-12 18:49:27 +08:00

64 lines
2.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 最小复现/验证脚本:直接编译 src/lib/stock-api.ts 真实源码,
// 调用 getStockBoard(null),复现「Cannot read properties of null (reading 'startsWith')」。
// 无测试框架,node 直接运行:node tests/get-stock-board-repro.mjs
import fs from "node:fs";
import path from "node:path";
import Module from "node:module";
import ts from "typescript";
const srcPath = path.resolve("src/lib/stock-api.ts");
const source = fs.readFileSync(srcPath, "utf8");
const js = ts.transpileModule(source, {
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020, esModuleInterop: true },
}).outputText;
const mod = new Module(srcPath);
mod.filename = srcPath;
mod.paths = Module._nodeModulePaths(path.dirname(srcPath));
// 拦截 @/lib/api-client 别名导入(getStockBoard 本身不依赖它)
const origResolve = Module._resolveFilename;
Module._resolveFilename = function (request, ...args) {
if (request === "@/lib/api-client") return path.resolve("tests/_stub-api-client.cjs");
return origResolve.call(this, request, ...args);
};
try {
mod._compile(js, srcPath);
} finally {
Module._resolveFilename = origResolve;
}
const { getStockBoard } = mod.exports;
// ---- 断言 ----
function assertThrows(fn, label) {
try {
fn();
console.log(`✗ ${label}: 未抛错`);
process.exitCode = 1;
} catch (e) {
console.log(`✓ ${label}: 抛错 -> ${e.message}`);
}
}
function assertNoThrow(fn, label) {
try {
const r = fn();
console.log(`✓ ${label}: 未抛错 -> ${JSON.stringify(r)}`);
return r;
} catch (e) {
console.log(`✗ ${label}: 抛错 -> ${e.message}`);
process.exitCode = 1;
}
}
// 正常代码
assertNoThrow(() => getStockBoard("600000"), "正常代码 getStockBoard('600000')");
// 崩盘场景:securityCode 为 nullEast Money 题材列表实测存在),修复后应兜底返回主板
assertNoThrow(() => getStockBoard(null), "null securityCode");
assertNoThrow(() => getStockBoard(undefined), "undefined securityCode");
// 空串不崩
assertNoThrow(() => getStockBoard(""), "空串 getStockBoard('')");