@aigne/doc-smith 0.8.5 → 0.8.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.aigne/doc-smith/output/structure-plan.json +1 -5
- package/CHANGELOG.md +25 -0
- package/README.md +3 -3
- package/agents/{chat.yaml → chat/index.yaml} +7 -7
- package/agents/generate/check-document-structure.yaml +30 -0
- package/agents/{check-structure-plan.mjs → generate/check-need-generate-structure.mjs} +21 -21
- package/agents/generate/generate-structure.yaml +58 -0
- package/agents/{docs-generator.yaml → generate/index.yaml} +15 -16
- package/agents/generate/refine-document-structure.yaml +12 -0
- package/agents/{input-generator.mjs → init/index.mjs} +34 -27
- package/agents/{manage-prefs.mjs → prefs/index.mjs} +16 -16
- package/agents/publish/index.yaml +17 -0
- package/agents/{publish-docs.mjs → publish/publish-docs.mjs} +15 -16
- package/agents/schema/{structure-plan-result.yaml → document-execution-structure.yaml} +3 -3
- package/agents/schema/document-structure.yaml +26 -0
- package/agents/{language-selector.mjs → translate/choose-language.mjs} +5 -5
- package/agents/{retranslate.yaml → translate/index.yaml} +17 -18
- package/agents/translate/translate-document.yaml +32 -0
- package/agents/{batch-translate.yaml → translate/translate-multilingual.yaml} +5 -5
- package/agents/update/batch-generate-document.yaml +19 -0
- package/agents/{check-detail.mjs → update/check-document.mjs} +16 -16
- package/agents/{detail-generator-and-translate.yaml → update/generate-and-translate-document.yaml} +23 -23
- package/agents/update/generate-document.yaml +50 -0
- package/agents/{detail-regenerator.yaml → update/index.yaml} +16 -17
- package/agents/{action-success.mjs → utils/action-success.mjs} +2 -2
- package/agents/{check-detail-result.mjs → utils/check-detail-result.mjs} +3 -3
- package/agents/{check-feedback-refiner.mjs → utils/check-feedback-refiner.mjs} +6 -6
- package/agents/{find-items-by-paths.mjs → utils/choose-docs.mjs} +25 -10
- package/agents/{docs-fs.yaml → utils/docs-fs-actor.yaml} +3 -1
- package/agents/utils/feedback-refiner.yaml +50 -0
- package/agents/{find-item-by-path.mjs → utils/find-item-by-path.mjs} +17 -7
- package/agents/{find-user-preferences-by-path.mjs → utils/find-user-preferences-by-path.mjs} +1 -1
- package/agents/utils/format-document-structure.mjs +25 -0
- package/agents/{load-sources.mjs → utils/load-sources.mjs} +41 -28
- package/agents/{save-docs.mjs → utils/save-docs.mjs} +16 -16
- package/agents/{save-single-doc.mjs → utils/save-single-doc.mjs} +2 -2
- package/agents/{transform-detail-datasources.mjs → utils/transform-detail-datasources.mjs} +1 -1
- package/aigne.yaml +35 -35
- package/docs/cli-reference.md +1 -1
- package/docs/features-generate-documentation.md +1 -1
- package/docs/features-update-and-refine.md +2 -2
- package/docs-mcp/analyze-docs-relevance.yaml +10 -10
- package/docs-mcp/docs-search.yaml +5 -3
- package/package.json +10 -8
- package/prompts/{document → detail/custom}/custom-code-block.md +6 -6
- package/prompts/detail/custom/custom-components.md +172 -0
- package/prompts/{document → detail}/d2-chart/rules.md +95 -1
- package/prompts/{document → detail}/detail-example.md +80 -61
- package/prompts/{document/detail-generator.md → detail/document-rules.md} +4 -8
- package/prompts/{content-detail-generator.md → detail/generate-document.md} +48 -25
- package/prompts/{check-structure-planning-result.md → structure/check-document-structure.md} +23 -17
- package/prompts/{document/structure-planning.md → structure/document-rules.md} +0 -2
- package/prompts/{structure-planning.md → structure/generate-structure.md} +51 -30
- package/prompts/{document → structure}/structure-example.md +2 -2
- package/prompts/{document → structure}/structure-getting-started.md +2 -2
- package/prompts/translate/glossary.md +6 -0
- package/prompts/{translator.md → translate/translate-document.md} +29 -10
- package/prompts/{feedback-refiner.md → utils/feedback-refiner.md} +8 -8
- package/tests/agents/chat/chat.test.mjs +46 -0
- package/tests/agents/generate/check-document-structure.test.mjs +51 -0
- package/tests/agents/generate/check-need-generate-structure.test.mjs +292 -0
- package/tests/agents/generate/generate-structure.test.mjs +51 -0
- package/tests/{input-generator.test.mjs → agents/init/init.test.mjs} +19 -17
- package/tests/agents/prefs/prefs.test.mjs +431 -0
- package/tests/agents/publish/publish-docs.test.mjs +642 -0
- package/tests/agents/translate/choose-language.test.mjs +311 -0
- package/tests/agents/translate/translate-document.test.mjs +51 -0
- package/tests/agents/update/check-document.test.mjs +523 -0
- package/tests/agents/update/generate-document.test.mjs +51 -0
- package/tests/agents/utils/action-success.test.mjs +54 -0
- package/tests/{check-detail-result.test.mjs → agents/utils/check-detail-result.test.mjs} +98 -98
- package/tests/agents/utils/check-feedback-refiner.test.mjs +478 -0
- package/tests/agents/utils/choose-docs.test.mjs +417 -0
- package/tests/agents/utils/exit.test.mjs +70 -0
- package/tests/agents/utils/feedback-refiner.test.mjs +51 -0
- package/tests/agents/utils/find-item-by-path.test.mjs +526 -0
- package/tests/agents/utils/find-user-preferences-by-path.test.mjs +382 -0
- package/tests/agents/utils/format-document-structure.test.mjs +264 -0
- package/tests/agents/utils/fs.test.mjs +267 -0
- package/tests/{load-sources.test.mjs → agents/utils/load-sources.test.mjs} +153 -25
- package/tests/{save-docs.test.mjs → agents/utils/save-docs.test.mjs} +11 -5
- package/tests/agents/utils/save-output.test.mjs +315 -0
- package/tests/agents/utils/save-single-doc.test.mjs +364 -0
- package/tests/agents/utils/transform-detail-datasources.test.mjs +363 -0
- package/tests/utils/auth-utils.test.mjs +358 -0
- package/tests/utils/blocklet.test.mjs +334 -0
- package/tests/{conflict-resolution.test.mjs → utils/conflict-detector.test.mjs} +3 -3
- package/tests/utils/constants.test.mjs +295 -0
- package/tests/utils/d2-utils.test.mjs +423 -0
- package/tests/utils/deploy.test.mjs +365 -0
- package/tests/utils/docs-finder-utils.test.mjs +625 -0
- package/tests/utils/file-utils.test.mjs +213 -0
- package/tests/{kroki-utils.test.mjs → utils/kroki-utils.test.mjs} +2 -2
- package/tests/utils/load-config.test.mjs +141 -0
- package/tests/{mermaid-validation.test.mjs → utils/mermaid-validator.test.mjs} +2 -2
- package/tests/utils/mock-chat-model.mjs +12 -0
- package/tests/{preferences-utils.test.mjs → utils/preferences-utils.test.mjs} +1 -1
- package/tests/{save-value-to-config.test.mjs → utils/save-value-to-config.test.mjs} +61 -4
- package/tests/utils/utils.test.mjs +939 -0
- package/utils/auth-utils.mjs +1 -1
- package/utils/conflict-detector.mjs +1 -1
- package/utils/constants.mjs +5 -3
- package/utils/d2-utils.mjs +194 -0
- package/utils/deploy.mjs +3 -3
- package/utils/docs-finder-utils.mjs +26 -26
- package/utils/icon-map.mjs +26 -0
- package/{agents → utils}/load-config.mjs +2 -18
- package/utils/markdown-checker.mjs +5 -5
- package/agents/batch-docs-detail-generator.yaml +0 -19
- package/agents/check-structure-planning-result.yaml +0 -30
- package/agents/content-detail-generator.yaml +0 -50
- package/agents/feedback-refiner.yaml +0 -52
- package/agents/format-structure-plan.mjs +0 -25
- package/agents/reflective-structure-planner.yaml +0 -12
- package/agents/schema/structure-plan.yaml +0 -26
- package/agents/structure-planning.yaml +0 -58
- package/agents/team-publish-docs.yaml +0 -18
- package/agents/translate.yaml +0 -31
- package/prompts/document/custom-components.md +0 -104
- package/tests/README.md +0 -93
- package/tests/utils.test.mjs +0 -2067
- /package/agents/{exit.mjs → utils/exit.mjs} +0 -0
- /package/agents/{fs.mjs → utils/fs.mjs} +0 -0
- /package/agents/{save-output.mjs → utils/save-output.mjs} +0 -0
- /package/prompts/{document → detail}/d2-chart/official-examples.md +0 -0
- /package/prompts/{document → detail}/jsx/rules.md +0 -0
|
@@ -1,107 +1,107 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
|
-
import checkDetailResult from "
|
|
2
|
+
import checkDetailResult from "../../../agents/utils/check-detail-result.mjs";
|
|
3
3
|
|
|
4
|
-
describe("
|
|
4
|
+
describe("check-detail-result", () => {
|
|
5
5
|
test("should approve valid content", async () => {
|
|
6
|
-
const
|
|
6
|
+
const documentStructure = [{ path: "/getting-started" }];
|
|
7
7
|
const reviewContent =
|
|
8
8
|
"This is a test with a [valid link](/getting-started).\n\nThis has proper structure with multiple lines.";
|
|
9
|
-
const result = await checkDetailResult({
|
|
9
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
10
10
|
expect(result.isApproved).toBe(true);
|
|
11
11
|
expect(result.detailFeedback).toBe("");
|
|
12
12
|
});
|
|
13
13
|
|
|
14
14
|
test("should reject content with a dead link", async () => {
|
|
15
|
-
const
|
|
15
|
+
const documentStructure = [{ path: "/getting-started" }];
|
|
16
16
|
const reviewContent = "This contains a [dead link](/dead-link).";
|
|
17
|
-
const result = await checkDetailResult({
|
|
17
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
18
18
|
expect(result.isApproved).toBe(false);
|
|
19
19
|
expect(result.detailFeedback).toContain("Found a dead link");
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
test("should accept valid table format", async () => {
|
|
23
|
-
const
|
|
23
|
+
const documentStructure = [];
|
|
24
24
|
const reviewContent =
|
|
25
25
|
"| Header | Header |\n|--------|--------|\n| Cell | Cell |\n\nThis table is properly formatted.";
|
|
26
|
-
const result = await checkDetailResult({
|
|
26
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
27
27
|
expect(result.isApproved).toBe(true);
|
|
28
28
|
expect(result.detailFeedback).toBe("");
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
test("should approve content with an external link", async () => {
|
|
32
|
-
const
|
|
32
|
+
const documentStructure = [];
|
|
33
33
|
const reviewContent =
|
|
34
34
|
"This is a [valid external link](https://example.com).\n\nThis has proper multi-line structure.";
|
|
35
|
-
const result = await checkDetailResult({
|
|
35
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
36
36
|
expect(result.isApproved).toBe(true);
|
|
37
37
|
expect(result.detailFeedback).toBe("");
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
test("should approve content with valid local image path", async () => {
|
|
41
|
-
const
|
|
41
|
+
const documentStructure = [];
|
|
42
42
|
const reviewContent =
|
|
43
43
|
"This is a valid image .\n\nThis has proper structure.";
|
|
44
44
|
const docsDir = process.cwd();
|
|
45
|
-
const result = await checkDetailResult({
|
|
45
|
+
const result = await checkDetailResult({ documentStructure, reviewContent, docsDir });
|
|
46
46
|
expect(result.isApproved).toBe(true);
|
|
47
47
|
expect(result.detailFeedback).toBe("");
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
test("should reject content with invalid local image path", async () => {
|
|
51
|
-
const
|
|
51
|
+
const documentStructure = [];
|
|
52
52
|
const reviewContent =
|
|
53
53
|
"This is an invalid image .\n\nThis has proper structure.";
|
|
54
54
|
const docsDir = process.cwd();
|
|
55
|
-
const result = await checkDetailResult({
|
|
55
|
+
const result = await checkDetailResult({ documentStructure, reviewContent, docsDir });
|
|
56
56
|
expect(result.isApproved).toBe(false);
|
|
57
57
|
expect(result.detailFeedback).toContain("Found invalid local image");
|
|
58
58
|
expect(result.detailFeedback).toContain("only valid media resources can be used");
|
|
59
59
|
});
|
|
60
60
|
|
|
61
61
|
test("should approve content with absolute image path that exists", async () => {
|
|
62
|
-
const
|
|
62
|
+
const documentStructure = [];
|
|
63
63
|
const reviewContent = `This is an absolute image }/README.md).\n\nThis has proper structure.`;
|
|
64
|
-
const result = await checkDetailResult({
|
|
64
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
65
65
|
expect(result.isApproved).toBe(true);
|
|
66
66
|
expect(result.detailFeedback).toBe("");
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
test("should reject content with absolute image path that doesn't exist", async () => {
|
|
70
|
-
const
|
|
70
|
+
const documentStructure = [];
|
|
71
71
|
const reviewContent =
|
|
72
72
|
"This is an invalid absolute image .\n\nThis has proper structure.";
|
|
73
|
-
const result = await checkDetailResult({
|
|
73
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
74
74
|
expect(result.isApproved).toBe(false);
|
|
75
75
|
expect(result.detailFeedback).toContain("Found invalid local image");
|
|
76
76
|
expect(result.detailFeedback).toContain("only valid media resources can be used");
|
|
77
77
|
});
|
|
78
78
|
|
|
79
79
|
test("should approve content with external image URL", async () => {
|
|
80
|
-
const
|
|
80
|
+
const documentStructure = [];
|
|
81
81
|
const reviewContent =
|
|
82
82
|
"This is an external image .\n\nThis has proper structure.";
|
|
83
|
-
const result = await checkDetailResult({
|
|
83
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
84
84
|
expect(result.isApproved).toBe(true);
|
|
85
85
|
expect(result.detailFeedback).toBe("");
|
|
86
86
|
});
|
|
87
87
|
|
|
88
88
|
describe("Table validation", () => {
|
|
89
89
|
test("should reject table with mismatched column count", async () => {
|
|
90
|
-
const
|
|
90
|
+
const documentStructure = [];
|
|
91
91
|
const reviewContent =
|
|
92
92
|
"| Header 1 | Header 2 | Header 3 |\n" +
|
|
93
93
|
"|----------|----------|\n" + // Only 2 separator columns but 3 header columns
|
|
94
94
|
"| Cell 1 | Cell 2 | Cell 3 |";
|
|
95
|
-
const result = await checkDetailResult({
|
|
95
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
96
96
|
expect(result.isApproved).toBe(false);
|
|
97
97
|
expect(result.detailFeedback).toContain("separator has 2 columns but header has 3 columns");
|
|
98
98
|
});
|
|
99
99
|
|
|
100
100
|
test("should reject table with data row column mismatch", async () => {
|
|
101
|
-
const
|
|
101
|
+
const documentStructure = [];
|
|
102
102
|
const reviewContent =
|
|
103
103
|
"| Header 1 | Header 2 |\n" + "|----------|----------|\n" + "| Cell 1 | Cell 2 | Cell 3 |"; // Data row has 3 columns but separator defines 2
|
|
104
|
-
const result = await checkDetailResult({
|
|
104
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
105
105
|
expect(result.isApproved).toBe(false);
|
|
106
106
|
expect(result.detailFeedback).toContain(
|
|
107
107
|
"data row has 3 columns but separator defines 2 columns",
|
|
@@ -109,46 +109,46 @@ describe("checkDetailResult", () => {
|
|
|
109
109
|
});
|
|
110
110
|
|
|
111
111
|
test("should handle complex table with pipes in content", async () => {
|
|
112
|
-
const
|
|
112
|
+
const documentStructure = [];
|
|
113
113
|
const reviewContent =
|
|
114
114
|
"| Code | Description |\n" +
|
|
115
115
|
"|------|-------------|\n" +
|
|
116
116
|
"| `a \\| b` | This has escaped pipe |\n" +
|
|
117
117
|
"| `c | d` | This has unescaped pipe in code |";
|
|
118
|
-
const result = await checkDetailResult({
|
|
118
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
119
119
|
expect(result.isApproved).toBe(true);
|
|
120
120
|
});
|
|
121
121
|
});
|
|
122
122
|
|
|
123
123
|
describe("Code block validation", () => {
|
|
124
124
|
test("should reject incomplete code blocks", async () => {
|
|
125
|
-
const
|
|
125
|
+
const documentStructure = [];
|
|
126
126
|
const reviewContent =
|
|
127
127
|
"Here is some code:\n\n" +
|
|
128
128
|
"```javascript\n" +
|
|
129
129
|
"function test() {\n" +
|
|
130
130
|
" return 'incomplete';\n" +
|
|
131
131
|
"}\n"; // Missing closing ```
|
|
132
|
-
const result = await checkDetailResult({
|
|
132
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
133
133
|
expect(result.isApproved).toBe(false);
|
|
134
134
|
expect(result.detailFeedback).toContain("incomplete code block");
|
|
135
135
|
});
|
|
136
136
|
|
|
137
137
|
test("should detect code block indentation issues", async () => {
|
|
138
|
-
const
|
|
138
|
+
const documentStructure = [];
|
|
139
139
|
const reviewContent =
|
|
140
140
|
" ```javascript\n" +
|
|
141
141
|
"function test() {\n" + // This line has insufficient indentation
|
|
142
142
|
" return 'test';\n" +
|
|
143
143
|
" }\n" +
|
|
144
144
|
" ```";
|
|
145
|
-
const result = await checkDetailResult({
|
|
145
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
146
146
|
expect(result.isApproved).toBe(false);
|
|
147
147
|
expect(result.detailFeedback).toContain("insufficient indentation");
|
|
148
148
|
});
|
|
149
149
|
|
|
150
150
|
test("should approve various programming language code blocks with proper detection", async () => {
|
|
151
|
-
const
|
|
151
|
+
const documentStructure = [];
|
|
152
152
|
const reviewContent = `Programming Language Examples:
|
|
153
153
|
|
|
154
154
|
## Rust with Configuration
|
|
@@ -254,7 +254,7 @@ app.listen(PORT, () => {
|
|
|
254
254
|
|
|
255
255
|
This document demonstrates various programming language code blocks.`;
|
|
256
256
|
|
|
257
|
-
const result = await checkDetailResult({
|
|
257
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
258
258
|
expect(result.isApproved).toBe(true);
|
|
259
259
|
expect(result.detailFeedback).toBe("");
|
|
260
260
|
});
|
|
@@ -262,68 +262,68 @@ This document demonstrates various programming language code blocks.`;
|
|
|
262
262
|
|
|
263
263
|
describe("Content structure validation", () => {
|
|
264
264
|
test("should reject single line content", async () => {
|
|
265
|
-
const
|
|
265
|
+
const documentStructure = [];
|
|
266
266
|
const reviewContent = "This is a single line without proper line breaks";
|
|
267
|
-
const result = await checkDetailResult({
|
|
267
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
268
268
|
expect(result.isApproved).toBe(false);
|
|
269
269
|
expect(result.detailFeedback).toContain("single line content");
|
|
270
270
|
});
|
|
271
271
|
|
|
272
272
|
test("should reject incomplete content without proper ending", async () => {
|
|
273
|
-
const
|
|
273
|
+
const documentStructure = [];
|
|
274
274
|
const reviewContent = "This content doesn't end properly\n\nNo proper punctuation";
|
|
275
|
-
const result = await checkDetailResult({
|
|
275
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
276
276
|
expect(result.isApproved).toBe(false);
|
|
277
277
|
expect(result.detailFeedback).toContain("incomplete content");
|
|
278
278
|
});
|
|
279
279
|
|
|
280
280
|
test("should approve content with valid ending punctuation", async () => {
|
|
281
|
-
const
|
|
281
|
+
const documentStructure = [];
|
|
282
282
|
const reviewContent = "This content ends properly.\n\nWith valid punctuation.";
|
|
283
|
-
const result = await checkDetailResult({
|
|
283
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
284
284
|
expect(result.isApproved).toBe(true);
|
|
285
285
|
});
|
|
286
286
|
});
|
|
287
287
|
|
|
288
288
|
describe("Mermaid syntax validation", () => {
|
|
289
289
|
test("should reject Mermaid with backticks in node labels", async () => {
|
|
290
|
-
const
|
|
290
|
+
const documentStructure = [];
|
|
291
291
|
const reviewContent =
|
|
292
292
|
"```mermaid\n" + "graph TD\n" + ' A["Contains `backticks` in label"]\n' + "```";
|
|
293
|
-
const result = await checkDetailResult({
|
|
293
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
294
294
|
expect(result.isApproved).toBe(false);
|
|
295
295
|
expect(result.detailFeedback).toContain("backticks in Mermaid node label");
|
|
296
296
|
});
|
|
297
297
|
|
|
298
298
|
test("should reject Mermaid with numbered lists in node labels", async () => {
|
|
299
|
-
const
|
|
299
|
+
const documentStructure = [];
|
|
300
300
|
const reviewContent =
|
|
301
301
|
"```mermaid\n" + "graph TD\n" + ' A["1. First item\\n2. Second item"]\n' + "```";
|
|
302
|
-
const result = await checkDetailResult({
|
|
302
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
303
303
|
expect(result.isApproved).toBe(false);
|
|
304
304
|
expect(result.detailFeedback).toContain("numbered list format in Mermaid node label");
|
|
305
305
|
});
|
|
306
306
|
|
|
307
307
|
test("should reject Mermaid with numbered lists in edge descriptions", async () => {
|
|
308
|
-
const
|
|
308
|
+
const documentStructure = [];
|
|
309
309
|
const reviewContent =
|
|
310
310
|
"```mermaid\n" + "graph TD\n" + ' A -- "1. First step" --> B\n' + "```";
|
|
311
|
-
const result = await checkDetailResult({
|
|
311
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
312
312
|
expect(result.isApproved).toBe(false);
|
|
313
313
|
expect(result.detailFeedback).toContain("numbered list format in Mermaid edge description");
|
|
314
314
|
});
|
|
315
315
|
|
|
316
316
|
test("should reject Mermaid with unquoted special characters", async () => {
|
|
317
|
-
const
|
|
317
|
+
const documentStructure = [];
|
|
318
318
|
const reviewContent =
|
|
319
319
|
"```mermaid\n" + "graph TD\n" + " A[Node with: special chars]\n" + "```";
|
|
320
|
-
const result = await checkDetailResult({
|
|
320
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
321
321
|
expect(result.isApproved).toBe(false);
|
|
322
322
|
expect(result.detailFeedback).toContain("unquoted special characters in Mermaid node label");
|
|
323
323
|
});
|
|
324
324
|
|
|
325
325
|
test("should approve properly formatted Mermaid", async () => {
|
|
326
|
-
const
|
|
326
|
+
const documentStructure = [];
|
|
327
327
|
const reviewContent =
|
|
328
328
|
"```mermaid\n" +
|
|
329
329
|
"graph TD\n" +
|
|
@@ -332,51 +332,51 @@ This document demonstrates various programming language code blocks.`;
|
|
|
332
332
|
" A --> B\n" +
|
|
333
333
|
"```\n\n" +
|
|
334
334
|
"This diagram is properly formatted.";
|
|
335
|
-
const result = await checkDetailResult({
|
|
335
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
336
336
|
expect(result.isApproved).toBe(true);
|
|
337
337
|
});
|
|
338
338
|
});
|
|
339
339
|
|
|
340
340
|
describe("D2 syntax validation", () => {
|
|
341
341
|
test("should handle D2 syntax errors", async () => {
|
|
342
|
-
const
|
|
342
|
+
const documentStructure = [];
|
|
343
343
|
const reviewContent =
|
|
344
344
|
"```d2\n" +
|
|
345
345
|
"invalid d2 syntax {{\n" + // Malformed D2
|
|
346
346
|
"```\n\n" +
|
|
347
347
|
"This has proper structure.";
|
|
348
|
-
const result = await checkDetailResult({
|
|
348
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
349
349
|
expect(result.isApproved).toBe(false);
|
|
350
350
|
});
|
|
351
351
|
});
|
|
352
352
|
|
|
353
353
|
describe("Advanced table edge cases", () => {
|
|
354
354
|
test("should handle empty table cells correctly", async () => {
|
|
355
|
-
const
|
|
355
|
+
const documentStructure = [];
|
|
356
356
|
const reviewContent =
|
|
357
357
|
"| Header 1 | Header 2 | Header 3 |\n" +
|
|
358
358
|
"|----------|----------|----------|\n" +
|
|
359
359
|
"| Cell 1 | | Cell 3 |\n" +
|
|
360
360
|
"| | Cell 2 | |";
|
|
361
|
-
const result = await checkDetailResult({
|
|
361
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
362
362
|
expect(result.isApproved).toBe(true);
|
|
363
363
|
});
|
|
364
364
|
|
|
365
365
|
test("should handle tables with code spans containing pipes", async () => {
|
|
366
|
-
const
|
|
366
|
+
const documentStructure = [];
|
|
367
367
|
const reviewContent =
|
|
368
368
|
"| Function | Code Example |\n" +
|
|
369
369
|
"|----------|---------------|\n" +
|
|
370
370
|
"| pipe | `a \\| b` |\n" +
|
|
371
371
|
"| filter | `data \\| filter` |";
|
|
372
|
-
const result = await checkDetailResult({
|
|
372
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
373
373
|
expect(result.isApproved).toBe(true);
|
|
374
374
|
});
|
|
375
375
|
});
|
|
376
376
|
|
|
377
377
|
describe("Code block edge cases", () => {
|
|
378
378
|
test("should handle nested code blocks properly", async () => {
|
|
379
|
-
const
|
|
379
|
+
const documentStructure = [];
|
|
380
380
|
const reviewContent =
|
|
381
381
|
"Here's a markdown example:\n\n" +
|
|
382
382
|
"```markdown\n" +
|
|
@@ -387,12 +387,12 @@ This document demonstrates various programming language code blocks.`;
|
|
|
387
387
|
"```\n" +
|
|
388
388
|
"```\n\n" +
|
|
389
389
|
"This content ends properly.";
|
|
390
|
-
const result = await checkDetailResult({
|
|
390
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
391
391
|
expect(result.isApproved).toBe(true);
|
|
392
392
|
});
|
|
393
393
|
|
|
394
394
|
test("should handle code blocks with unusual indentation patterns", async () => {
|
|
395
|
-
const
|
|
395
|
+
const documentStructure = [];
|
|
396
396
|
const reviewContent =
|
|
397
397
|
" ```javascript\n" +
|
|
398
398
|
" function test() {\n" +
|
|
@@ -400,14 +400,14 @@ This document demonstrates various programming language code blocks.`;
|
|
|
400
400
|
" }\n" +
|
|
401
401
|
" ```\n\n" +
|
|
402
402
|
"This has proper structure.";
|
|
403
|
-
const result = await checkDetailResult({
|
|
403
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
404
404
|
expect(result.isApproved).toBe(true);
|
|
405
405
|
});
|
|
406
406
|
});
|
|
407
407
|
|
|
408
408
|
describe("Complex Mermaid scenarios", () => {
|
|
409
409
|
test("should handle Mermaid with curly brace syntax", async () => {
|
|
410
|
-
const
|
|
410
|
+
const documentStructure = [];
|
|
411
411
|
const reviewContent =
|
|
412
412
|
"```mermaid\n" +
|
|
413
413
|
"graph TD\n" +
|
|
@@ -416,15 +416,15 @@ This document demonstrates various programming language code blocks.`;
|
|
|
416
416
|
" A --> B\n" +
|
|
417
417
|
"```\n\n" +
|
|
418
418
|
"This diagram uses proper syntax.";
|
|
419
|
-
const result = await checkDetailResult({
|
|
419
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
420
420
|
expect(result.isApproved).toBe(true);
|
|
421
421
|
});
|
|
422
422
|
|
|
423
423
|
test("should reject Mermaid with problematic curly brace labels", async () => {
|
|
424
|
-
const
|
|
424
|
+
const documentStructure = [];
|
|
425
425
|
const reviewContent =
|
|
426
426
|
"```mermaid\n" + "graph TD\n" + ' A{"Contains `backticks` problem"}\n' + "```";
|
|
427
|
-
const result = await checkDetailResult({
|
|
427
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
428
428
|
expect(result.isApproved).toBe(false);
|
|
429
429
|
expect(result.detailFeedback).toContain("backticks in Mermaid node label");
|
|
430
430
|
});
|
|
@@ -432,86 +432,86 @@ This document demonstrates various programming language code blocks.`;
|
|
|
432
432
|
|
|
433
433
|
describe("Image validation edge cases", () => {
|
|
434
434
|
test("should approve data URLs in images", async () => {
|
|
435
|
-
const
|
|
435
|
+
const documentStructure = [];
|
|
436
436
|
const reviewContent =
|
|
437
437
|
"Here's an inline image .\n\n" +
|
|
438
438
|
"This has proper structure.";
|
|
439
|
-
const result = await checkDetailResult({
|
|
439
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
440
440
|
expect(result.isApproved).toBe(true);
|
|
441
441
|
});
|
|
442
442
|
|
|
443
443
|
test("should handle images with complex alt text", async () => {
|
|
444
|
-
const
|
|
444
|
+
const documentStructure = [];
|
|
445
445
|
const reviewContent =
|
|
446
446
|
"![Complex alt text with [brackets] and (parentheses)](https://example.com/image.png)\n\n" +
|
|
447
447
|
"This has proper structure.";
|
|
448
|
-
const result = await checkDetailResult({
|
|
448
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
449
449
|
expect(result.isApproved).toBe(true);
|
|
450
450
|
});
|
|
451
451
|
});
|
|
452
452
|
|
|
453
453
|
describe("Link validation edge cases", () => {
|
|
454
454
|
test("should handle mailto links correctly", async () => {
|
|
455
|
-
const
|
|
455
|
+
const documentStructure = [];
|
|
456
456
|
const reviewContent =
|
|
457
457
|
"Contact us at [email](mailto:test@example.com).\n\n" + "This has proper structure.";
|
|
458
|
-
const result = await checkDetailResult({
|
|
458
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
459
459
|
expect(result.isApproved).toBe(true);
|
|
460
460
|
});
|
|
461
461
|
|
|
462
462
|
test("should handle links with anchors", async () => {
|
|
463
|
-
const
|
|
463
|
+
const documentStructure = [{ path: "/getting-started" }];
|
|
464
464
|
const reviewContent =
|
|
465
465
|
"See the [installation section](/getting-started#installation).\n\n" +
|
|
466
466
|
"This has proper structure.";
|
|
467
|
-
const result = await checkDetailResult({
|
|
467
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
468
468
|
expect(result.isApproved).toBe(true);
|
|
469
469
|
});
|
|
470
470
|
|
|
471
471
|
test("should handle anchor-only links without base path", async () => {
|
|
472
|
-
const
|
|
472
|
+
const documentStructure = [];
|
|
473
473
|
const reviewContent =
|
|
474
474
|
"See the [section](#non-existent-anchor).\n\n" + "This has proper structure.";
|
|
475
|
-
const result = await checkDetailResult({
|
|
475
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
476
476
|
expect(result.isApproved).toBe(true);
|
|
477
477
|
});
|
|
478
478
|
});
|
|
479
479
|
|
|
480
480
|
describe("Content structure edge cases", () => {
|
|
481
481
|
test("should approve content ending with table", async () => {
|
|
482
|
-
const
|
|
482
|
+
const documentStructure = [];
|
|
483
483
|
const reviewContent =
|
|
484
484
|
"Here's a data table:\n\n" +
|
|
485
485
|
"| Column 1 | Column 2 |\n" +
|
|
486
486
|
"|----------|----------|\n" +
|
|
487
487
|
"| Data 1 | Data 2 |";
|
|
488
|
-
const result = await checkDetailResult({
|
|
488
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
489
489
|
expect(result.isApproved).toBe(true);
|
|
490
490
|
});
|
|
491
491
|
|
|
492
492
|
test("should approve content ending with list", async () => {
|
|
493
|
-
const
|
|
493
|
+
const documentStructure = [];
|
|
494
494
|
const reviewContent =
|
|
495
495
|
"Here are the requirements:\n\n" +
|
|
496
496
|
"- First requirement\n" +
|
|
497
497
|
"- Second requirement\n" +
|
|
498
498
|
"- Third requirement*";
|
|
499
|
-
const result = await checkDetailResult({
|
|
499
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
500
500
|
expect(result.isApproved).toBe(true);
|
|
501
501
|
});
|
|
502
502
|
|
|
503
503
|
test("should approve content ending with blockquote", async () => {
|
|
504
|
-
const
|
|
504
|
+
const documentStructure = [];
|
|
505
505
|
const reviewContent =
|
|
506
506
|
"As they say:\n\n" + "> This is a famous quote that ends with proper punctuation.";
|
|
507
|
-
const result = await checkDetailResult({
|
|
507
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
508
508
|
expect(result.isApproved).toBe(true);
|
|
509
509
|
});
|
|
510
510
|
});
|
|
511
511
|
|
|
512
512
|
describe("Real-world scenario tests", () => {
|
|
513
513
|
test("should approve comprehensive valid document", async () => {
|
|
514
|
-
const
|
|
514
|
+
const documentStructure = [
|
|
515
515
|
{ path: "./getting-started" },
|
|
516
516
|
{ path: "/api/overview" },
|
|
517
517
|
{ path: "./advanced/configuration" },
|
|
@@ -571,12 +571,12 @@ For more information, see our [API reference](/api/overview) and [advanced confi
|
|
|
571
571
|
|
|
572
572
|
This document ends with proper punctuation and formatting.
|
|
573
573
|
`;
|
|
574
|
-
const result = await checkDetailResult({
|
|
574
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
575
575
|
expect(result.isApproved).toBe(true);
|
|
576
576
|
});
|
|
577
577
|
|
|
578
578
|
test("should approve content with Chinese punctuation", async () => {
|
|
579
|
-
const
|
|
579
|
+
const documentStructure = [];
|
|
580
580
|
const reviewContent = `# 中文文档
|
|
581
581
|
|
|
582
582
|
这是一个中文文档的示例。
|
|
@@ -587,12 +587,12 @@ This document ends with proper punctuation and formatting.
|
|
|
587
587
|
|
|
588
588
|
这个文档以中文句号结尾。
|
|
589
589
|
`;
|
|
590
|
-
const result = await checkDetailResult({
|
|
590
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
591
591
|
expect(result.isApproved).toBe(true);
|
|
592
592
|
});
|
|
593
593
|
|
|
594
594
|
test("should reject document with multiple validation issues", async () => {
|
|
595
|
-
const
|
|
595
|
+
const documentStructure = [{ path: "/getting-started" }];
|
|
596
596
|
const reviewContent = `# Complex Test Document
|
|
597
597
|
|
|
598
598
|
This document has [multiple issues](./broken-link).
|
|
@@ -607,7 +607,7 @@ flowchart TD
|
|
|
607
607
|
\`\`\`
|
|
608
608
|
|
|
609
609
|
This content doesn't end properly`;
|
|
610
|
-
const result = await checkDetailResult({
|
|
610
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
611
611
|
expect(result.isApproved).toBe(false);
|
|
612
612
|
expect(result.detailFeedback).toContain("dead link");
|
|
613
613
|
expect(result.detailFeedback).toContain("separator has 2 columns but header has 3 columns");
|
|
@@ -617,7 +617,7 @@ This content doesn't end properly`;
|
|
|
617
617
|
|
|
618
618
|
describe("Complex code block indentation cases", () => {
|
|
619
619
|
test("should reject real-world code block indentation issue", async () => {
|
|
620
|
-
const
|
|
620
|
+
const documentStructure = [];
|
|
621
621
|
const reviewContent = `# API Response Handling
|
|
622
622
|
|
|
623
623
|
You can retrieve the response body in various formats:
|
|
@@ -644,7 +644,7 @@ print(r.text)
|
|
|
644
644
|
|
|
645
645
|
This document ends properly.
|
|
646
646
|
`;
|
|
647
|
-
const result = await checkDetailResult({
|
|
647
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
648
648
|
expect(result.isApproved).toBe(false);
|
|
649
649
|
expect(result.detailFeedback).toContain("insufficient indentation");
|
|
650
650
|
});
|
|
@@ -652,7 +652,7 @@ This document ends properly.
|
|
|
652
652
|
|
|
653
653
|
describe("Advanced Mermaid validation cases", () => {
|
|
654
654
|
test("should reject Mermaid with numbered list in node labels", async () => {
|
|
655
|
-
const
|
|
655
|
+
const documentStructure = [];
|
|
656
656
|
const reviewContent = `# Test Document
|
|
657
657
|
|
|
658
658
|
\`\`\`mermaid
|
|
@@ -666,13 +666,13 @@ flowchart TD
|
|
|
666
666
|
|
|
667
667
|
This content ends properly.
|
|
668
668
|
`;
|
|
669
|
-
const result = await checkDetailResult({
|
|
669
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
670
670
|
expect(result.isApproved).toBe(false);
|
|
671
671
|
expect(result.detailFeedback).toContain("numbered list format in Mermaid node label");
|
|
672
672
|
});
|
|
673
673
|
|
|
674
674
|
test("should handle complex Mermaid with subgraph issues", async () => {
|
|
675
|
-
const
|
|
675
|
+
const documentStructure = [];
|
|
676
676
|
const reviewContent = `# Test Document
|
|
677
677
|
|
|
678
678
|
\`\`\`mermaid
|
|
@@ -691,7 +691,7 @@ flowchart TD
|
|
|
691
691
|
|
|
692
692
|
This content ends properly.
|
|
693
693
|
`;
|
|
694
|
-
const result = await checkDetailResult({
|
|
694
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
695
695
|
// This may pass or fail depending on Mermaid validation - we just ensure it doesn't crash
|
|
696
696
|
expect(typeof result.isApproved).toBe("boolean");
|
|
697
697
|
});
|
|
@@ -699,7 +699,7 @@ This content ends properly.
|
|
|
699
699
|
|
|
700
700
|
describe("Table validation with real content", () => {
|
|
701
701
|
test("should approve table with escaped pipes", async () => {
|
|
702
|
-
const
|
|
702
|
+
const documentStructure = [];
|
|
703
703
|
const reviewContent = `# Test Document
|
|
704
704
|
|
|
705
705
|
| 参数 | 类型 | 描述 |
|
|
@@ -709,33 +709,33 @@ This content ends properly.
|
|
|
709
709
|
|
|
710
710
|
This document demonstrates escaped pipe handling.
|
|
711
711
|
`;
|
|
712
|
-
const result = await checkDetailResult({
|
|
712
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
713
713
|
expect(result.isApproved).toBe(true);
|
|
714
714
|
});
|
|
715
715
|
});
|
|
716
716
|
|
|
717
717
|
describe("Error handling", () => {
|
|
718
718
|
test("should handle markdown processing errors gracefully", async () => {
|
|
719
|
-
const
|
|
719
|
+
const documentStructure = [];
|
|
720
720
|
// Test with extremely malformed content that might cause parsing errors
|
|
721
721
|
const reviewContent = null;
|
|
722
|
-
const result = await checkDetailResult({
|
|
722
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
723
723
|
expect(result.isApproved).toBe(false);
|
|
724
724
|
expect(result.detailFeedback).toBe("Review content is empty");
|
|
725
725
|
});
|
|
726
726
|
|
|
727
727
|
test("should handle empty content gracefully", async () => {
|
|
728
|
-
const
|
|
728
|
+
const documentStructure = [];
|
|
729
729
|
const reviewContent = "";
|
|
730
|
-
const result = await checkDetailResult({
|
|
730
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
731
731
|
expect(result.isApproved).toBe(false);
|
|
732
732
|
expect(result.detailFeedback).toBe("Review content is empty");
|
|
733
733
|
});
|
|
734
734
|
|
|
735
735
|
test("should handle whitespace-only content", async () => {
|
|
736
|
-
const
|
|
736
|
+
const documentStructure = [];
|
|
737
737
|
const reviewContent = " \n\n \t \n ";
|
|
738
|
-
const result = await checkDetailResult({
|
|
738
|
+
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
739
739
|
expect(result.isApproved).toBe(false);
|
|
740
740
|
expect(result.detailFeedback).toBe("Review content is empty");
|
|
741
741
|
});
|