Files
one_divine_lot/scripts/test-r011-api.mjs
T
kyugao 4ac8a29805 feat(Tab设置+UI主题): 迭代09 Tab设置统一管理 + 迭代10 UI适配DSH主题
迭代09 (R-011): Tab 设置统一管理所有会话 tab
- settings.tabs 布尔对象 → 统一有序数组 (kind: builtin|strategy)
- 旧配置 schema union 兼容 + 读取归一化无感迁移
- strategies 收窄为 {id,name},策略行 name join 自动跟随改名
- 策略增删联动 tabs 条目 (add 追加末尾 / remove 联动删除)
- 客户端统一注册读 tabs 数组,内置与策略可任意混排
- 设置页 Tab 设置子 tab:混排表格 + 拖动手柄 + 显隐开关 + 落点立即持久化
- 策略分组瘦身:仅 新增/重命名/删除 + 指引提示
- 回归测试: test-r011-tabs (23) + test-r011-api (12)

迭代10 (R-012): UI 适配 DSH 浅色/深色/跟随系统主题
- 10 个视图文件 141 处硬编码色 → var(--dsw-alias-*, fallback)
- 语义映射: bg-layer/label/border/state/button-contrast 等
- 淡底 color-mix 自适应;遮罩 bg-mask-1;阴影 shadow-lv3
2026-09-02 14:00:56 +08:00

86 lines
4.0 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.
/**
* R-011 API 层集成测试:handleStrategy tabs 域(联动链路)
* 独立内存 mock settings scope + mock manager,验证:
* 1. tabs 端点:返回归一化后的统一数组
* 2. tabs/update:整表更新(顺序 + 显隐)
* 3. strategies/add:联动追加 tab 条目(末尾)
* 4. strategies/remove:联动删除 tab 条目 + 清份额(manager
* 5. strategies/update:重命名(tabs 行 name join 跟随)
* 纯内存,不触真实数据(技术约束-011)
*/
import { handleStrategy, STRATEGY_METHODS } from '../src/api/strategies.js';
let pass = 0, fail = 0;
function assert(cond, msg) {
if (cond) { pass++; console.log(" ✅ " + msg); }
else { fail++; console.log(" ❌ " + msg); }
}
/** 内存 mock scope */
function makeScope(initial) {
const store = structuredClone(initial ?? {});
return {
get: () => structuredClone(store),
update: async (patch) => { Object.assign(store, structuredClone(patch)); },
};
}
const scope = makeScope({
strategies: [{ id: "grid-supermarket", name: "网格超市" }],
tabs: [
{ id: "tab-all", kind: "builtin", refKey: "allPositions", name: "全部持仓", visible: true, order: 0 },
{ id: "tab-g", kind: "strategy", refId: "grid-supermarket", name: "网格超市", visible: true, order: 1 },
],
});
const cleared = [];
const manager = {
async clearStrategyShares(id) { cleared.push(id); },
};
const runtime = { manager, settings: scope };
// 1. tabs 端点
console.log("\n[1] tabs 端点");
const tabs1 = await handleStrategy("tabs", {}, runtime);
assert(Array.isArray(tabs1) && tabs1.length === 2, "tabs 返回统一数组");
assert(tabs1[0].kind === "builtin" && tabs1[1].kind === "strategy", "内置 + 策略混排");
// 2. tabs/update 整表更新
console.log("\n[2] tabs/update 整表更新");
const afterUpdate = await handleStrategy("tabs/update", { tabs: [
{ id: "tab-g", kind: "strategy", refId: "grid-supermarket", name: "网格超市", visible: false, order: 0 },
{ id: "tab-all", kind: "builtin", refKey: "allPositions", name: "全部持仓", visible: true, order: 1 },
] }, runtime);
assert(afterUpdate[0].id === "tab-g" && afterUpdate[0].visible === false, "策略 tab 排到前面且隐藏");
assert(afterUpdate[1].id === "tab-all", "内置 tab 排后");
// 3. strategies/add 联动追加 tab
console.log("\n[3] strategies/add 联动追加 tab");
const added = await handleStrategy("strategies/add", { name: "长线持有" }, runtime);
const tabsAfterAdd = await handleStrategy("tabs", {}, runtime);
assert(tabsAfterAdd.length === 3, "add 后 tabs 联动新增一条");
assert(tabsAfterAdd[2].kind === "strategy" && tabsAfterAdd[2].refId === added.id, "新策略 tab 追加末尾");
assert(tabsAfterAdd[2].name === "长线持有", "新策略 tab name 正确");
// 4. strategies/remove 联动删除 tab + 清份额
console.log("\n[4] strategies/remove 联动删除 tab");
await handleStrategy("strategies/remove", { strategyId: "grid-supermarket" }, runtime);
const tabsAfterRm = await handleStrategy("tabs", {}, runtime);
assert(!tabsAfterRm.some((t) => t.refId === "grid-supermarket"), "删除策略后对应 tab 条目消失");
assert(tabsAfterRm.some((t) => t.refId === added.id), "其余策略 tab 保留");
assert(cleared.includes("grid-supermarket"), "manager.clearStrategyShares 被调用(份额回未分配)");
// 5. strategies/update 重命名(tabs 行 join 跟随)
console.log("\n[5] strategies/update 重命名跟随");
await handleStrategy("strategies/update", { strategies: [
{ id: added.id, name: "长线持有v2" },
] }, runtime);
const tabsAfterRename = await handleStrategy("tabs", {}, runtime);
assert(tabsAfterRename.find((t) => t.refId === added.id).name === "长线持有v2", "重命名后 tabs 行 name join 跟随(Q4");
// 6. 端点表不含 strategies/move
console.log("\n[6] strategies/move 已废弃");
assert(!STRATEGY_METHODS.has("strategies/move"), "STRATEGY_METHODS 不含 strategies/move");
console.log("\n结果: " + pass + " 通过 / " + fail + " 失败");
if (fail > 0) process.exit(1);