@aigne/doc-smith 0.8.12-beta.7 → 0.8.12-beta.9
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 +25 -0
- package/agents/clear/choose-contents.mjs +14 -1
- package/agents/clear/clear-media-description.mjs +129 -0
- package/agents/clear/index.yaml +3 -1
- package/agents/evaluate/code-snippet.mjs +28 -24
- package/agents/evaluate/document-structure.yaml +0 -4
- package/agents/evaluate/document.yaml +1 -5
- package/agents/generate/index.yaml +1 -0
- package/agents/init/index.mjs +10 -0
- package/agents/media/batch-generate-media-description.yaml +44 -0
- package/agents/media/generate-media-description.yaml +47 -0
- package/agents/media/load-media-description.mjs +238 -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/index.yaml +1 -0
- package/agents/update/update-document-detail.yaml +3 -1
- package/agents/utils/load-sources.mjs +103 -53
- package/agents/utils/update-branding.mjs +69 -0
- package/aigne.yaml +6 -0
- package/assets/report-template/report.html +34 -34
- package/package.json +17 -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/evaluate/document-structure.md +6 -7
- package/prompts/evaluate/document.md +16 -25
- package/prompts/media/media-description/system-prompt.md +35 -0
- package/prompts/media/media-description/user-prompt.md +8 -0
- package/prompts/structure/update/user-prompt.md +0 -4
- package/utils/constants/index.mjs +0 -107
- package/utils/file-utils.mjs +86 -0
- 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/output/structure-plan.json +0 -162
- package/.aigne/doc-smith/preferences.yml +0 -97
- package/.aigne/doc-smith/upload-cache.yaml +0 -1893
- 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 -179
- 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 -96
- package/docs/configuration.md +0 -96
- package/docs/configuration.zh-TW.md +0 -96
- package/docs/configuration.zh.md +0 -96
- package/docs/getting-started.ja.md +0 -88
- package/docs/getting-started.md +0 -88
- package/docs/getting-started.zh-TW.md +0 -88
- package/docs/getting-started.zh.md +0 -88
- package/docs/guides-cleaning-up.ja.md +0 -51
- package/docs/guides-cleaning-up.md +0 -51
- 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 -66
- 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 -151
- 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 -85
- 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 -48
- 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 -78
- 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 -95
- 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 -77
- 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 -255
- package/docs/release-notes.zh-TW.md +0 -255
- package/docs/release-notes.zh.md +0 -255
- package/media.md +0 -19
- 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,541 +0,0 @@
|
|
|
1
|
-
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
|
2
|
-
import { dirname } from "node:path";
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
-
import {
|
|
5
|
-
getValidationStats,
|
|
6
|
-
shutdownValidation,
|
|
7
|
-
validateBasicMermaidSyntax,
|
|
8
|
-
validateMermaidSyntax,
|
|
9
|
-
} from "../../utils/mermaid-validator.mjs";
|
|
10
|
-
import {
|
|
11
|
-
getMermaidWorkerPool,
|
|
12
|
-
SimpleMermaidWorkerPool,
|
|
13
|
-
shutdownMermaidWorkerPool,
|
|
14
|
-
} from "../../utils/mermaid-worker-pool.mjs";
|
|
15
|
-
|
|
16
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
17
|
-
const __dirname = dirname(__filename);
|
|
18
|
-
|
|
19
|
-
describe.skip("Mermaid Worker Pool", () => {
|
|
20
|
-
let workerPool;
|
|
21
|
-
|
|
22
|
-
beforeAll(() => {
|
|
23
|
-
// Ensure clean state
|
|
24
|
-
workerPool = new SimpleMermaidWorkerPool({ poolSize: 2, timeout: 5000 });
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
afterAll(async () => {
|
|
28
|
-
if (workerPool) {
|
|
29
|
-
await workerPool.shutdown();
|
|
30
|
-
}
|
|
31
|
-
await shutdownMermaidWorkerPool();
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
describe("SimpleMermaidWorkerPool", () => {
|
|
35
|
-
test("should initialize with default options", () => {
|
|
36
|
-
const pool = new SimpleMermaidWorkerPool();
|
|
37
|
-
expect(pool.poolSize).toBe(3);
|
|
38
|
-
expect(pool.timeout).toBe(15000);
|
|
39
|
-
expect(pool.workers).toEqual([]);
|
|
40
|
-
expect(pool.availableWorkers).toEqual([]);
|
|
41
|
-
expect(pool.requestQueue).toEqual([]);
|
|
42
|
-
expect(pool.isShuttingDown).toBe(false);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
test("should initialize with custom options", () => {
|
|
46
|
-
const pool = new SimpleMermaidWorkerPool({ poolSize: 5, timeout: 10000 });
|
|
47
|
-
expect(pool.poolSize).toBe(5);
|
|
48
|
-
expect(pool.timeout).toBe(10000);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
test("should initialize workers", async () => {
|
|
52
|
-
const pool = new SimpleMermaidWorkerPool({ poolSize: 2, timeout: 5000 });
|
|
53
|
-
|
|
54
|
-
await pool.initialize();
|
|
55
|
-
|
|
56
|
-
expect(pool.workers.length).toBe(2);
|
|
57
|
-
expect(pool.availableWorkers.length).toBe(2);
|
|
58
|
-
|
|
59
|
-
await pool.shutdown();
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
test("should not reinitialize if already initialized", async () => {
|
|
63
|
-
const pool = new SimpleMermaidWorkerPool({ poolSize: 2, timeout: 5000 });
|
|
64
|
-
|
|
65
|
-
await pool.initialize();
|
|
66
|
-
const initialWorkers = pool.workers.length;
|
|
67
|
-
|
|
68
|
-
await pool.initialize();
|
|
69
|
-
expect(pool.workers.length).toBe(initialWorkers);
|
|
70
|
-
|
|
71
|
-
await pool.shutdown();
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
test("should validate valid mermaid content", async () => {
|
|
75
|
-
const pool = new SimpleMermaidWorkerPool({ poolSize: 1, timeout: 10000 });
|
|
76
|
-
|
|
77
|
-
const validContent = `
|
|
78
|
-
flowchart TD
|
|
79
|
-
A[Start] --> B[Process]
|
|
80
|
-
B --> C[End]
|
|
81
|
-
`;
|
|
82
|
-
|
|
83
|
-
const result = await pool.validate(validContent);
|
|
84
|
-
expect(result).toBe(true);
|
|
85
|
-
|
|
86
|
-
await pool.shutdown();
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
test("should reject invalid mermaid content", async () => {
|
|
90
|
-
const pool = new SimpleMermaidWorkerPool({ poolSize: 1, timeout: 10000 });
|
|
91
|
-
|
|
92
|
-
const invalidContent = `
|
|
93
|
-
flowchart TD
|
|
94
|
-
A[Start] --> B[Process
|
|
95
|
-
B --> C[End]
|
|
96
|
-
`;
|
|
97
|
-
|
|
98
|
-
await expect(pool.validate(invalidContent)).rejects.toThrow();
|
|
99
|
-
|
|
100
|
-
await pool.shutdown();
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
test("should handle concurrent validation requests", async () => {
|
|
104
|
-
const pool = new SimpleMermaidWorkerPool({ poolSize: 2, timeout: 10000 });
|
|
105
|
-
|
|
106
|
-
const validContent1 = `
|
|
107
|
-
flowchart TD
|
|
108
|
-
A[Start] --> B[Process]
|
|
109
|
-
`;
|
|
110
|
-
|
|
111
|
-
const validContent2 = `
|
|
112
|
-
graph LR
|
|
113
|
-
X --> Y --> Z
|
|
114
|
-
`;
|
|
115
|
-
|
|
116
|
-
const validContent3 = `
|
|
117
|
-
sequenceDiagram
|
|
118
|
-
Alice->>Bob: Hello
|
|
119
|
-
`;
|
|
120
|
-
|
|
121
|
-
const promises = [
|
|
122
|
-
pool.validate(validContent1),
|
|
123
|
-
pool.validate(validContent2),
|
|
124
|
-
pool.validate(validContent3),
|
|
125
|
-
];
|
|
126
|
-
|
|
127
|
-
const results = await Promise.all(promises);
|
|
128
|
-
expect(results).toEqual([true, true, true]);
|
|
129
|
-
|
|
130
|
-
await pool.shutdown();
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
test("should handle validation timeout", async () => {
|
|
134
|
-
const pool = new SimpleMermaidWorkerPool({ poolSize: 1, timeout: 100 });
|
|
135
|
-
|
|
136
|
-
// Create content that might cause processing delay
|
|
137
|
-
const complexContent = `
|
|
138
|
-
flowchart TD
|
|
139
|
-
${"A --> B\n".repeat(1000)}
|
|
140
|
-
`;
|
|
141
|
-
|
|
142
|
-
await expect(pool.validate(complexContent)).rejects.toThrow(/timeout/);
|
|
143
|
-
|
|
144
|
-
await pool.shutdown();
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
test("should queue requests when all workers are busy", async () => {
|
|
148
|
-
const pool = new SimpleMermaidWorkerPool({ poolSize: 1, timeout: 5000 });
|
|
149
|
-
|
|
150
|
-
const validContent = `
|
|
151
|
-
flowchart TD
|
|
152
|
-
A --> B
|
|
153
|
-
`;
|
|
154
|
-
|
|
155
|
-
// Start multiple validations simultaneously
|
|
156
|
-
const promise1 = pool.validate(validContent);
|
|
157
|
-
const promise2 = pool.validate(validContent);
|
|
158
|
-
const promise3 = pool.validate(validContent);
|
|
159
|
-
|
|
160
|
-
const results = await Promise.all([promise1, promise2, promise3]);
|
|
161
|
-
expect(results).toEqual([true, true, true]);
|
|
162
|
-
|
|
163
|
-
await pool.shutdown();
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
test("should reject requests when shutting down", async () => {
|
|
167
|
-
const pool = new SimpleMermaidWorkerPool({ poolSize: 1, timeout: 5000 });
|
|
168
|
-
|
|
169
|
-
await pool.initialize();
|
|
170
|
-
await pool.shutdown();
|
|
171
|
-
|
|
172
|
-
await expect(pool.validate("flowchart TD\nA --> B")).rejects.toThrow(
|
|
173
|
-
"Worker pool is shutting down",
|
|
174
|
-
);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
test("should provide accurate statistics", async () => {
|
|
178
|
-
const pool = new SimpleMermaidWorkerPool({ poolSize: 3, timeout: 5000 });
|
|
179
|
-
await pool.initialize();
|
|
180
|
-
|
|
181
|
-
const stats = pool.getStats();
|
|
182
|
-
expect(stats.poolSize).toBe(3);
|
|
183
|
-
expect(stats.totalWorkers).toBe(3);
|
|
184
|
-
expect(stats.availableWorkers).toBe(3);
|
|
185
|
-
expect(stats.busyWorkers).toBe(0);
|
|
186
|
-
expect(stats.queuedRequests).toBe(0);
|
|
187
|
-
expect(stats.isShuttingDown).toBe(false);
|
|
188
|
-
|
|
189
|
-
await pool.shutdown();
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
test("should handle worker errors gracefully", async () => {
|
|
193
|
-
const pool = new SimpleMermaidWorkerPool({ poolSize: 1, timeout: 5000 });
|
|
194
|
-
|
|
195
|
-
// Try to validate empty content which should cause an error
|
|
196
|
-
await expect(pool.validate("")).rejects.toThrow();
|
|
197
|
-
|
|
198
|
-
// Pool should still be functional after error
|
|
199
|
-
const validContent = "flowchart TD\nA --> B";
|
|
200
|
-
const result = await pool.validate(validContent);
|
|
201
|
-
expect(result).toBe(true);
|
|
202
|
-
|
|
203
|
-
await pool.shutdown();
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
test("should shutdown gracefully", async () => {
|
|
207
|
-
const pool = new SimpleMermaidWorkerPool({ poolSize: 2, timeout: 5000 });
|
|
208
|
-
await pool.initialize();
|
|
209
|
-
|
|
210
|
-
expect(pool.workers.length).toBe(2);
|
|
211
|
-
expect(pool.isShuttingDown).toBe(false);
|
|
212
|
-
|
|
213
|
-
await pool.shutdown();
|
|
214
|
-
|
|
215
|
-
expect(pool.workers.length).toBe(0);
|
|
216
|
-
expect(pool.availableWorkers.length).toBe(0);
|
|
217
|
-
expect(pool.isShuttingDown).toBe(true);
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
test("should reject queued requests during shutdown", async () => {
|
|
221
|
-
const pool = new SimpleMermaidWorkerPool({ poolSize: 1, timeout: 5000 });
|
|
222
|
-
await pool.initialize();
|
|
223
|
-
|
|
224
|
-
// Add requests to queue
|
|
225
|
-
const validContent = "flowchart TD\nA --> B";
|
|
226
|
-
const promise1 = pool.validate(validContent);
|
|
227
|
-
const promise2 = pool.validate(validContent);
|
|
228
|
-
|
|
229
|
-
// Start shutdown while requests are queued
|
|
230
|
-
setTimeout(() => pool.shutdown(), 10);
|
|
231
|
-
|
|
232
|
-
// At least one request should be rejected due to shutdown
|
|
233
|
-
const results = await Promise.allSettled([promise1, promise2]);
|
|
234
|
-
const rejectedCount = results.filter((r) => r.status === "rejected").length;
|
|
235
|
-
expect(rejectedCount).toBeGreaterThan(0);
|
|
236
|
-
});
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
describe("Global Worker Pool Functions", () => {
|
|
240
|
-
afterAll(async () => {
|
|
241
|
-
await shutdownMermaidWorkerPool();
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
test("should get global worker pool instance", () => {
|
|
245
|
-
const pool1 = getMermaidWorkerPool();
|
|
246
|
-
const pool2 = getMermaidWorkerPool();
|
|
247
|
-
expect(pool1).toBe(pool2); // Should return same instance
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
test("should get global worker pool with options", () => {
|
|
251
|
-
// Note: Global pool ignores options if already created
|
|
252
|
-
// This test verifies that the function returns a pool instance
|
|
253
|
-
const pool = getMermaidWorkerPool({ poolSize: 4, timeout: 8000 });
|
|
254
|
-
expect(pool).toBeInstanceOf(SimpleMermaidWorkerPool);
|
|
255
|
-
expect(typeof pool.poolSize).toBe("number");
|
|
256
|
-
expect(typeof pool.timeout).toBe("number");
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
test("should shutdown global worker pool", async () => {
|
|
260
|
-
const pool = getMermaidWorkerPool();
|
|
261
|
-
await pool.initialize();
|
|
262
|
-
expect(pool.workers.length).toBeGreaterThan(0);
|
|
263
|
-
|
|
264
|
-
await shutdownMermaidWorkerPool();
|
|
265
|
-
expect(pool.workers.length).toBe(0);
|
|
266
|
-
});
|
|
267
|
-
});
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
describe.skip("Mermaid Validator", () => {
|
|
271
|
-
afterAll(async () => {
|
|
272
|
-
await shutdownValidation();
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
describe("validateBasicMermaidSyntax", () => {
|
|
276
|
-
test("should validate basic flowchart syntax", () => {
|
|
277
|
-
const content = "flowchart TD\nA --> B";
|
|
278
|
-
expect(validateBasicMermaidSyntax(content)).toBe(true);
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
test("should validate graph syntax", () => {
|
|
282
|
-
const content = "graph LR\nA --> B";
|
|
283
|
-
expect(validateBasicMermaidSyntax(content)).toBe(true);
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
test("should validate sequence diagram syntax", () => {
|
|
287
|
-
const content = "sequenceDiagram\nAlice->>Bob: Hello";
|
|
288
|
-
expect(validateBasicMermaidSyntax(content)).toBe(true);
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
test("should validate class diagram syntax", () => {
|
|
292
|
-
const content = "classDiagram\nclass Animal";
|
|
293
|
-
expect(validateBasicMermaidSyntax(content)).toBe(true);
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
test("should validate state diagram syntax", () => {
|
|
297
|
-
const content = "stateDiagram\n[*] --> Still";
|
|
298
|
-
expect(validateBasicMermaidSyntax(content)).toBe(true);
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
test("should validate ER diagram syntax", () => {
|
|
302
|
-
const content = "erDiagram\nCUSTOMER {}";
|
|
303
|
-
expect(validateBasicMermaidSyntax(content)).toBe(true);
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
test("should validate journey diagram syntax", () => {
|
|
307
|
-
const content = "journey\ntitle My working day";
|
|
308
|
-
expect(validateBasicMermaidSyntax(content)).toBe(true);
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
test("should validate gantt chart syntax", () => {
|
|
312
|
-
const content = "gantt\ntitle A Gantt Diagram";
|
|
313
|
-
expect(validateBasicMermaidSyntax(content)).toBe(true);
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
test("should validate pie chart syntax", () => {
|
|
317
|
-
const content = "pie title Pets adopted by volunteers";
|
|
318
|
-
expect(validateBasicMermaidSyntax(content)).toBe(true);
|
|
319
|
-
});
|
|
320
|
-
|
|
321
|
-
test("should reject empty content", () => {
|
|
322
|
-
expect(() => validateBasicMermaidSyntax("")).toThrow("Empty mermaid diagram");
|
|
323
|
-
expect(() => validateBasicMermaidSyntax(" ")).toThrow("Empty mermaid diagram");
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
test("should reject invalid diagram type", () => {
|
|
327
|
-
expect(() => validateBasicMermaidSyntax("invalid\nA --> B")).toThrow(
|
|
328
|
-
"Invalid or missing diagram type",
|
|
329
|
-
);
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
test("should detect unmatched brackets", () => {
|
|
333
|
-
expect(() => validateBasicMermaidSyntax("flowchart TD\nA[Start --> B[End]")).toThrow(
|
|
334
|
-
"Unmatched brackets in diagram",
|
|
335
|
-
);
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
test("should detect unmatched single quotes", () => {
|
|
339
|
-
// Test with properly matched brackets but unmatched quotes
|
|
340
|
-
expect(() =>
|
|
341
|
-
validateBasicMermaidSyntax("flowchart TD\nA --> B\nNote: 'Unmatched quote"),
|
|
342
|
-
).toThrow("Unmatched single quotes in diagram");
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
test("should detect unmatched double quotes", () => {
|
|
346
|
-
// Test with properly matched brackets but unmatched quotes
|
|
347
|
-
expect(() =>
|
|
348
|
-
validateBasicMermaidSyntax('flowchart TD\nA --> B\nNote: "Unmatched quote'),
|
|
349
|
-
).toThrow("Unmatched double quotes in diagram");
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
test("should allow matched quotes", () => {
|
|
353
|
-
const content = "flowchart TD\nA[\"Start\"] --> B['End']";
|
|
354
|
-
expect(validateBasicMermaidSyntax(content)).toBe(true);
|
|
355
|
-
});
|
|
356
|
-
|
|
357
|
-
test("should allow complex bracket combinations", () => {
|
|
358
|
-
const content = "flowchart TD\nA[Start] --> B{Decision} --> C((Circle))";
|
|
359
|
-
expect(validateBasicMermaidSyntax(content)).toBe(true);
|
|
360
|
-
});
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
describe("validateMermaidSyntax", () => {
|
|
364
|
-
test("should validate simple flowchart", async () => {
|
|
365
|
-
const content = "flowchart TD\nA[Start] --> B[End]";
|
|
366
|
-
const result = await validateMermaidSyntax(content);
|
|
367
|
-
expect(result).toBe(true);
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
test("should validate complex flowchart", async () => {
|
|
371
|
-
const content = `
|
|
372
|
-
flowchart TD
|
|
373
|
-
A[Start] --> B{Is it working?}
|
|
374
|
-
B -->|Yes| C[Great!]
|
|
375
|
-
B -->|No| D[Fix it]
|
|
376
|
-
D --> B
|
|
377
|
-
C --> E[End]
|
|
378
|
-
`;
|
|
379
|
-
const result = await validateMermaidSyntax(content);
|
|
380
|
-
expect(result).toBe(true);
|
|
381
|
-
});
|
|
382
|
-
|
|
383
|
-
test("should validate sequence diagram", async () => {
|
|
384
|
-
const content = `
|
|
385
|
-
sequenceDiagram
|
|
386
|
-
participant Alice
|
|
387
|
-
participant Bob
|
|
388
|
-
Alice->>Bob: Hello Bob, how are you?
|
|
389
|
-
Bob-->>Alice: Great!
|
|
390
|
-
`;
|
|
391
|
-
const result = await validateMermaidSyntax(content);
|
|
392
|
-
expect(result).toBe(true);
|
|
393
|
-
});
|
|
394
|
-
|
|
395
|
-
test("should reject invalid syntax", async () => {
|
|
396
|
-
const content = "flowchart TD\nA[Start --> B[End"; // Missing closing bracket
|
|
397
|
-
await expect(validateMermaidSyntax(content)).rejects.toThrow();
|
|
398
|
-
});
|
|
399
|
-
|
|
400
|
-
test("should reject empty content", async () => {
|
|
401
|
-
await expect(validateMermaidSyntax("")).rejects.toThrow("Empty mermaid diagram");
|
|
402
|
-
await expect(validateMermaidSyntax(" ")).rejects.toThrow("Empty mermaid diagram");
|
|
403
|
-
});
|
|
404
|
-
|
|
405
|
-
test("should handle worker pool fallback gracefully", async () => {
|
|
406
|
-
// This test checks that the function can fall back to basic validation
|
|
407
|
-
// if worker validation fails due to environment issues
|
|
408
|
-
const content = "flowchart TD\nA --> B";
|
|
409
|
-
const result = await validateMermaidSyntax(content);
|
|
410
|
-
expect(result).toBe(true);
|
|
411
|
-
});
|
|
412
|
-
|
|
413
|
-
test("should validate different diagram types", async () => {
|
|
414
|
-
const testCases = [
|
|
415
|
-
"graph LR\nA --> B",
|
|
416
|
-
"sequenceDiagram\nAlice->>Bob: Hello",
|
|
417
|
-
"classDiagram\nclass Animal",
|
|
418
|
-
"stateDiagram\n[*] --> Still",
|
|
419
|
-
"erDiagram\nCUSTOMER {}",
|
|
420
|
-
"journey\ntitle My day",
|
|
421
|
-
"gantt\ntitle Project",
|
|
422
|
-
"pie title Data",
|
|
423
|
-
];
|
|
424
|
-
|
|
425
|
-
for (const content of testCases) {
|
|
426
|
-
const result = await validateMermaidSyntax(content);
|
|
427
|
-
expect(result).toBe(true);
|
|
428
|
-
}
|
|
429
|
-
});
|
|
430
|
-
});
|
|
431
|
-
|
|
432
|
-
describe("Utility Functions", () => {
|
|
433
|
-
test("should get validation statistics", () => {
|
|
434
|
-
const stats = getValidationStats();
|
|
435
|
-
expect(typeof stats).toBe("object");
|
|
436
|
-
|
|
437
|
-
if (stats.error) {
|
|
438
|
-
expect(typeof stats.error).toBe("string");
|
|
439
|
-
} else {
|
|
440
|
-
expect(typeof stats.poolSize).toBe("number");
|
|
441
|
-
expect(typeof stats.totalWorkers).toBe("number");
|
|
442
|
-
expect(typeof stats.availableWorkers).toBe("number");
|
|
443
|
-
expect(typeof stats.busyWorkers).toBe("number");
|
|
444
|
-
expect(typeof stats.queuedRequests).toBe("number");
|
|
445
|
-
expect(typeof stats.isShuttingDown).toBe("boolean");
|
|
446
|
-
}
|
|
447
|
-
});
|
|
448
|
-
|
|
449
|
-
test("should shutdown validation properly", async () => {
|
|
450
|
-
// Should not throw
|
|
451
|
-
await expect(shutdownValidation()).resolves.toBeUndefined();
|
|
452
|
-
});
|
|
453
|
-
});
|
|
454
|
-
|
|
455
|
-
describe("Error Handling and Edge Cases", () => {
|
|
456
|
-
test("should handle very large diagrams", async () => {
|
|
457
|
-
const largeContent = `
|
|
458
|
-
flowchart TD
|
|
459
|
-
${Array.from({ length: 50 }, (_, i) => `A${i} --> A${i + 1}`).join("\n ")}
|
|
460
|
-
`;
|
|
461
|
-
|
|
462
|
-
// Should either succeed or fail with a clear error
|
|
463
|
-
try {
|
|
464
|
-
const result = await validateMermaidSyntax(largeContent);
|
|
465
|
-
expect(result).toBe(true);
|
|
466
|
-
} catch (error) {
|
|
467
|
-
expect(error.message).toBeTruthy();
|
|
468
|
-
}
|
|
469
|
-
});
|
|
470
|
-
|
|
471
|
-
test("should handle special characters in content", async () => {
|
|
472
|
-
const content = `
|
|
473
|
-
flowchart TD
|
|
474
|
-
A["Node with special chars: @#$%"] --> B["Another node: &*()"]
|
|
475
|
-
`;
|
|
476
|
-
|
|
477
|
-
const result = await validateMermaidSyntax(content);
|
|
478
|
-
expect(result).toBe(true);
|
|
479
|
-
});
|
|
480
|
-
|
|
481
|
-
test("should handle unicode characters", async () => {
|
|
482
|
-
const content = `
|
|
483
|
-
flowchart TD
|
|
484
|
-
A["开始"] --> B["处理"]
|
|
485
|
-
B --> C["结束"]
|
|
486
|
-
`;
|
|
487
|
-
|
|
488
|
-
const result = await validateMermaidSyntax(content);
|
|
489
|
-
expect(result).toBe(true);
|
|
490
|
-
});
|
|
491
|
-
|
|
492
|
-
test("should handle multiline node labels", async () => {
|
|
493
|
-
const content = `
|
|
494
|
-
flowchart TD
|
|
495
|
-
A["Multi<br/>Line<br/>Label"] --> B["Another<br/>Multi<br/>Line"]
|
|
496
|
-
`;
|
|
497
|
-
|
|
498
|
-
const result = await validateMermaidSyntax(content);
|
|
499
|
-
expect(result).toBe(true);
|
|
500
|
-
});
|
|
501
|
-
|
|
502
|
-
test("should handle comments in diagrams", async () => {
|
|
503
|
-
const content = `
|
|
504
|
-
flowchart TD
|
|
505
|
-
%% This is a comment
|
|
506
|
-
A[Start] --> B[End]
|
|
507
|
-
%% Another comment
|
|
508
|
-
`;
|
|
509
|
-
|
|
510
|
-
const result = await validateMermaidSyntax(content);
|
|
511
|
-
expect(result).toBe(true);
|
|
512
|
-
});
|
|
513
|
-
});
|
|
514
|
-
|
|
515
|
-
describe("Concurrency and Performance", () => {
|
|
516
|
-
test("should handle multiple concurrent validations", async () => {
|
|
517
|
-
const validations = Array.from({ length: 10 }, (_, i) =>
|
|
518
|
-
validateMermaidSyntax(`flowchart TD\nA${i} --> B${i}`),
|
|
519
|
-
);
|
|
520
|
-
|
|
521
|
-
const results = await Promise.all(validations);
|
|
522
|
-
expect(results.every((r) => r === true)).toBe(true);
|
|
523
|
-
});
|
|
524
|
-
|
|
525
|
-
test("should handle mixed valid and invalid validations", async () => {
|
|
526
|
-
const validations = [
|
|
527
|
-
validateMermaidSyntax("flowchart TD\nA --> B"),
|
|
528
|
-
validateMermaidSyntax("invalid content"),
|
|
529
|
-
validateMermaidSyntax("graph LR\nX --> Y"),
|
|
530
|
-
validateMermaidSyntax("another invalid"),
|
|
531
|
-
];
|
|
532
|
-
|
|
533
|
-
const results = await Promise.allSettled(validations);
|
|
534
|
-
|
|
535
|
-
expect(results[0].status).toBe("fulfilled");
|
|
536
|
-
expect(results[1].status).toBe("rejected");
|
|
537
|
-
expect(results[2].status).toBe("fulfilled");
|
|
538
|
-
expect(results[3].status).toBe("rejected");
|
|
539
|
-
});
|
|
540
|
-
});
|
|
541
|
-
});
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// Mock ChatModel for testing
|
|
2
|
-
export class MockChatModel {
|
|
3
|
-
constructor(options = {}) {
|
|
4
|
-
this.options = options;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
process() {
|
|
8
|
-
throw new Error("Method not implemented in test mock");
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const loadModel = () => new MockChatModel();
|