You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
5.1 KiB
135 lines
5.1 KiB
import assert from "node:assert/strict";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
|
|
const root = path.resolve(import.meta.dirname, "..");
|
|
const sourcePath = path.join(
|
|
root,
|
|
"client",
|
|
"src",
|
|
"sections",
|
|
"superAgent",
|
|
"utils",
|
|
"workspace.js"
|
|
);
|
|
const source = fs.readFileSync(sourcePath, "utf8");
|
|
const streamHookSource = fs.readFileSync(
|
|
path.join(root, "client", "src", "sections", "superAgent", "hooks", "useSuperAgentStream.js"),
|
|
"utf8"
|
|
);
|
|
const containerSource = fs.readFileSync(
|
|
path.join(root, "client", "src", "sections", "superAgent", "container", "index.jsx"),
|
|
"utf8"
|
|
);
|
|
|
|
function loadWorkspaceUtils() {
|
|
const transformed =
|
|
source.replace(/export const ([A-Za-z0-9_]+) =/g, "const $1 =") +
|
|
"\nreturn { normalizeCatalogWorkspace, toCheckpointCatalog, mergeAuthoritativeSectionList, buildSectionDisplayHierarchy, shouldMarkSectionDirty };";
|
|
return new Function(transformed)();
|
|
}
|
|
|
|
const {
|
|
normalizeCatalogWorkspace,
|
|
toCheckpointCatalog,
|
|
mergeAuthoritativeSectionList,
|
|
buildSectionDisplayHierarchy,
|
|
shouldMarkSectionDirty,
|
|
} = loadWorkspaceUtils();
|
|
|
|
const normalized = normalizeCatalogWorkspace({
|
|
chapters: [
|
|
{
|
|
id: "ch1",
|
|
title: "技术方案",
|
|
subsections: [
|
|
{
|
|
id: "ch1s1",
|
|
title: "网络安全方案",
|
|
subsections: [{ id: "ch1s1a", title: "实施保障措施" }],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
});
|
|
|
|
assert.equal(normalized[0].children[0].children[0].title, "实施保障措施");
|
|
|
|
const edited = [
|
|
{
|
|
...normalized[0],
|
|
subsections: [{ id: "stale", title: "旧目录" }],
|
|
children: [
|
|
{
|
|
...normalized[0].children[0],
|
|
title: "网络安全方案(已修改)",
|
|
children: [
|
|
...normalized[0].children[0].children,
|
|
{ key: "1-1-2", title: "新增条目", name: "新增条目", children: [] },
|
|
],
|
|
},
|
|
],
|
|
},
|
|
];
|
|
const checkpointCatalog = toCheckpointCatalog(edited);
|
|
|
|
assert.equal(checkpointCatalog[0].subsections[0].title, "网络安全方案(已修改)");
|
|
assert.equal(checkpointCatalog[0].subsections[0].subsections[1].title, "新增条目");
|
|
assert.equal(checkpointCatalog[0].subsections[0].subsections[1].id, "1-1-2");
|
|
assert.equal("children" in checkpointCatalog[0], false);
|
|
assert.equal(
|
|
checkpointCatalog[0].subsections.some((item) => item.id === "stale"),
|
|
false
|
|
);
|
|
|
|
const mergedSections = mergeAuthoritativeSectionList(
|
|
[
|
|
{ id: "ch1", title: "一、报价部分", content: "" },
|
|
{ id: "ch1s1", title: "磋商函", content: "本地旧内容", order: 1 },
|
|
],
|
|
[{ id: "ch1s1", title: "磋商函", content: "服务端正文", order: 1 }],
|
|
new Set()
|
|
);
|
|
assert.deepEqual(mergedSections.map((item) => item.id), ["ch1s1"]);
|
|
assert.equal(mergedSections[0].content, "服务端正文");
|
|
|
|
const dirtyMergedSections = mergeAuthoritativeSectionList(
|
|
[{ id: "ch1s1", title: "磋商函", content: "尚未保存的本地修改", order: 1 }],
|
|
[{ id: "ch1s1", title: "磋商函", content: "服务端旧正文", order: 1 }],
|
|
new Set(["ch1s1"])
|
|
);
|
|
assert.equal(dirtyMergedSections[0].content, "尚未保存的本地修改");
|
|
|
|
const displaySections = buildSectionDisplayHierarchy([
|
|
{ id: "ch1s1", parent_id: "ch1", parent_title: "报价部分", title: "磋商函", order: 1 },
|
|
{ id: "ch1s2", parent_id: "ch1", parent_title: "报价部分", title: "报价一览表", order: 2 },
|
|
{ id: "ch2s1", parent_id: "ch2", parent_title: "资格审查部分", title: "法定代表人身份证明", order: 3 },
|
|
{ id: "ch3s1", parent_id: "ch3", parent_title: "符合性审查部分", title: "技术、商务要求响应表", order: 4 },
|
|
{ id: "ch4s1", parent_id: "ch4", parent_title: "技术和商务部分", title: "项目理解与总体方案概述", order: 5 },
|
|
{ id: "ch4s2", parent_id: "ch4", parent_title: "技术和商务部分", title: "网络及网络安全运维方案", order: 6 },
|
|
]);
|
|
|
|
assert.equal(displaySections[0].parentDisplayTitle, "一、报价部分");
|
|
assert.equal(displaySections[0].displayTitle, "1.1 磋商函");
|
|
assert.equal(displaySections[1].startsParentGroup, false);
|
|
assert.equal(displaySections[4].parentDisplayTitle, "四、技术和商务部分");
|
|
assert.equal(displaySections[4].displayTitle, "4.1 项目理解与总体方案概述");
|
|
assert.equal(displaySections[5].displayTitle, "4.2 网络及网络安全运维方案");
|
|
|
|
assert.equal(
|
|
shouldMarkSectionDirty({ hasUserFocus: false, previousContent: "", nextContent: "<p></p>" }),
|
|
false
|
|
);
|
|
assert.equal(
|
|
shouldMarkSectionDirty({ hasUserFocus: true, previousContent: "正文", nextContent: "修改后正文" }),
|
|
true
|
|
);
|
|
|
|
assert.match(streamHookSource, /"custom:generation"/);
|
|
assert.match(streamHookSource, /"custom:section"/);
|
|
assert.match(streamHookSource, /"custom:workspace"/);
|
|
assert.match(streamHookSource, /replay:\s*false/);
|
|
assert.match(containerSource, /workspace\.updated/);
|
|
assert.match(containerSource, /section\.completed/);
|
|
assert.match(containerSource, /syncSessionProgressSections/);
|
|
assert.match(containerSource, /refreshSessionContentWorkspace/);
|
|
|