@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,109 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
2
|
-
import { mkdir, readdir, rm, writeFile } from "node:fs/promises";
|
|
3
|
-
import { dirname, join } from "node:path";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
-
import saveDocs from "../../../agents/utils/save-docs.mjs";
|
|
6
|
-
|
|
7
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
-
|
|
9
|
-
describe("save-docs", () => {
|
|
10
|
-
let testDir;
|
|
11
|
-
|
|
12
|
-
beforeEach(async () => {
|
|
13
|
-
// Set test environment variable to prevent actual config file modification
|
|
14
|
-
process.env.NODE_ENV = "test";
|
|
15
|
-
|
|
16
|
-
// Create a temporary test directory
|
|
17
|
-
testDir = join(__dirname, "test-docs");
|
|
18
|
-
await mkdir(testDir, { recursive: true });
|
|
19
|
-
|
|
20
|
-
// Create some test files
|
|
21
|
-
const testFiles = [
|
|
22
|
-
"overview.md",
|
|
23
|
-
"getting-started.md",
|
|
24
|
-
"getting-started.zh.md",
|
|
25
|
-
"getting-started.en.md",
|
|
26
|
-
"old-file.md", // This should be deleted
|
|
27
|
-
"another-old-file.md", // This should be deleted
|
|
28
|
-
"old-translation.zh.md", // This should be deleted
|
|
29
|
-
"_sidebar.md", // This should be preserved
|
|
30
|
-
];
|
|
31
|
-
|
|
32
|
-
for (const file of testFiles) {
|
|
33
|
-
await writeFile(join(testDir, file), `# Test content for ${file}`);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
afterEach(async () => {
|
|
38
|
-
// Clean up environment variable
|
|
39
|
-
delete process.env.NODE_ENV;
|
|
40
|
-
|
|
41
|
-
// Clean up test directory
|
|
42
|
-
try {
|
|
43
|
-
await rm(testDir, { recursive: true, force: true });
|
|
44
|
-
} catch {
|
|
45
|
-
// Ignore cleanup errors since they don't affect test results
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
test("should clean up invalid files and maintain valid ones", async () => {
|
|
50
|
-
const initialFiles = await readdir(testDir);
|
|
51
|
-
expect(initialFiles).toContain("overview.md");
|
|
52
|
-
expect(initialFiles).toContain("getting-started.md");
|
|
53
|
-
expect(initialFiles).toContain("old-file.md");
|
|
54
|
-
|
|
55
|
-
// Test documentation structure
|
|
56
|
-
const documentStructure = [
|
|
57
|
-
{
|
|
58
|
-
path: "/overview",
|
|
59
|
-
title: "Overview",
|
|
60
|
-
description: "Overview page",
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
path: "/getting-started",
|
|
64
|
-
title: "Getting Started",
|
|
65
|
-
description: "Getting started guide",
|
|
66
|
-
},
|
|
67
|
-
];
|
|
68
|
-
|
|
69
|
-
// Test with translation languages
|
|
70
|
-
const translateLanguages = ["zh", "en"];
|
|
71
|
-
|
|
72
|
-
const result = await saveDocs({
|
|
73
|
-
documentExecutionStructure: documentStructure,
|
|
74
|
-
docsDir: testDir,
|
|
75
|
-
translateLanguages,
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
expect(result).toBeDefined();
|
|
79
|
-
|
|
80
|
-
const remainingFiles = await readdir(testDir);
|
|
81
|
-
|
|
82
|
-
// Expected files after cleanup:
|
|
83
|
-
// - overview.md (existing)
|
|
84
|
-
// - getting-started.md (existing)
|
|
85
|
-
// - getting-started.zh.md (existing)
|
|
86
|
-
// - _sidebar.md (generated)
|
|
87
|
-
// Note: getting-started.en.md may be cleaned up if not needed
|
|
88
|
-
// Note: overview.zh.md and overview.en.md are not created by saveDocs,
|
|
89
|
-
// they would be created by saveDocWithTranslations when content is generated
|
|
90
|
-
const expectedFiles = [
|
|
91
|
-
"overview.md",
|
|
92
|
-
"getting-started.md",
|
|
93
|
-
"getting-started.zh.md",
|
|
94
|
-
"_sidebar.md",
|
|
95
|
-
];
|
|
96
|
-
|
|
97
|
-
const missingFiles = expectedFiles.filter((file) => !remainingFiles.includes(file));
|
|
98
|
-
const extraFiles = remainingFiles.filter((file) => !expectedFiles.includes(file));
|
|
99
|
-
|
|
100
|
-
expect(missingFiles).toHaveLength(0);
|
|
101
|
-
expect(extraFiles).toHaveLength(0);
|
|
102
|
-
|
|
103
|
-
// Verify that invalid files were deleted
|
|
104
|
-
const deletedFiles = ["old-file.md", "another-old-file.md", "old-translation.zh.md"];
|
|
105
|
-
const stillExist = deletedFiles.filter((file) => remainingFiles.includes(file));
|
|
106
|
-
|
|
107
|
-
expect(stillExist).toHaveLength(0);
|
|
108
|
-
});
|
|
109
|
-
});
|
|
@@ -1,315 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test";
|
|
2
|
-
import fs from "node:fs";
|
|
3
|
-
import * as path from "node:path";
|
|
4
|
-
import saveOutput from "../../../agents/utils/save-output.mjs";
|
|
5
|
-
|
|
6
|
-
describe("saveOutput utility", () => {
|
|
7
|
-
let mkdirSpy;
|
|
8
|
-
let writeFileSpy;
|
|
9
|
-
let joinSpy;
|
|
10
|
-
let consoleWarnSpy;
|
|
11
|
-
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
// Spy on fs.promises methods
|
|
14
|
-
mkdirSpy = spyOn(fs.promises, "mkdir").mockResolvedValue();
|
|
15
|
-
writeFileSpy = spyOn(fs.promises, "writeFile").mockResolvedValue();
|
|
16
|
-
|
|
17
|
-
// Spy on path methods
|
|
18
|
-
joinSpy = spyOn(path, "join").mockImplementation((...paths) => paths.join("/"));
|
|
19
|
-
|
|
20
|
-
// Spy on console.warn
|
|
21
|
-
consoleWarnSpy = spyOn(console, "warn").mockImplementation(() => {});
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
afterEach(() => {
|
|
25
|
-
// Restore all spies
|
|
26
|
-
mkdirSpy?.mockRestore();
|
|
27
|
-
writeFileSpy?.mockRestore();
|
|
28
|
-
joinSpy?.mockRestore();
|
|
29
|
-
consoleWarnSpy?.mockRestore();
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
// SUCCESSFUL SAVE TESTS
|
|
33
|
-
test("should save string content successfully", async () => {
|
|
34
|
-
const result = await saveOutput({
|
|
35
|
-
savePath: "/output/dir",
|
|
36
|
-
fileName: "result.txt",
|
|
37
|
-
saveKey: "textContent",
|
|
38
|
-
textContent: "Hello, World!",
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
expect(mkdirSpy).toHaveBeenCalledWith("/output/dir", { recursive: true });
|
|
42
|
-
expect(joinSpy).toHaveBeenCalledWith("/output/dir", "result.txt");
|
|
43
|
-
expect(writeFileSpy).toHaveBeenCalledWith("/output/dir/result.txt", "Hello, World!", "utf8");
|
|
44
|
-
expect(result).toEqual({
|
|
45
|
-
saveOutputStatus: true,
|
|
46
|
-
saveOutputPath: "/output/dir/result.txt",
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test("should save object content as formatted JSON", async () => {
|
|
51
|
-
const objectData = {
|
|
52
|
-
title: "Test Document",
|
|
53
|
-
tags: ["test", "sample"],
|
|
54
|
-
metadata: { version: 1 },
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
const result = await saveOutput({
|
|
58
|
-
savePath: "/data",
|
|
59
|
-
fileName: "config.json",
|
|
60
|
-
saveKey: "configData",
|
|
61
|
-
configData: objectData,
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
const expectedContent = JSON.stringify(objectData, null, 2);
|
|
65
|
-
expect(writeFileSpy).toHaveBeenCalledWith("/data/config.json", expectedContent, "utf8");
|
|
66
|
-
expect(result.saveOutputStatus).toBe(true);
|
|
67
|
-
expect(result.saveOutputPath).toBe("/data/config.json");
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
test("should save number content as string", async () => {
|
|
71
|
-
const result = await saveOutput({
|
|
72
|
-
savePath: "/numbers",
|
|
73
|
-
fileName: "count.txt",
|
|
74
|
-
saveKey: "count",
|
|
75
|
-
count: 42,
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
expect(writeFileSpy).toHaveBeenCalledWith("/numbers/count.txt", "42", "utf8");
|
|
79
|
-
expect(result.saveOutputStatus).toBe(true);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
test("should save boolean content as string", async () => {
|
|
83
|
-
const result = await saveOutput({
|
|
84
|
-
savePath: "/flags",
|
|
85
|
-
fileName: "flag.txt",
|
|
86
|
-
saveKey: "isEnabled",
|
|
87
|
-
isEnabled: true,
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
expect(writeFileSpy).toHaveBeenCalledWith("/flags/flag.txt", "true", "utf8");
|
|
91
|
-
expect(result.saveOutputStatus).toBe(true);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
test("should save array content as formatted JSON", async () => {
|
|
95
|
-
const arrayData = ["item1", "item2", { nested: "object" }];
|
|
96
|
-
|
|
97
|
-
const result = await saveOutput({
|
|
98
|
-
savePath: "/arrays",
|
|
99
|
-
fileName: "list.json",
|
|
100
|
-
saveKey: "items",
|
|
101
|
-
items: arrayData,
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
const expectedContent = JSON.stringify(arrayData, null, 2);
|
|
105
|
-
expect(writeFileSpy).toHaveBeenCalledWith("/arrays/list.json", expectedContent, "utf8");
|
|
106
|
-
expect(result.saveOutputStatus).toBe(true);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
// NULL AND UNDEFINED HANDLING
|
|
110
|
-
test("should handle null values by converting to JSON string", async () => {
|
|
111
|
-
const result = await saveOutput({
|
|
112
|
-
savePath: "/null-test",
|
|
113
|
-
fileName: "null.json",
|
|
114
|
-
saveKey: "nullValue",
|
|
115
|
-
nullValue: null,
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
expect(writeFileSpy).toHaveBeenCalledWith("/null-test/null.json", "null", "utf8");
|
|
119
|
-
expect(result.saveOutputStatus).toBe(true);
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
test("should handle undefined values by converting to string", async () => {
|
|
123
|
-
const result = await saveOutput({
|
|
124
|
-
savePath: "/undefined-test",
|
|
125
|
-
fileName: "undefined.txt",
|
|
126
|
-
saveKey: "undefinedValue",
|
|
127
|
-
undefinedValue: undefined,
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
expect(writeFileSpy).toHaveBeenCalledWith("/undefined-test/undefined.txt", "undefined", "utf8");
|
|
131
|
-
expect(result.saveOutputStatus).toBe(true);
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
// MISSING SAVE KEY TESTS
|
|
135
|
-
test("should warn and return false when saveKey is not found", async () => {
|
|
136
|
-
const result = await saveOutput({
|
|
137
|
-
savePath: "/output",
|
|
138
|
-
fileName: "missing.txt",
|
|
139
|
-
saveKey: "nonExistentKey",
|
|
140
|
-
existingKey: "some value",
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
144
|
-
'saveKey "nonExistentKey" not found in input, skip saving.',
|
|
145
|
-
);
|
|
146
|
-
expect(result).toEqual({
|
|
147
|
-
saveOutputStatus: false,
|
|
148
|
-
saveOutputPath: null,
|
|
149
|
-
});
|
|
150
|
-
expect(mkdirSpy).not.toHaveBeenCalled();
|
|
151
|
-
expect(writeFileSpy).not.toHaveBeenCalled();
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
test("should not save when saveKey exists but is undefined", async () => {
|
|
155
|
-
const result = await saveOutput({
|
|
156
|
-
savePath: "/output",
|
|
157
|
-
fileName: "test.txt",
|
|
158
|
-
saveKey: "undefinedKey",
|
|
159
|
-
// undefinedKey is not provided, so it will be undefined
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
163
|
-
'saveKey "undefinedKey" not found in input, skip saving.',
|
|
164
|
-
);
|
|
165
|
-
expect(result.saveOutputStatus).toBe(false);
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
// COMPLEX PATH HANDLING
|
|
169
|
-
test("should handle nested directory paths", async () => {
|
|
170
|
-
await saveOutput({
|
|
171
|
-
savePath: "/deep/nested/directory/structure",
|
|
172
|
-
fileName: "file.txt",
|
|
173
|
-
saveKey: "content",
|
|
174
|
-
content: "test content",
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
expect(mkdirSpy).toHaveBeenCalledWith("/deep/nested/directory/structure", {
|
|
178
|
-
recursive: true,
|
|
179
|
-
});
|
|
180
|
-
expect(joinSpy).toHaveBeenCalledWith("/deep/nested/directory/structure", "file.txt");
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
test("should handle paths with special characters", async () => {
|
|
184
|
-
await saveOutput({
|
|
185
|
-
savePath: "/path with spaces/特殊字符/symbols!@#",
|
|
186
|
-
fileName: "file-name_with-symbols.json",
|
|
187
|
-
saveKey: "data",
|
|
188
|
-
data: { test: "value" },
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
expect(mkdirSpy).toHaveBeenCalledWith("/path with spaces/特殊字符/symbols!@#", {
|
|
192
|
-
recursive: true,
|
|
193
|
-
});
|
|
194
|
-
expect(joinSpy).toHaveBeenCalledWith(
|
|
195
|
-
"/path with spaces/特殊字符/symbols!@#",
|
|
196
|
-
"file-name_with-symbols.json",
|
|
197
|
-
);
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
// EMPTY AND EDGE CASES
|
|
201
|
-
test("should save empty string content", async () => {
|
|
202
|
-
const result = await saveOutput({
|
|
203
|
-
savePath: "/empty",
|
|
204
|
-
fileName: "empty.txt",
|
|
205
|
-
saveKey: "emptyString",
|
|
206
|
-
emptyString: "",
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
expect(writeFileSpy).toHaveBeenCalledWith("/empty/empty.txt", "", "utf8");
|
|
210
|
-
expect(result.saveOutputStatus).toBe(true);
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
test("should save empty object as formatted JSON", async () => {
|
|
214
|
-
const result = await saveOutput({
|
|
215
|
-
savePath: "/empty",
|
|
216
|
-
fileName: "empty.json",
|
|
217
|
-
saveKey: "emptyObject",
|
|
218
|
-
emptyObject: {},
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
expect(writeFileSpy).toHaveBeenCalledWith("/empty/empty.json", "{}", "utf8");
|
|
222
|
-
expect(result.saveOutputStatus).toBe(true);
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
test("should save empty array as formatted JSON", async () => {
|
|
226
|
-
const result = await saveOutput({
|
|
227
|
-
savePath: "/empty",
|
|
228
|
-
fileName: "empty-array.json",
|
|
229
|
-
saveKey: "emptyArray",
|
|
230
|
-
emptyArray: [],
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
expect(writeFileSpy).toHaveBeenCalledWith("/empty/empty-array.json", "[]", "utf8");
|
|
234
|
-
expect(result.saveOutputStatus).toBe(true);
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
// COMPLEX OBJECT SERIALIZATION
|
|
238
|
-
test("should handle complex nested objects", async () => {
|
|
239
|
-
const complexObject = {
|
|
240
|
-
users: [
|
|
241
|
-
{ id: 1, name: "Alice", settings: { theme: "dark", notifications: true } },
|
|
242
|
-
{ id: 2, name: "Bob", settings: { theme: "light", notifications: false } },
|
|
243
|
-
],
|
|
244
|
-
metadata: {
|
|
245
|
-
version: "1.0.0",
|
|
246
|
-
created: "2024-01-01",
|
|
247
|
-
features: ["auth", "api", "ui"],
|
|
248
|
-
},
|
|
249
|
-
};
|
|
250
|
-
|
|
251
|
-
const result = await saveOutput({
|
|
252
|
-
savePath: "/complex",
|
|
253
|
-
fileName: "data.json",
|
|
254
|
-
saveKey: "complexData",
|
|
255
|
-
complexData: complexObject,
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
const expectedContent = JSON.stringify(complexObject, null, 2);
|
|
259
|
-
expect(writeFileSpy).toHaveBeenCalledWith("/complex/data.json", expectedContent, "utf8");
|
|
260
|
-
expect(result.saveOutputStatus).toBe(true);
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
// MULTIPLE KEYS IN INPUT
|
|
264
|
-
test("should only save the specified saveKey among multiple keys", async () => {
|
|
265
|
-
const result = await saveOutput({
|
|
266
|
-
savePath: "/selective",
|
|
267
|
-
fileName: "selected.txt",
|
|
268
|
-
saveKey: "targetKey",
|
|
269
|
-
targetKey: "This should be saved",
|
|
270
|
-
otherKey: "This should be ignored",
|
|
271
|
-
anotherKey: { ignored: "data" },
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
expect(writeFileSpy).toHaveBeenCalledWith(
|
|
275
|
-
"/selective/selected.txt",
|
|
276
|
-
"This should be saved",
|
|
277
|
-
"utf8",
|
|
278
|
-
);
|
|
279
|
-
expect(result.saveOutputStatus).toBe(true);
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
// FUNCTION CONTENT HANDLING
|
|
283
|
-
test("should convert function to string", async () => {
|
|
284
|
-
const testFunction = function testFn() {
|
|
285
|
-
return "hello";
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
const result = await saveOutput({
|
|
289
|
-
savePath: "/functions",
|
|
290
|
-
fileName: "function.txt",
|
|
291
|
-
saveKey: "fn",
|
|
292
|
-
fn: testFunction,
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
expect(writeFileSpy).toHaveBeenCalledWith(
|
|
296
|
-
"/functions/function.txt",
|
|
297
|
-
testFunction.toString(),
|
|
298
|
-
"utf8",
|
|
299
|
-
);
|
|
300
|
-
expect(result.saveOutputStatus).toBe(true);
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
// ZERO VALUES
|
|
304
|
-
test("should save zero values correctly", async () => {
|
|
305
|
-
const result = await saveOutput({
|
|
306
|
-
savePath: "/zeros",
|
|
307
|
-
fileName: "zero.txt",
|
|
308
|
-
saveKey: "zeroValue",
|
|
309
|
-
zeroValue: 0,
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
expect(writeFileSpy).toHaveBeenCalledWith("/zeros/zero.txt", "0", "utf8");
|
|
313
|
-
expect(result.saveOutputStatus).toBe(true);
|
|
314
|
-
});
|
|
315
|
-
});
|