@aigne/doc-smith 0.8.12-beta.8 → 0.8.12
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/CHANGELOG.md +15 -0
- package/agents/publish/index.yaml +4 -0
- package/agents/publish/publish-docs.mjs +77 -5
- package/agents/publish/translate-meta.mjs +103 -0
- package/agents/update/generate-document.yaml +30 -28
- package/agents/update/update-document-detail.yaml +3 -1
- package/agents/utils/update-branding.mjs +69 -0
- package/package.json +16 -2
- package/prompts/common/document/role-and-personality.md +3 -1
- package/prompts/detail/d2-diagram/guide.md +7 -1
- package/prompts/detail/d2-diagram/user-prompt.md +3 -0
- package/prompts/detail/generate/system-prompt.md +6 -7
- package/prompts/detail/generate/user-prompt.md +12 -3
- package/prompts/detail/update/user-prompt.md +0 -2
- package/prompts/structure/update/user-prompt.md +0 -4
- package/utils/file-utils.mjs +69 -24
- package/utils/markdown-checker.mjs +0 -20
- package/utils/request.mjs +7 -0
- package/utils/upload-files.mjs +231 -0
- package/utils/utils.mjs +11 -1
- package/.aigne/doc-smith/config.yaml +0 -77
- package/.aigne/doc-smith/history.yaml +0 -37
- package/.aigne/doc-smith/media-description.yaml +0 -91
- package/.aigne/doc-smith/output/structure-plan.json +0 -162
- package/.aigne/doc-smith/preferences.yml +0 -97
- package/.aigne/doc-smith/upload-cache.yaml +0 -1830
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -28
- package/.github/workflows/ci.yml +0 -54
- package/.github/workflows/create-release-pr.yaml +0 -21
- package/.github/workflows/publish-docs.yml +0 -65
- package/.github/workflows/release.yml +0 -49
- package/.github/workflows/reviewer.yml +0 -54
- package/.release-please-manifest.json +0 -3
- package/RELEASE.md +0 -9
- package/assets/screenshots/doc-complete-setup.png +0 -0
- package/assets/screenshots/doc-generate-docs.png +0 -0
- package/assets/screenshots/doc-generate.png +0 -0
- package/assets/screenshots/doc-generated-successfully.png +0 -0
- package/assets/screenshots/doc-publish.png +0 -0
- package/assets/screenshots/doc-regenerate.png +0 -0
- package/assets/screenshots/doc-translate-langs.png +0 -0
- package/assets/screenshots/doc-translate.png +0 -0
- package/assets/screenshots/doc-update.png +0 -0
- package/biome.json +0 -73
- package/codecov.yml +0 -15
- package/docs/_sidebar.md +0 -15
- package/docs/configuration-initial-setup.ja.md +0 -179
- package/docs/configuration-initial-setup.md +0 -198
- package/docs/configuration-initial-setup.zh-TW.md +0 -179
- package/docs/configuration-initial-setup.zh.md +0 -179
- package/docs/configuration-managing-preferences.ja.md +0 -100
- package/docs/configuration-managing-preferences.md +0 -100
- package/docs/configuration-managing-preferences.zh-TW.md +0 -100
- package/docs/configuration-managing-preferences.zh.md +0 -100
- package/docs/configuration.ja.md +0 -69
- package/docs/configuration.md +0 -69
- package/docs/configuration.zh-TW.md +0 -69
- package/docs/configuration.zh.md +0 -69
- package/docs/getting-started.ja.md +0 -107
- package/docs/getting-started.md +0 -107
- package/docs/getting-started.zh-TW.md +0 -107
- package/docs/getting-started.zh.md +0 -107
- package/docs/guides-cleaning-up.ja.md +0 -51
- package/docs/guides-cleaning-up.md +0 -52
- package/docs/guides-cleaning-up.zh-TW.md +0 -51
- package/docs/guides-cleaning-up.zh.md +0 -51
- package/docs/guides-evaluating-documents.ja.md +0 -66
- package/docs/guides-evaluating-documents.md +0 -107
- package/docs/guides-evaluating-documents.zh-TW.md +0 -66
- package/docs/guides-evaluating-documents.zh.md +0 -66
- package/docs/guides-generating-documentation.ja.md +0 -151
- package/docs/guides-generating-documentation.md +0 -89
- package/docs/guides-generating-documentation.zh-TW.md +0 -151
- package/docs/guides-generating-documentation.zh.md +0 -151
- package/docs/guides-interactive-chat.ja.md +0 -85
- package/docs/guides-interactive-chat.md +0 -93
- package/docs/guides-interactive-chat.zh-TW.md +0 -85
- package/docs/guides-interactive-chat.zh.md +0 -85
- package/docs/guides-managing-history.ja.md +0 -48
- package/docs/guides-managing-history.md +0 -53
- package/docs/guides-managing-history.zh-TW.md +0 -48
- package/docs/guides-managing-history.zh.md +0 -48
- package/docs/guides-publishing-your-docs.ja.md +0 -78
- package/docs/guides-publishing-your-docs.md +0 -83
- package/docs/guides-publishing-your-docs.zh-TW.md +0 -78
- package/docs/guides-publishing-your-docs.zh.md +0 -78
- package/docs/guides-translating-documentation.ja.md +0 -95
- package/docs/guides-translating-documentation.md +0 -100
- package/docs/guides-translating-documentation.zh-TW.md +0 -95
- package/docs/guides-translating-documentation.zh.md +0 -95
- package/docs/guides-updating-documentation.ja.md +0 -77
- package/docs/guides-updating-documentation.md +0 -79
- package/docs/guides-updating-documentation.zh-TW.md +0 -77
- package/docs/guides-updating-documentation.zh.md +0 -77
- package/docs/guides.ja.md +0 -32
- package/docs/guides.md +0 -32
- package/docs/guides.zh-TW.md +0 -32
- package/docs/guides.zh.md +0 -32
- package/docs/overview.ja.md +0 -61
- package/docs/overview.md +0 -61
- package/docs/overview.zh-TW.md +0 -61
- package/docs/overview.zh.md +0 -61
- package/docs/release-notes.ja.md +0 -255
- package/docs/release-notes.md +0 -288
- package/docs/release-notes.zh-TW.md +0 -255
- package/docs/release-notes.zh.md +0 -255
- package/prompts/common/afs/afs-tools-usage.md +0 -5
- package/prompts/common/afs/use-afs-instruction.md +0 -1
- package/release-please-config.json +0 -14
- package/tests/agents/chat/chat.test.mjs +0 -46
- package/tests/agents/clear/choose-contents.test.mjs +0 -284
- package/tests/agents/clear/clear-auth-tokens.test.mjs +0 -268
- package/tests/agents/clear/clear-document-config.test.mjs +0 -167
- package/tests/agents/clear/clear-document-structure.test.mjs +0 -380
- package/tests/agents/clear/clear-generated-docs.test.mjs +0 -222
- package/tests/agents/evaluate/code-snippet.test.mjs +0 -163
- package/tests/agents/evaluate/fixtures/api-services.md +0 -87
- package/tests/agents/evaluate/fixtures/js-sdk.md +0 -94
- package/tests/agents/evaluate/generate-report.test.mjs +0 -312
- package/tests/agents/generate/check-document-structure.test.mjs +0 -45
- package/tests/agents/generate/check-need-generate-structure.test.mjs +0 -279
- package/tests/agents/generate/document-structure-tools/add-document.test.mjs +0 -449
- package/tests/agents/generate/document-structure-tools/delete-document.test.mjs +0 -410
- package/tests/agents/generate/document-structure-tools/generate-sub-structure.test.mjs +0 -277
- package/tests/agents/generate/document-structure-tools/move-document.test.mjs +0 -476
- package/tests/agents/generate/document-structure-tools/update-document.test.mjs +0 -548
- package/tests/agents/generate/generate-structure.test.mjs +0 -45
- package/tests/agents/generate/user-review-document-structure.test.mjs +0 -319
- package/tests/agents/history/view.test.mjs +0 -97
- package/tests/agents/init/init.test.mjs +0 -1657
- package/tests/agents/prefs/prefs.test.mjs +0 -431
- package/tests/agents/publish/publish-docs.test.mjs +0 -787
- package/tests/agents/translate/choose-language.test.mjs +0 -311
- package/tests/agents/translate/translate-document.test.mjs +0 -51
- package/tests/agents/update/check-document.test.mjs +0 -463
- package/tests/agents/update/check-update-is-single.test.mjs +0 -300
- package/tests/agents/update/document-tools/update-document-content.test.mjs +0 -329
- package/tests/agents/update/generate-document.test.mjs +0 -51
- package/tests/agents/update/save-and-translate-document.test.mjs +0 -369
- package/tests/agents/update/user-review-document.test.mjs +0 -582
- package/tests/agents/utils/action-success.test.mjs +0 -54
- package/tests/agents/utils/check-detail-result.test.mjs +0 -743
- package/tests/agents/utils/check-feedback-refiner.test.mjs +0 -478
- package/tests/agents/utils/choose-docs.test.mjs +0 -406
- package/tests/agents/utils/exit.test.mjs +0 -70
- package/tests/agents/utils/feedback-refiner.test.mjs +0 -51
- package/tests/agents/utils/find-item-by-path.test.mjs +0 -517
- package/tests/agents/utils/find-user-preferences-by-path.test.mjs +0 -382
- package/tests/agents/utils/format-document-structure.test.mjs +0 -364
- package/tests/agents/utils/fs.test.mjs +0 -267
- package/tests/agents/utils/load-sources.test.mjs +0 -1470
- package/tests/agents/utils/save-docs.test.mjs +0 -109
- package/tests/agents/utils/save-output.test.mjs +0 -315
- package/tests/agents/utils/save-single-doc.test.mjs +0 -364
- package/tests/agents/utils/transform-detail-datasources.test.mjs +0 -320
- package/tests/utils/auth-utils.test.mjs +0 -596
- package/tests/utils/blocklet.test.mjs +0 -336
- package/tests/utils/conflict-detector.test.mjs +0 -355
- package/tests/utils/constants.test.mjs +0 -295
- package/tests/utils/d2-utils.test.mjs +0 -437
- package/tests/utils/deploy.test.mjs +0 -399
- package/tests/utils/docs-finder-utils.test.mjs +0 -650
- package/tests/utils/file-utils.test.mjs +0 -521
- package/tests/utils/history-utils.test.mjs +0 -206
- package/tests/utils/kroki-utils.test.mjs +0 -646
- package/tests/utils/linter/fixtures/css/keyword-error.css +0 -1
- package/tests/utils/linter/fixtures/css/missing-semicolon.css +0 -1
- package/tests/utils/linter/fixtures/css/syntax-error.css +0 -1
- package/tests/utils/linter/fixtures/css/undeclare-variable.css +0 -1
- package/tests/utils/linter/fixtures/css/unused-variable.css +0 -2
- package/tests/utils/linter/fixtures/css/valid-code.css +0 -1
- package/tests/utils/linter/fixtures/dockerfile/keyword-error.dockerfile +0 -1
- package/tests/utils/linter/fixtures/dockerfile/missing-semicolon.dockerfile +0 -2
- package/tests/utils/linter/fixtures/dockerfile/syntax-error.dockerfile +0 -2
- package/tests/utils/linter/fixtures/dockerfile/undeclare-variable.dockerfile +0 -1
- package/tests/utils/linter/fixtures/dockerfile/unused-variable.dockerfile +0 -1
- package/tests/utils/linter/fixtures/dockerfile/valid-code.dockerfile +0 -2
- package/tests/utils/linter/fixtures/go/keyword-error.go +0 -5
- package/tests/utils/linter/fixtures/go/missing-semicolon.go +0 -5
- package/tests/utils/linter/fixtures/go/syntax-error.go +0 -6
- package/tests/utils/linter/fixtures/go/undeclare-variable.go +0 -5
- package/tests/utils/linter/fixtures/go/unused-variable.go +0 -5
- package/tests/utils/linter/fixtures/go/valid-code.go +0 -7
- package/tests/utils/linter/fixtures/js/keyword-error.js +0 -3
- package/tests/utils/linter/fixtures/js/missing-semicolon.js +0 -6
- package/tests/utils/linter/fixtures/js/syntax-error.js +0 -4
- package/tests/utils/linter/fixtures/js/undeclare-variable.js +0 -3
- package/tests/utils/linter/fixtures/js/unused-variable.js +0 -7
- package/tests/utils/linter/fixtures/js/valid-code.js +0 -15
- package/tests/utils/linter/fixtures/json/keyword-error.json +0 -1
- package/tests/utils/linter/fixtures/json/missing-semicolon.json +0 -1
- package/tests/utils/linter/fixtures/json/syntax-error.json +0 -1
- package/tests/utils/linter/fixtures/json/undeclare-variable.json +0 -1
- package/tests/utils/linter/fixtures/json/unused-variable.json +0 -1
- package/tests/utils/linter/fixtures/json/valid-code.json +0 -1
- package/tests/utils/linter/fixtures/jsx/keyword-error.jsx +0 -5
- package/tests/utils/linter/fixtures/jsx/missing-semicolon.jsx +0 -5
- package/tests/utils/linter/fixtures/jsx/syntax-error.jsx +0 -5
- package/tests/utils/linter/fixtures/jsx/undeclare-variable.jsx +0 -5
- package/tests/utils/linter/fixtures/jsx/unused-variable.jsx +0 -4
- package/tests/utils/linter/fixtures/jsx/valid-code.jsx +0 -5
- package/tests/utils/linter/fixtures/python/keyword-error.py +0 -3
- package/tests/utils/linter/fixtures/python/missing-semicolon.py +0 -2
- package/tests/utils/linter/fixtures/python/syntax-error.py +0 -3
- package/tests/utils/linter/fixtures/python/undeclare-variable.py +0 -3
- package/tests/utils/linter/fixtures/python/unused-variable.py +0 -6
- package/tests/utils/linter/fixtures/python/valid-code.py +0 -12
- package/tests/utils/linter/fixtures/ruby/keyword-error.rb +0 -2
- package/tests/utils/linter/fixtures/ruby/missing-semicolon.rb +0 -1
- package/tests/utils/linter/fixtures/ruby/syntax-error.rb +0 -2
- package/tests/utils/linter/fixtures/ruby/undeclare-variable.rb +0 -1
- package/tests/utils/linter/fixtures/ruby/unused-variable.rb +0 -2
- package/tests/utils/linter/fixtures/ruby/valid-code.rb +0 -1
- package/tests/utils/linter/fixtures/sass/keyword-error.sass +0 -2
- package/tests/utils/linter/fixtures/sass/missing-semicolon.sass +0 -3
- package/tests/utils/linter/fixtures/sass/syntax-error.sass +0 -3
- package/tests/utils/linter/fixtures/sass/undeclare-variable.sass +0 -2
- package/tests/utils/linter/fixtures/sass/unused-variable.sass +0 -4
- package/tests/utils/linter/fixtures/sass/valid-code.sass +0 -2
- package/tests/utils/linter/fixtures/scss/keyword-error.scss +0 -1
- package/tests/utils/linter/fixtures/scss/missing-semicolon.scss +0 -1
- package/tests/utils/linter/fixtures/scss/syntax-error.scss +0 -1
- package/tests/utils/linter/fixtures/scss/undeclare-variable.scss +0 -1
- package/tests/utils/linter/fixtures/scss/unused-variable.scss +0 -2
- package/tests/utils/linter/fixtures/scss/valid-code.scss +0 -1
- package/tests/utils/linter/fixtures/shell/keyword-error.sh +0 -5
- package/tests/utils/linter/fixtures/shell/missing-semicolon.sh +0 -3
- package/tests/utils/linter/fixtures/shell/syntax-error.sh +0 -4
- package/tests/utils/linter/fixtures/shell/undeclare-variable.sh +0 -3
- package/tests/utils/linter/fixtures/shell/unused-variable.sh +0 -4
- package/tests/utils/linter/fixtures/shell/valid-code.sh +0 -3
- package/tests/utils/linter/fixtures/ts/keyword-error.ts +0 -1
- package/tests/utils/linter/fixtures/ts/missing-semicolon.ts +0 -1
- package/tests/utils/linter/fixtures/ts/syntax-error.ts +0 -1
- package/tests/utils/linter/fixtures/ts/undeclare-variable.ts +0 -1
- package/tests/utils/linter/fixtures/ts/unused-variable.ts +0 -3
- package/tests/utils/linter/fixtures/ts/valid-code.ts +0 -3
- package/tests/utils/linter/fixtures/tsx/keyword-error.tsx +0 -5
- package/tests/utils/linter/fixtures/tsx/missing-semicolon.tsx +0 -5
- package/tests/utils/linter/fixtures/tsx/syntax-error.tsx +0 -5
- package/tests/utils/linter/fixtures/tsx/undeclare-variable.tsx +0 -6
- package/tests/utils/linter/fixtures/tsx/unused-variable.tsx +0 -6
- package/tests/utils/linter/fixtures/tsx/valid-code.tsx +0 -5
- package/tests/utils/linter/fixtures/vue/keyword-error.vue +0 -6
- package/tests/utils/linter/fixtures/vue/missing-semicolon.vue +0 -6
- package/tests/utils/linter/fixtures/vue/syntax-error.vue +0 -6
- package/tests/utils/linter/fixtures/vue/undeclare-variable.vue +0 -6
- package/tests/utils/linter/fixtures/vue/unused-variable.vue +0 -7
- package/tests/utils/linter/fixtures/vue/valid-code.vue +0 -6
- package/tests/utils/linter/fixtures/yaml/keyword-error.yml +0 -1
- package/tests/utils/linter/fixtures/yaml/missing-semicolon.yml +0 -2
- package/tests/utils/linter/fixtures/yaml/syntax-error.yml +0 -1
- package/tests/utils/linter/fixtures/yaml/undeclare-variable.yml +0 -1
- package/tests/utils/linter/fixtures/yaml/unused-variable.yml +0 -2
- package/tests/utils/linter/fixtures/yaml/valid-code.yml +0 -3
- package/tests/utils/linter/index.test.mjs +0 -440
- package/tests/utils/linter/scan-results.mjs +0 -42
- package/tests/utils/load-config.test.mjs +0 -141
- package/tests/utils/markdown/index.test.mjs +0 -478
- package/tests/utils/mermaid-validator.test.mjs +0 -541
- package/tests/utils/mock-chat-model.mjs +0 -12
- package/tests/utils/preferences-utils.test.mjs +0 -465
- package/tests/utils/save-value-to-config.test.mjs +0 -483
- package/tests/utils/utils.test.mjs +0 -941
|
@@ -1,743 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "bun:test";
|
|
2
|
-
import checkDetailResult from "../../../agents/utils/check-detail-result.mjs";
|
|
3
|
-
|
|
4
|
-
describe("check-detail-result", () => {
|
|
5
|
-
test("should approve valid content", async () => {
|
|
6
|
-
const documentStructure = [{ path: "/getting-started" }];
|
|
7
|
-
const reviewContent =
|
|
8
|
-
"This is a test with a [valid link](/getting-started).\n\nThis has proper structure with multiple lines.";
|
|
9
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
10
|
-
expect(result.isApproved).toBe(true);
|
|
11
|
-
expect(result.detailFeedback).toBe("");
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
test("should reject content with a dead link", async () => {
|
|
15
|
-
const documentStructure = [{ path: "/getting-started" }];
|
|
16
|
-
const reviewContent = "This contains a [dead link](/dead-link).";
|
|
17
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
18
|
-
expect(result.isApproved).toBe(false);
|
|
19
|
-
expect(result.detailFeedback).toContain("Found a dead link");
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
test("should accept valid table format", async () => {
|
|
23
|
-
const documentStructure = [];
|
|
24
|
-
const reviewContent =
|
|
25
|
-
"| Header | Header |\n|--------|--------|\n| Cell | Cell |\n\nThis table is properly formatted.";
|
|
26
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
27
|
-
expect(result.isApproved).toBe(true);
|
|
28
|
-
expect(result.detailFeedback).toBe("");
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
test("should approve content with an external link", async () => {
|
|
32
|
-
const documentStructure = [];
|
|
33
|
-
const reviewContent =
|
|
34
|
-
"This is a [valid external link](https://example.com).\n\nThis has proper multi-line structure.";
|
|
35
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
36
|
-
expect(result.isApproved).toBe(true);
|
|
37
|
-
expect(result.detailFeedback).toBe("");
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
test("should approve content with valid local image path", async () => {
|
|
41
|
-
const documentStructure = [];
|
|
42
|
-
const reviewContent =
|
|
43
|
-
"This is a valid image .\n\nThis has proper structure.";
|
|
44
|
-
const docsDir = process.cwd();
|
|
45
|
-
const result = await checkDetailResult({ documentStructure, reviewContent, docsDir });
|
|
46
|
-
expect(result.isApproved).toBe(true);
|
|
47
|
-
expect(result.detailFeedback).toBe("");
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test("should reject content with invalid local image path", async () => {
|
|
51
|
-
const documentStructure = [];
|
|
52
|
-
const reviewContent =
|
|
53
|
-
"This is an invalid image .\n\nThis has proper structure.";
|
|
54
|
-
const docsDir = process.cwd();
|
|
55
|
-
const result = await checkDetailResult({ documentStructure, reviewContent, docsDir });
|
|
56
|
-
expect(result.isApproved).toBe(false);
|
|
57
|
-
expect(result.detailFeedback).toContain("Found invalid local image");
|
|
58
|
-
expect(result.detailFeedback).toContain("only valid media resources can be used");
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
test("should approve content with absolute image path that exists", async () => {
|
|
62
|
-
const documentStructure = [];
|
|
63
|
-
const reviewContent = `This is an absolute image }/README.md).\n\nThis has proper structure.`;
|
|
64
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
65
|
-
expect(result.isApproved).toBe(true);
|
|
66
|
-
expect(result.detailFeedback).toBe("");
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
test("should reject content with absolute image path that doesn't exist", async () => {
|
|
70
|
-
const documentStructure = [];
|
|
71
|
-
const reviewContent =
|
|
72
|
-
"This is an invalid absolute image .\n\nThis has proper structure.";
|
|
73
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
74
|
-
expect(result.isApproved).toBe(false);
|
|
75
|
-
expect(result.detailFeedback).toContain("Found invalid local image");
|
|
76
|
-
expect(result.detailFeedback).toContain("only valid media resources can be used");
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
test("should approve content with external image URL", async () => {
|
|
80
|
-
const documentStructure = [];
|
|
81
|
-
const reviewContent =
|
|
82
|
-
"This is an external image .\n\nThis has proper structure.";
|
|
83
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
84
|
-
expect(result.isApproved).toBe(true);
|
|
85
|
-
expect(result.detailFeedback).toBe("");
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
describe("Table validation", () => {
|
|
89
|
-
test("should reject table with mismatched column count", async () => {
|
|
90
|
-
const documentStructure = [];
|
|
91
|
-
const reviewContent =
|
|
92
|
-
"| Header 1 | Header 2 | Header 3 |\n" +
|
|
93
|
-
"|----------|----------|\n" + // Only 2 separator columns but 3 header columns
|
|
94
|
-
"| Cell 1 | Cell 2 | Cell 3 |";
|
|
95
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
96
|
-
expect(result.isApproved).toBe(false);
|
|
97
|
-
expect(result.detailFeedback).toContain("separator has 2 columns but header has 3 columns");
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
test("should reject table with data row column mismatch", async () => {
|
|
101
|
-
const documentStructure = [];
|
|
102
|
-
const reviewContent =
|
|
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({ documentStructure, reviewContent });
|
|
105
|
-
expect(result.isApproved).toBe(false);
|
|
106
|
-
expect(result.detailFeedback).toContain(
|
|
107
|
-
"data row has 3 columns but separator defines 2 columns",
|
|
108
|
-
);
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
test("should handle complex table with pipes in content", async () => {
|
|
112
|
-
const documentStructure = [];
|
|
113
|
-
const reviewContent =
|
|
114
|
-
"| Code | Description |\n" +
|
|
115
|
-
"|------|-------------|\n" +
|
|
116
|
-
"| `a \\| b` | This has escaped pipe |\n" +
|
|
117
|
-
"| `c | d` | This has unescaped pipe in code |";
|
|
118
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
119
|
-
expect(result.isApproved).toBe(true);
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
describe("Code block validation", () => {
|
|
124
|
-
test("should reject incomplete code blocks", async () => {
|
|
125
|
-
const documentStructure = [];
|
|
126
|
-
const reviewContent =
|
|
127
|
-
"Here is some code:\n\n" +
|
|
128
|
-
"```javascript\n" +
|
|
129
|
-
"function test() {\n" +
|
|
130
|
-
" return 'incomplete';\n" +
|
|
131
|
-
"}\n"; // Missing closing ```
|
|
132
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
133
|
-
expect(result.isApproved).toBe(false);
|
|
134
|
-
expect(result.detailFeedback).toContain("incomplete code block");
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
test("should detect code block indentation issues", async () => {
|
|
138
|
-
const documentStructure = [];
|
|
139
|
-
const reviewContent =
|
|
140
|
-
" ```javascript\n" +
|
|
141
|
-
"function test() {\n" + // This line has insufficient indentation
|
|
142
|
-
" return 'test';\n" +
|
|
143
|
-
" }\n" +
|
|
144
|
-
" ```";
|
|
145
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
146
|
-
expect(result.isApproved).toBe(false);
|
|
147
|
-
expect(result.detailFeedback).toContain("insufficient indentation");
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
test("should approve various programming language code blocks with proper detection", async () => {
|
|
151
|
-
const documentStructure = [];
|
|
152
|
-
const reviewContent = `Programming Language Examples:
|
|
153
|
-
|
|
154
|
-
## Rust with Configuration
|
|
155
|
-
\`\`\`rust,no_run
|
|
156
|
-
use tokio::signal::windows::ctrl_shutdown;
|
|
157
|
-
|
|
158
|
-
#[tokio::main]
|
|
159
|
-
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
160
|
-
let mut signal = ctrl_shutdown()?;
|
|
161
|
-
signal.recv().await;
|
|
162
|
-
println!("got CTRL-SHUTDOWN. Cleaning up before exiting");
|
|
163
|
-
Ok(())
|
|
164
|
-
}
|
|
165
|
-
\`\`\`
|
|
166
|
-
|
|
167
|
-
## C# .NET Example
|
|
168
|
-
\`\`\`c#
|
|
169
|
-
using System;
|
|
170
|
-
using System.Threading.Tasks;
|
|
171
|
-
|
|
172
|
-
public class Program
|
|
173
|
-
{
|
|
174
|
-
public static async Task Main(string[] args)
|
|
175
|
-
{
|
|
176
|
-
Console.WriteLine("Hello C#!");
|
|
177
|
-
await Task.Delay(1000);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
\`\`\`
|
|
181
|
-
|
|
182
|
-
## C++ with CLI Extension
|
|
183
|
-
\`\`\`c++/cli
|
|
184
|
-
#include <iostream>
|
|
185
|
-
#include <vector>
|
|
186
|
-
|
|
187
|
-
int main() {
|
|
188
|
-
std::vector<int> numbers = {1, 2, 3, 4, 5};
|
|
189
|
-
for (const auto& num : numbers) {
|
|
190
|
-
std::cout << num << " ";
|
|
191
|
-
}
|
|
192
|
-
return 0;
|
|
193
|
-
}
|
|
194
|
-
\`\`\`
|
|
195
|
-
|
|
196
|
-
## TypeScript with Extension
|
|
197
|
-
\`\`\`typescript.tsx
|
|
198
|
-
interface Props {
|
|
199
|
-
title: string;
|
|
200
|
-
count: number;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
const Component: React.FC<Props> = ({ title, count }) => {
|
|
204
|
-
return <div>{title}: {count}</div>;
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
export default Component;
|
|
208
|
-
\`\`\`
|
|
209
|
-
|
|
210
|
-
## Python with Version
|
|
211
|
-
\`\`\`python,version=3.9
|
|
212
|
-
import asyncio
|
|
213
|
-
from typing import List, Optional
|
|
214
|
-
|
|
215
|
-
async def fetch_data(urls: List[str]) -> Optional[dict]:
|
|
216
|
-
tasks = [asyncio.create_task(process_url(url)) for url in urls]
|
|
217
|
-
results = await asyncio.gather(*tasks)
|
|
218
|
-
return {"results": results}
|
|
219
|
-
|
|
220
|
-
if __name__ == "__main__":
|
|
221
|
-
asyncio.run(fetch_data(["http://example.com"]))
|
|
222
|
-
\`\`\`
|
|
223
|
-
|
|
224
|
-
## Shell Script with Latest Tag
|
|
225
|
-
\`\`\`bash:latest
|
|
226
|
-
#!/bin/bash
|
|
227
|
-
set -euo pipefail
|
|
228
|
-
|
|
229
|
-
function deploy_app() {
|
|
230
|
-
local app_name="$1"
|
|
231
|
-
local version="$2"
|
|
232
|
-
|
|
233
|
-
echo "Deploying $app_name version $version"
|
|
234
|
-
docker run --rm "$app_name:$version"
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
deploy_app "my-app" "v1.0.0"
|
|
238
|
-
\`\`\`
|
|
239
|
-
|
|
240
|
-
## Node.js Configuration
|
|
241
|
-
\`\`\`node.js
|
|
242
|
-
const express = require('express');
|
|
243
|
-
const app = express();
|
|
244
|
-
const PORT = process.env.PORT || 3000;
|
|
245
|
-
|
|
246
|
-
app.get('/health', (req, res) => {
|
|
247
|
-
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
app.listen(PORT, () => {
|
|
251
|
-
console.log(\`Server running on port \${PORT}\`);
|
|
252
|
-
});
|
|
253
|
-
\`\`\`
|
|
254
|
-
|
|
255
|
-
This document demonstrates various programming language code blocks.`;
|
|
256
|
-
|
|
257
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
258
|
-
expect(result.isApproved).toBe(true);
|
|
259
|
-
expect(result.detailFeedback).toBe("");
|
|
260
|
-
});
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
describe("Content structure validation", () => {
|
|
264
|
-
test("should reject single line content", async () => {
|
|
265
|
-
const documentStructure = [];
|
|
266
|
-
const reviewContent = "This is a single line without proper line breaks";
|
|
267
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
268
|
-
expect(result.isApproved).toBe(false);
|
|
269
|
-
expect(result.detailFeedback).toContain("single line content");
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
test("should reject incomplete content without proper ending", async () => {
|
|
273
|
-
const documentStructure = [];
|
|
274
|
-
const reviewContent = "This content doesn't end properly\n\nNo proper punctuation";
|
|
275
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
276
|
-
expect(result.isApproved).toBe(false);
|
|
277
|
-
expect(result.detailFeedback).toContain("incomplete content");
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
test("should approve content with valid ending punctuation", async () => {
|
|
281
|
-
const documentStructure = [];
|
|
282
|
-
const reviewContent = "This content ends properly.\n\nWith valid punctuation.";
|
|
283
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
284
|
-
expect(result.isApproved).toBe(true);
|
|
285
|
-
});
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
describe("Mermaid syntax validation", () => {
|
|
289
|
-
test("should reject Mermaid with backticks in node labels", async () => {
|
|
290
|
-
const documentStructure = [];
|
|
291
|
-
const reviewContent =
|
|
292
|
-
"```mermaid\n" + "graph TD\n" + ' A["Contains `backticks` in label"]\n' + "```";
|
|
293
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
294
|
-
expect(result.isApproved).toBe(false);
|
|
295
|
-
expect(result.detailFeedback).toContain("backticks in Mermaid node label");
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
test("should reject Mermaid with numbered lists in node labels", async () => {
|
|
299
|
-
const documentStructure = [];
|
|
300
|
-
const reviewContent =
|
|
301
|
-
"```mermaid\n" + "graph TD\n" + ' A["1. First item\\n2. Second item"]\n' + "```";
|
|
302
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
303
|
-
expect(result.isApproved).toBe(false);
|
|
304
|
-
expect(result.detailFeedback).toContain("numbered list format in Mermaid node label");
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
test("should reject Mermaid with numbered lists in edge descriptions", async () => {
|
|
308
|
-
const documentStructure = [];
|
|
309
|
-
const reviewContent =
|
|
310
|
-
"```mermaid\n" + "graph TD\n" + ' A -- "1. First step" --> B\n' + "```";
|
|
311
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
312
|
-
expect(result.isApproved).toBe(false);
|
|
313
|
-
expect(result.detailFeedback).toContain("numbered list format in Mermaid edge description");
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
test("should reject Mermaid with unquoted special characters", async () => {
|
|
317
|
-
const documentStructure = [];
|
|
318
|
-
const reviewContent =
|
|
319
|
-
"```mermaid\n" + "graph TD\n" + " A[Node with: special chars]\n" + "```";
|
|
320
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
321
|
-
expect(result.isApproved).toBe(false);
|
|
322
|
-
expect(result.detailFeedback).toContain("unquoted special characters in Mermaid node label");
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
test("should approve properly formatted Mermaid", async () => {
|
|
326
|
-
const documentStructure = [];
|
|
327
|
-
const reviewContent =
|
|
328
|
-
"```mermaid\n" +
|
|
329
|
-
"graph TD\n" +
|
|
330
|
-
' A["Properly quoted label"]\n' +
|
|
331
|
-
' B["Another node"]\n' +
|
|
332
|
-
" A --> B\n" +
|
|
333
|
-
"```\n\n" +
|
|
334
|
-
"This diagram is properly formatted.";
|
|
335
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
336
|
-
expect(result.isApproved).toBe(true);
|
|
337
|
-
});
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
describe("D2 syntax validation", () => {
|
|
341
|
-
test("should handle D2 syntax errors", async () => {
|
|
342
|
-
const documentStructure = [];
|
|
343
|
-
const reviewContent =
|
|
344
|
-
"```d2\n" +
|
|
345
|
-
"invalid d2 syntax {{\n" + // Malformed D2
|
|
346
|
-
"```\n\n" +
|
|
347
|
-
"This has proper structure.";
|
|
348
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
349
|
-
expect(result.isApproved).toBe(false);
|
|
350
|
-
});
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
describe("Advanced table edge cases", () => {
|
|
354
|
-
test("should handle empty table cells correctly", async () => {
|
|
355
|
-
const documentStructure = [];
|
|
356
|
-
const reviewContent =
|
|
357
|
-
"| Header 1 | Header 2 | Header 3 |\n" +
|
|
358
|
-
"|----------|----------|----------|\n" +
|
|
359
|
-
"| Cell 1 | | Cell 3 |\n" +
|
|
360
|
-
"| | Cell 2 | |";
|
|
361
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
362
|
-
expect(result.isApproved).toBe(true);
|
|
363
|
-
});
|
|
364
|
-
|
|
365
|
-
test("should handle tables with code spans containing pipes", async () => {
|
|
366
|
-
const documentStructure = [];
|
|
367
|
-
const reviewContent =
|
|
368
|
-
"| Function | Code Example |\n" +
|
|
369
|
-
"|----------|---------------|\n" +
|
|
370
|
-
"| pipe | `a \\| b` |\n" +
|
|
371
|
-
"| filter | `data \\| filter` |";
|
|
372
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
373
|
-
expect(result.isApproved).toBe(true);
|
|
374
|
-
});
|
|
375
|
-
});
|
|
376
|
-
|
|
377
|
-
describe("Code block edge cases", () => {
|
|
378
|
-
test("should handle nested code blocks properly", async () => {
|
|
379
|
-
const documentStructure = [];
|
|
380
|
-
const reviewContent =
|
|
381
|
-
"Here's a markdown example:\n\n" +
|
|
382
|
-
"```markdown\n" +
|
|
383
|
-
"# Title\n" +
|
|
384
|
-
"\n" +
|
|
385
|
-
"```javascript\n" +
|
|
386
|
-
"function test() { return true; }\n" +
|
|
387
|
-
"```\n" +
|
|
388
|
-
"```\n\n" +
|
|
389
|
-
"This content ends properly.";
|
|
390
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
391
|
-
expect(result.isApproved).toBe(true);
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
test("should handle code blocks with unusual indentation patterns", async () => {
|
|
395
|
-
const documentStructure = [];
|
|
396
|
-
const reviewContent =
|
|
397
|
-
" ```javascript\n" +
|
|
398
|
-
" function test() {\n" +
|
|
399
|
-
" return 'properly indented';\n" +
|
|
400
|
-
" }\n" +
|
|
401
|
-
" ```\n\n" +
|
|
402
|
-
"This has proper structure.";
|
|
403
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
404
|
-
expect(result.isApproved).toBe(true);
|
|
405
|
-
});
|
|
406
|
-
});
|
|
407
|
-
|
|
408
|
-
describe("Complex Mermaid scenarios", () => {
|
|
409
|
-
test("should handle Mermaid with curly brace syntax", async () => {
|
|
410
|
-
const documentStructure = [];
|
|
411
|
-
const reviewContent =
|
|
412
|
-
"```mermaid\n" +
|
|
413
|
-
"graph TD\n" +
|
|
414
|
-
' A{"Decision point"}\n' +
|
|
415
|
-
' B["Action"]\n' +
|
|
416
|
-
" A --> B\n" +
|
|
417
|
-
"```\n\n" +
|
|
418
|
-
"This diagram uses proper syntax.";
|
|
419
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
420
|
-
expect(result.isApproved).toBe(true);
|
|
421
|
-
});
|
|
422
|
-
|
|
423
|
-
test("should reject Mermaid with problematic curly brace labels", async () => {
|
|
424
|
-
const documentStructure = [];
|
|
425
|
-
const reviewContent =
|
|
426
|
-
"```mermaid\n" + "graph TD\n" + ' A{"Contains `backticks` problem"}\n' + "```";
|
|
427
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
428
|
-
expect(result.isApproved).toBe(false);
|
|
429
|
-
expect(result.detailFeedback).toContain("backticks in Mermaid node label");
|
|
430
|
-
});
|
|
431
|
-
});
|
|
432
|
-
|
|
433
|
-
describe("Image validation edge cases", () => {
|
|
434
|
-
test("should approve data URLs in images", async () => {
|
|
435
|
-
const documentStructure = [];
|
|
436
|
-
const reviewContent =
|
|
437
|
-
"Here's an inline image .\n\n" +
|
|
438
|
-
"This has proper structure.";
|
|
439
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
440
|
-
expect(result.isApproved).toBe(true);
|
|
441
|
-
});
|
|
442
|
-
|
|
443
|
-
test("should handle images with complex alt text", async () => {
|
|
444
|
-
const documentStructure = [];
|
|
445
|
-
const reviewContent =
|
|
446
|
-
"![Complex alt text with [brackets] and (parentheses)](https://example.com/image.png)\n\n" +
|
|
447
|
-
"This has proper structure.";
|
|
448
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
449
|
-
expect(result.isApproved).toBe(true);
|
|
450
|
-
});
|
|
451
|
-
});
|
|
452
|
-
|
|
453
|
-
describe("Link validation edge cases", () => {
|
|
454
|
-
test("should handle mailto links correctly", async () => {
|
|
455
|
-
const documentStructure = [];
|
|
456
|
-
const reviewContent =
|
|
457
|
-
"Contact us at [email](mailto:test@example.com).\n\n" + "This has proper structure.";
|
|
458
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
459
|
-
expect(result.isApproved).toBe(true);
|
|
460
|
-
});
|
|
461
|
-
|
|
462
|
-
test("should handle links with anchors", async () => {
|
|
463
|
-
const documentStructure = [{ path: "/getting-started" }];
|
|
464
|
-
const reviewContent =
|
|
465
|
-
"See the [installation section](/getting-started#installation).\n\n" +
|
|
466
|
-
"This has proper structure.";
|
|
467
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
468
|
-
expect(result.isApproved).toBe(true);
|
|
469
|
-
});
|
|
470
|
-
|
|
471
|
-
test("should handle anchor-only links without base path", async () => {
|
|
472
|
-
const documentStructure = [];
|
|
473
|
-
const reviewContent =
|
|
474
|
-
"See the [section](#non-existent-anchor).\n\n" + "This has proper structure.";
|
|
475
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
476
|
-
expect(result.isApproved).toBe(true);
|
|
477
|
-
});
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
describe("Content structure edge cases", () => {
|
|
481
|
-
test("should approve content ending with table", async () => {
|
|
482
|
-
const documentStructure = [];
|
|
483
|
-
const reviewContent =
|
|
484
|
-
"Here's a data table:\n\n" +
|
|
485
|
-
"| Column 1 | Column 2 |\n" +
|
|
486
|
-
"|----------|----------|\n" +
|
|
487
|
-
"| Data 1 | Data 2 |";
|
|
488
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
489
|
-
expect(result.isApproved).toBe(true);
|
|
490
|
-
});
|
|
491
|
-
|
|
492
|
-
test("should approve content ending with list", async () => {
|
|
493
|
-
const documentStructure = [];
|
|
494
|
-
const reviewContent =
|
|
495
|
-
"Here are the requirements:\n\n" +
|
|
496
|
-
"- First requirement\n" +
|
|
497
|
-
"- Second requirement\n" +
|
|
498
|
-
"- Third requirement*";
|
|
499
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
500
|
-
expect(result.isApproved).toBe(true);
|
|
501
|
-
});
|
|
502
|
-
|
|
503
|
-
test("should approve content ending with blockquote", async () => {
|
|
504
|
-
const documentStructure = [];
|
|
505
|
-
const reviewContent =
|
|
506
|
-
"As they say:\n\n" + "> This is a famous quote that ends with proper punctuation.";
|
|
507
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
508
|
-
expect(result.isApproved).toBe(true);
|
|
509
|
-
});
|
|
510
|
-
});
|
|
511
|
-
|
|
512
|
-
describe("Real-world scenario tests", () => {
|
|
513
|
-
test("should approve comprehensive valid document", async () => {
|
|
514
|
-
const documentStructure = [
|
|
515
|
-
{ path: "./getting-started" },
|
|
516
|
-
{ path: "/api/overview" },
|
|
517
|
-
{ path: "./advanced/configuration" },
|
|
518
|
-
];
|
|
519
|
-
const reviewContent = `# Getting Started Guide
|
|
520
|
-
|
|
521
|
-
This is a complete document with proper structure and formatting.
|
|
522
|
-
|
|
523
|
-
## Introduction
|
|
524
|
-
|
|
525
|
-
Welcome to our comprehensive guide. This document follows all markdown best practices.
|
|
526
|
-
|
|
527
|
-
## Code Examples
|
|
528
|
-
|
|
529
|
-
Here's a properly formatted code block:
|
|
530
|
-
|
|
531
|
-
\`\`\`javascript
|
|
532
|
-
function validateInput(data) {
|
|
533
|
-
if (!data) {
|
|
534
|
-
throw new Error("Data is required");
|
|
535
|
-
}
|
|
536
|
-
return data.trim();
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
// Export the function
|
|
540
|
-
export { validateInput };
|
|
541
|
-
\`\`\`
|
|
542
|
-
|
|
543
|
-
## Data Tables
|
|
544
|
-
|
|
545
|
-
Our API supports the following data types:
|
|
546
|
-
|
|
547
|
-
|Type|Description|Example|
|
|
548
|
-
|----|-----------|-------|
|
|
549
|
-
|String|Text data|"Hello"|
|
|
550
|
-
|Number|Numeric values|42|
|
|
551
|
-
|Boolean|True/false|true|
|
|
552
|
-
|
|
553
|
-
## Process Flow
|
|
554
|
-
|
|
555
|
-
The following diagram shows our validation process:
|
|
556
|
-
|
|
557
|
-
\`\`\`mermaid
|
|
558
|
-
flowchart TD
|
|
559
|
-
A[Start] --> B{Valid Input?}
|
|
560
|
-
B -->|Yes| C[Process Data]
|
|
561
|
-
B -->|No| D[Return Error]
|
|
562
|
-
C --> E[Save Results]
|
|
563
|
-
D --> F[Log Error]
|
|
564
|
-
E --> G[End]
|
|
565
|
-
F --> G
|
|
566
|
-
\`\`\`
|
|
567
|
-
|
|
568
|
-
## Related Documentation
|
|
569
|
-
|
|
570
|
-
For more information, see our [API reference](/api/overview) and [advanced configuration](./advanced/configuration).
|
|
571
|
-
|
|
572
|
-
This document ends with proper punctuation and formatting.
|
|
573
|
-
`;
|
|
574
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
575
|
-
expect(result.isApproved).toBe(true);
|
|
576
|
-
});
|
|
577
|
-
|
|
578
|
-
test("should approve content with Chinese punctuation", async () => {
|
|
579
|
-
const documentStructure = [];
|
|
580
|
-
const reviewContent = `# 中文文档
|
|
581
|
-
|
|
582
|
-
这是一个中文文档的示例。
|
|
583
|
-
|
|
584
|
-
## 内容说明
|
|
585
|
-
|
|
586
|
-
文档内容使用中文标点符号。
|
|
587
|
-
|
|
588
|
-
这个文档以中文句号结尾。
|
|
589
|
-
`;
|
|
590
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
591
|
-
expect(result.isApproved).toBe(true);
|
|
592
|
-
});
|
|
593
|
-
|
|
594
|
-
test("should reject document with multiple validation issues", async () => {
|
|
595
|
-
const documentStructure = [{ path: "/getting-started" }];
|
|
596
|
-
const reviewContent = `# Complex Test Document
|
|
597
|
-
|
|
598
|
-
This document has [multiple issues](./broken-link).
|
|
599
|
-
|
|
600
|
-
| Column 1 | Column 2 | Column 3 |
|
|
601
|
-
| - | - |
|
|
602
|
-
| Data 1 | Data 2 | Data 3 |
|
|
603
|
-
|
|
604
|
-
\`\`\`mermaid
|
|
605
|
-
flowchart TD
|
|
606
|
-
A["node with \`backticks\`"] --> B[End]
|
|
607
|
-
\`\`\`
|
|
608
|
-
|
|
609
|
-
This content doesn't end properly`;
|
|
610
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
611
|
-
expect(result.isApproved).toBe(false);
|
|
612
|
-
expect(result.detailFeedback).toContain("dead link");
|
|
613
|
-
expect(result.detailFeedback).toContain("separator has 2 columns but header has 3 columns");
|
|
614
|
-
expect(result.detailFeedback).toContain("incomplete content");
|
|
615
|
-
});
|
|
616
|
-
});
|
|
617
|
-
|
|
618
|
-
describe("Complex code block indentation cases", () => {
|
|
619
|
-
test("should reject real-world code block indentation issue", async () => {
|
|
620
|
-
const documentStructure = [];
|
|
621
|
-
const reviewContent = `# API Response Handling
|
|
622
|
-
|
|
623
|
-
You can retrieve the response body in various formats:
|
|
624
|
-
|
|
625
|
-
* **\`response.content\`**: Accesses the raw response body as bytes. This is useful for non-text data like images or binary files.
|
|
626
|
-
\`\`\`python
|
|
627
|
-
import requests
|
|
628
|
-
|
|
629
|
-
r = requests.get('https://httpbin.org/image/png')
|
|
630
|
-
print(type(r.content))
|
|
631
|
-
# Expected output: <class 'bytes'>
|
|
632
|
-
\`\`\`
|
|
633
|
-
|
|
634
|
-
* **\`response.text\`**: Accesses the response body as Unicode text. Requests automatically guesses the encoding, or you can explicitly set \`response.encoding\`.
|
|
635
|
-
\`\`\`python
|
|
636
|
-
import requests
|
|
637
|
-
|
|
638
|
-
r = requests.get('https://httpbin.org/get')
|
|
639
|
-
print(type(r.text))
|
|
640
|
-
# Expected output: <class 'str'>
|
|
641
|
-
print(r.text)
|
|
642
|
-
# Expected output: {"args": {}, "headers": ..., "origin": "...", "url": "https://httpbin.org/get"}
|
|
643
|
-
\`\`\`
|
|
644
|
-
|
|
645
|
-
This document ends properly.
|
|
646
|
-
`;
|
|
647
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
648
|
-
expect(result.isApproved).toBe(false);
|
|
649
|
-
expect(result.detailFeedback).toContain("insufficient indentation");
|
|
650
|
-
});
|
|
651
|
-
});
|
|
652
|
-
|
|
653
|
-
describe("Advanced Mermaid validation cases", () => {
|
|
654
|
-
test("should reject Mermaid with numbered list in node labels", async () => {
|
|
655
|
-
const documentStructure = [];
|
|
656
|
-
const reviewContent = `# Test Document
|
|
657
|
-
|
|
658
|
-
\`\`\`mermaid
|
|
659
|
-
flowchart TD
|
|
660
|
-
A["1. Create Backend Implementation<br>api/src/providers/"]
|
|
661
|
-
B["2. Add Backend Configuration<br>api/src/providers/models.ts"]
|
|
662
|
-
C["3. Update Frontend Selector<br>src/pages/config/ai-providers/"]
|
|
663
|
-
|
|
664
|
-
A --> B --> C
|
|
665
|
-
\`\`\`
|
|
666
|
-
|
|
667
|
-
This content ends properly.
|
|
668
|
-
`;
|
|
669
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
670
|
-
expect(result.isApproved).toBe(false);
|
|
671
|
-
expect(result.detailFeedback).toContain("numbered list format in Mermaid node label");
|
|
672
|
-
});
|
|
673
|
-
|
|
674
|
-
test("should handle complex Mermaid with subgraph issues", async () => {
|
|
675
|
-
const documentStructure = [];
|
|
676
|
-
const reviewContent = `# Test Document
|
|
677
|
-
|
|
678
|
-
\`\`\`mermaid
|
|
679
|
-
flowchart TD
|
|
680
|
-
A["FastAPI Application"] --> B["Security & Authentication"];
|
|
681
|
-
A --> C["Error Handling"];
|
|
682
|
-
H["Project Structure"] -- "Organizes" --> A;
|
|
683
|
-
|
|
684
|
-
subgraph Advanced Capabilities
|
|
685
|
-
B
|
|
686
|
-
C
|
|
687
|
-
end
|
|
688
|
-
|
|
689
|
-
AdvancedCapabilities --> "Robustness" --> L["Production-Ready API"];
|
|
690
|
-
\`\`\`
|
|
691
|
-
|
|
692
|
-
This content ends properly.
|
|
693
|
-
`;
|
|
694
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
695
|
-
// This may pass or fail depending on Mermaid validation - we just ensure it doesn't crash
|
|
696
|
-
expect(typeof result.isApproved).toBe("boolean");
|
|
697
|
-
});
|
|
698
|
-
});
|
|
699
|
-
|
|
700
|
-
describe("Table validation with real content", () => {
|
|
701
|
-
test("should approve table with escaped pipes", async () => {
|
|
702
|
-
const documentStructure = [];
|
|
703
|
-
const reviewContent = `# Test Document
|
|
704
|
-
|
|
705
|
-
| 参数 | 类型 | 描述 |
|
|
706
|
-
|---|---|---|
|
|
707
|
-
| callback | () => void \\| Promise<void> | Payment Kit 组件运行后要执行的函数。这可以是一个异步函数。 |
|
|
708
|
-
| wait | boolean | 可选。如果为,稍后在组件启动时执行回调。 |
|
|
709
|
-
|
|
710
|
-
This document demonstrates escaped pipe handling.
|
|
711
|
-
`;
|
|
712
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
713
|
-
expect(result.isApproved).toBe(true);
|
|
714
|
-
});
|
|
715
|
-
});
|
|
716
|
-
|
|
717
|
-
describe("Error handling", () => {
|
|
718
|
-
test("should handle markdown processing errors gracefully", async () => {
|
|
719
|
-
const documentStructure = [];
|
|
720
|
-
// Test with extremely malformed content that might cause parsing errors
|
|
721
|
-
const reviewContent = null;
|
|
722
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
723
|
-
expect(result.isApproved).toBe(false);
|
|
724
|
-
expect(result.detailFeedback).toBe("Review content is empty");
|
|
725
|
-
});
|
|
726
|
-
|
|
727
|
-
test("should handle empty content gracefully", async () => {
|
|
728
|
-
const documentStructure = [];
|
|
729
|
-
const reviewContent = "";
|
|
730
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
731
|
-
expect(result.isApproved).toBe(false);
|
|
732
|
-
expect(result.detailFeedback).toBe("Review content is empty");
|
|
733
|
-
});
|
|
734
|
-
|
|
735
|
-
test("should handle whitespace-only content", async () => {
|
|
736
|
-
const documentStructure = [];
|
|
737
|
-
const reviewContent = " \n\n \t \n ";
|
|
738
|
-
const result = await checkDetailResult({ documentStructure, reviewContent });
|
|
739
|
-
expect(result.isApproved).toBe(false);
|
|
740
|
-
expect(result.detailFeedback).toBe("Review content is empty");
|
|
741
|
-
});
|
|
742
|
-
});
|
|
743
|
-
});
|