@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.
Files changed (284) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/agents/clear/choose-contents.mjs +14 -1
  3. package/agents/clear/clear-media-description.mjs +129 -0
  4. package/agents/clear/index.yaml +3 -1
  5. package/agents/evaluate/code-snippet.mjs +28 -24
  6. package/agents/evaluate/document-structure.yaml +0 -4
  7. package/agents/evaluate/document.yaml +1 -5
  8. package/agents/generate/index.yaml +1 -0
  9. package/agents/init/index.mjs +10 -0
  10. package/agents/media/batch-generate-media-description.yaml +44 -0
  11. package/agents/media/generate-media-description.yaml +47 -0
  12. package/agents/media/load-media-description.mjs +238 -0
  13. package/agents/publish/index.yaml +4 -0
  14. package/agents/publish/publish-docs.mjs +77 -5
  15. package/agents/publish/translate-meta.mjs +103 -0
  16. package/agents/update/generate-document.yaml +30 -28
  17. package/agents/update/index.yaml +1 -0
  18. package/agents/update/update-document-detail.yaml +3 -1
  19. package/agents/utils/load-sources.mjs +103 -53
  20. package/agents/utils/update-branding.mjs +69 -0
  21. package/aigne.yaml +6 -0
  22. package/assets/report-template/report.html +34 -34
  23. package/package.json +17 -2
  24. package/prompts/common/document/role-and-personality.md +3 -1
  25. package/prompts/detail/d2-diagram/guide.md +7 -1
  26. package/prompts/detail/d2-diagram/user-prompt.md +3 -0
  27. package/prompts/detail/generate/system-prompt.md +6 -7
  28. package/prompts/detail/generate/user-prompt.md +12 -3
  29. package/prompts/detail/update/user-prompt.md +0 -2
  30. package/prompts/evaluate/document-structure.md +6 -7
  31. package/prompts/evaluate/document.md +16 -25
  32. package/prompts/media/media-description/system-prompt.md +35 -0
  33. package/prompts/media/media-description/user-prompt.md +8 -0
  34. package/prompts/structure/update/user-prompt.md +0 -4
  35. package/utils/constants/index.mjs +0 -107
  36. package/utils/file-utils.mjs +86 -0
  37. package/utils/markdown-checker.mjs +0 -20
  38. package/utils/request.mjs +7 -0
  39. package/utils/upload-files.mjs +231 -0
  40. package/utils/utils.mjs +11 -1
  41. package/.aigne/doc-smith/config.yaml +0 -77
  42. package/.aigne/doc-smith/history.yaml +0 -37
  43. package/.aigne/doc-smith/output/structure-plan.json +0 -162
  44. package/.aigne/doc-smith/preferences.yml +0 -97
  45. package/.aigne/doc-smith/upload-cache.yaml +0 -1893
  46. package/.github/PULL_REQUEST_TEMPLATE.md +0 -28
  47. package/.github/workflows/ci.yml +0 -54
  48. package/.github/workflows/create-release-pr.yaml +0 -21
  49. package/.github/workflows/publish-docs.yml +0 -65
  50. package/.github/workflows/release.yml +0 -49
  51. package/.github/workflows/reviewer.yml +0 -54
  52. package/.release-please-manifest.json +0 -3
  53. package/RELEASE.md +0 -9
  54. package/assets/screenshots/doc-complete-setup.png +0 -0
  55. package/assets/screenshots/doc-generate-docs.png +0 -0
  56. package/assets/screenshots/doc-generate.png +0 -0
  57. package/assets/screenshots/doc-generated-successfully.png +0 -0
  58. package/assets/screenshots/doc-publish.png +0 -0
  59. package/assets/screenshots/doc-regenerate.png +0 -0
  60. package/assets/screenshots/doc-translate-langs.png +0 -0
  61. package/assets/screenshots/doc-translate.png +0 -0
  62. package/assets/screenshots/doc-update.png +0 -0
  63. package/biome.json +0 -73
  64. package/codecov.yml +0 -15
  65. package/docs/_sidebar.md +0 -15
  66. package/docs/configuration-initial-setup.ja.md +0 -179
  67. package/docs/configuration-initial-setup.md +0 -179
  68. package/docs/configuration-initial-setup.zh-TW.md +0 -179
  69. package/docs/configuration-initial-setup.zh.md +0 -179
  70. package/docs/configuration-managing-preferences.ja.md +0 -100
  71. package/docs/configuration-managing-preferences.md +0 -100
  72. package/docs/configuration-managing-preferences.zh-TW.md +0 -100
  73. package/docs/configuration-managing-preferences.zh.md +0 -100
  74. package/docs/configuration.ja.md +0 -96
  75. package/docs/configuration.md +0 -96
  76. package/docs/configuration.zh-TW.md +0 -96
  77. package/docs/configuration.zh.md +0 -96
  78. package/docs/getting-started.ja.md +0 -88
  79. package/docs/getting-started.md +0 -88
  80. package/docs/getting-started.zh-TW.md +0 -88
  81. package/docs/getting-started.zh.md +0 -88
  82. package/docs/guides-cleaning-up.ja.md +0 -51
  83. package/docs/guides-cleaning-up.md +0 -51
  84. package/docs/guides-cleaning-up.zh-TW.md +0 -51
  85. package/docs/guides-cleaning-up.zh.md +0 -51
  86. package/docs/guides-evaluating-documents.ja.md +0 -66
  87. package/docs/guides-evaluating-documents.md +0 -66
  88. package/docs/guides-evaluating-documents.zh-TW.md +0 -66
  89. package/docs/guides-evaluating-documents.zh.md +0 -66
  90. package/docs/guides-generating-documentation.ja.md +0 -151
  91. package/docs/guides-generating-documentation.md +0 -151
  92. package/docs/guides-generating-documentation.zh-TW.md +0 -151
  93. package/docs/guides-generating-documentation.zh.md +0 -151
  94. package/docs/guides-interactive-chat.ja.md +0 -85
  95. package/docs/guides-interactive-chat.md +0 -85
  96. package/docs/guides-interactive-chat.zh-TW.md +0 -85
  97. package/docs/guides-interactive-chat.zh.md +0 -85
  98. package/docs/guides-managing-history.ja.md +0 -48
  99. package/docs/guides-managing-history.md +0 -48
  100. package/docs/guides-managing-history.zh-TW.md +0 -48
  101. package/docs/guides-managing-history.zh.md +0 -48
  102. package/docs/guides-publishing-your-docs.ja.md +0 -78
  103. package/docs/guides-publishing-your-docs.md +0 -78
  104. package/docs/guides-publishing-your-docs.zh-TW.md +0 -78
  105. package/docs/guides-publishing-your-docs.zh.md +0 -78
  106. package/docs/guides-translating-documentation.ja.md +0 -95
  107. package/docs/guides-translating-documentation.md +0 -95
  108. package/docs/guides-translating-documentation.zh-TW.md +0 -95
  109. package/docs/guides-translating-documentation.zh.md +0 -95
  110. package/docs/guides-updating-documentation.ja.md +0 -77
  111. package/docs/guides-updating-documentation.md +0 -77
  112. package/docs/guides-updating-documentation.zh-TW.md +0 -77
  113. package/docs/guides-updating-documentation.zh.md +0 -77
  114. package/docs/guides.ja.md +0 -32
  115. package/docs/guides.md +0 -32
  116. package/docs/guides.zh-TW.md +0 -32
  117. package/docs/guides.zh.md +0 -32
  118. package/docs/overview.ja.md +0 -61
  119. package/docs/overview.md +0 -61
  120. package/docs/overview.zh-TW.md +0 -61
  121. package/docs/overview.zh.md +0 -61
  122. package/docs/release-notes.ja.md +0 -255
  123. package/docs/release-notes.md +0 -255
  124. package/docs/release-notes.zh-TW.md +0 -255
  125. package/docs/release-notes.zh.md +0 -255
  126. package/media.md +0 -19
  127. package/prompts/common/afs/afs-tools-usage.md +0 -5
  128. package/prompts/common/afs/use-afs-instruction.md +0 -1
  129. package/release-please-config.json +0 -14
  130. package/tests/agents/chat/chat.test.mjs +0 -46
  131. package/tests/agents/clear/choose-contents.test.mjs +0 -284
  132. package/tests/agents/clear/clear-auth-tokens.test.mjs +0 -268
  133. package/tests/agents/clear/clear-document-config.test.mjs +0 -167
  134. package/tests/agents/clear/clear-document-structure.test.mjs +0 -380
  135. package/tests/agents/clear/clear-generated-docs.test.mjs +0 -222
  136. package/tests/agents/evaluate/code-snippet.test.mjs +0 -163
  137. package/tests/agents/evaluate/fixtures/api-services.md +0 -87
  138. package/tests/agents/evaluate/fixtures/js-sdk.md +0 -94
  139. package/tests/agents/evaluate/generate-report.test.mjs +0 -312
  140. package/tests/agents/generate/check-document-structure.test.mjs +0 -45
  141. package/tests/agents/generate/check-need-generate-structure.test.mjs +0 -279
  142. package/tests/agents/generate/document-structure-tools/add-document.test.mjs +0 -449
  143. package/tests/agents/generate/document-structure-tools/delete-document.test.mjs +0 -410
  144. package/tests/agents/generate/document-structure-tools/generate-sub-structure.test.mjs +0 -277
  145. package/tests/agents/generate/document-structure-tools/move-document.test.mjs +0 -476
  146. package/tests/agents/generate/document-structure-tools/update-document.test.mjs +0 -548
  147. package/tests/agents/generate/generate-structure.test.mjs +0 -45
  148. package/tests/agents/generate/user-review-document-structure.test.mjs +0 -319
  149. package/tests/agents/history/view.test.mjs +0 -97
  150. package/tests/agents/init/init.test.mjs +0 -1657
  151. package/tests/agents/prefs/prefs.test.mjs +0 -431
  152. package/tests/agents/publish/publish-docs.test.mjs +0 -787
  153. package/tests/agents/translate/choose-language.test.mjs +0 -311
  154. package/tests/agents/translate/translate-document.test.mjs +0 -51
  155. package/tests/agents/update/check-document.test.mjs +0 -463
  156. package/tests/agents/update/check-update-is-single.test.mjs +0 -300
  157. package/tests/agents/update/document-tools/update-document-content.test.mjs +0 -329
  158. package/tests/agents/update/generate-document.test.mjs +0 -51
  159. package/tests/agents/update/save-and-translate-document.test.mjs +0 -369
  160. package/tests/agents/update/user-review-document.test.mjs +0 -582
  161. package/tests/agents/utils/action-success.test.mjs +0 -54
  162. package/tests/agents/utils/check-detail-result.test.mjs +0 -743
  163. package/tests/agents/utils/check-feedback-refiner.test.mjs +0 -478
  164. package/tests/agents/utils/choose-docs.test.mjs +0 -406
  165. package/tests/agents/utils/exit.test.mjs +0 -70
  166. package/tests/agents/utils/feedback-refiner.test.mjs +0 -51
  167. package/tests/agents/utils/find-item-by-path.test.mjs +0 -517
  168. package/tests/agents/utils/find-user-preferences-by-path.test.mjs +0 -382
  169. package/tests/agents/utils/format-document-structure.test.mjs +0 -364
  170. package/tests/agents/utils/fs.test.mjs +0 -267
  171. package/tests/agents/utils/load-sources.test.mjs +0 -1470
  172. package/tests/agents/utils/save-docs.test.mjs +0 -109
  173. package/tests/agents/utils/save-output.test.mjs +0 -315
  174. package/tests/agents/utils/save-single-doc.test.mjs +0 -364
  175. package/tests/agents/utils/transform-detail-datasources.test.mjs +0 -320
  176. package/tests/utils/auth-utils.test.mjs +0 -596
  177. package/tests/utils/blocklet.test.mjs +0 -336
  178. package/tests/utils/conflict-detector.test.mjs +0 -355
  179. package/tests/utils/constants.test.mjs +0 -295
  180. package/tests/utils/d2-utils.test.mjs +0 -437
  181. package/tests/utils/deploy.test.mjs +0 -399
  182. package/tests/utils/docs-finder-utils.test.mjs +0 -650
  183. package/tests/utils/file-utils.test.mjs +0 -521
  184. package/tests/utils/history-utils.test.mjs +0 -206
  185. package/tests/utils/kroki-utils.test.mjs +0 -646
  186. package/tests/utils/linter/fixtures/css/keyword-error.css +0 -1
  187. package/tests/utils/linter/fixtures/css/missing-semicolon.css +0 -1
  188. package/tests/utils/linter/fixtures/css/syntax-error.css +0 -1
  189. package/tests/utils/linter/fixtures/css/undeclare-variable.css +0 -1
  190. package/tests/utils/linter/fixtures/css/unused-variable.css +0 -2
  191. package/tests/utils/linter/fixtures/css/valid-code.css +0 -1
  192. package/tests/utils/linter/fixtures/dockerfile/keyword-error.dockerfile +0 -1
  193. package/tests/utils/linter/fixtures/dockerfile/missing-semicolon.dockerfile +0 -2
  194. package/tests/utils/linter/fixtures/dockerfile/syntax-error.dockerfile +0 -2
  195. package/tests/utils/linter/fixtures/dockerfile/undeclare-variable.dockerfile +0 -1
  196. package/tests/utils/linter/fixtures/dockerfile/unused-variable.dockerfile +0 -1
  197. package/tests/utils/linter/fixtures/dockerfile/valid-code.dockerfile +0 -2
  198. package/tests/utils/linter/fixtures/go/keyword-error.go +0 -5
  199. package/tests/utils/linter/fixtures/go/missing-semicolon.go +0 -5
  200. package/tests/utils/linter/fixtures/go/syntax-error.go +0 -6
  201. package/tests/utils/linter/fixtures/go/undeclare-variable.go +0 -5
  202. package/tests/utils/linter/fixtures/go/unused-variable.go +0 -5
  203. package/tests/utils/linter/fixtures/go/valid-code.go +0 -7
  204. package/tests/utils/linter/fixtures/js/keyword-error.js +0 -3
  205. package/tests/utils/linter/fixtures/js/missing-semicolon.js +0 -6
  206. package/tests/utils/linter/fixtures/js/syntax-error.js +0 -4
  207. package/tests/utils/linter/fixtures/js/undeclare-variable.js +0 -3
  208. package/tests/utils/linter/fixtures/js/unused-variable.js +0 -7
  209. package/tests/utils/linter/fixtures/js/valid-code.js +0 -15
  210. package/tests/utils/linter/fixtures/json/keyword-error.json +0 -1
  211. package/tests/utils/linter/fixtures/json/missing-semicolon.json +0 -1
  212. package/tests/utils/linter/fixtures/json/syntax-error.json +0 -1
  213. package/tests/utils/linter/fixtures/json/undeclare-variable.json +0 -1
  214. package/tests/utils/linter/fixtures/json/unused-variable.json +0 -1
  215. package/tests/utils/linter/fixtures/json/valid-code.json +0 -1
  216. package/tests/utils/linter/fixtures/jsx/keyword-error.jsx +0 -5
  217. package/tests/utils/linter/fixtures/jsx/missing-semicolon.jsx +0 -5
  218. package/tests/utils/linter/fixtures/jsx/syntax-error.jsx +0 -5
  219. package/tests/utils/linter/fixtures/jsx/undeclare-variable.jsx +0 -5
  220. package/tests/utils/linter/fixtures/jsx/unused-variable.jsx +0 -4
  221. package/tests/utils/linter/fixtures/jsx/valid-code.jsx +0 -5
  222. package/tests/utils/linter/fixtures/python/keyword-error.py +0 -3
  223. package/tests/utils/linter/fixtures/python/missing-semicolon.py +0 -2
  224. package/tests/utils/linter/fixtures/python/syntax-error.py +0 -3
  225. package/tests/utils/linter/fixtures/python/undeclare-variable.py +0 -3
  226. package/tests/utils/linter/fixtures/python/unused-variable.py +0 -6
  227. package/tests/utils/linter/fixtures/python/valid-code.py +0 -12
  228. package/tests/utils/linter/fixtures/ruby/keyword-error.rb +0 -2
  229. package/tests/utils/linter/fixtures/ruby/missing-semicolon.rb +0 -1
  230. package/tests/utils/linter/fixtures/ruby/syntax-error.rb +0 -2
  231. package/tests/utils/linter/fixtures/ruby/undeclare-variable.rb +0 -1
  232. package/tests/utils/linter/fixtures/ruby/unused-variable.rb +0 -2
  233. package/tests/utils/linter/fixtures/ruby/valid-code.rb +0 -1
  234. package/tests/utils/linter/fixtures/sass/keyword-error.sass +0 -2
  235. package/tests/utils/linter/fixtures/sass/missing-semicolon.sass +0 -3
  236. package/tests/utils/linter/fixtures/sass/syntax-error.sass +0 -3
  237. package/tests/utils/linter/fixtures/sass/undeclare-variable.sass +0 -2
  238. package/tests/utils/linter/fixtures/sass/unused-variable.sass +0 -4
  239. package/tests/utils/linter/fixtures/sass/valid-code.sass +0 -2
  240. package/tests/utils/linter/fixtures/scss/keyword-error.scss +0 -1
  241. package/tests/utils/linter/fixtures/scss/missing-semicolon.scss +0 -1
  242. package/tests/utils/linter/fixtures/scss/syntax-error.scss +0 -1
  243. package/tests/utils/linter/fixtures/scss/undeclare-variable.scss +0 -1
  244. package/tests/utils/linter/fixtures/scss/unused-variable.scss +0 -2
  245. package/tests/utils/linter/fixtures/scss/valid-code.scss +0 -1
  246. package/tests/utils/linter/fixtures/shell/keyword-error.sh +0 -5
  247. package/tests/utils/linter/fixtures/shell/missing-semicolon.sh +0 -3
  248. package/tests/utils/linter/fixtures/shell/syntax-error.sh +0 -4
  249. package/tests/utils/linter/fixtures/shell/undeclare-variable.sh +0 -3
  250. package/tests/utils/linter/fixtures/shell/unused-variable.sh +0 -4
  251. package/tests/utils/linter/fixtures/shell/valid-code.sh +0 -3
  252. package/tests/utils/linter/fixtures/ts/keyword-error.ts +0 -1
  253. package/tests/utils/linter/fixtures/ts/missing-semicolon.ts +0 -1
  254. package/tests/utils/linter/fixtures/ts/syntax-error.ts +0 -1
  255. package/tests/utils/linter/fixtures/ts/undeclare-variable.ts +0 -1
  256. package/tests/utils/linter/fixtures/ts/unused-variable.ts +0 -3
  257. package/tests/utils/linter/fixtures/ts/valid-code.ts +0 -3
  258. package/tests/utils/linter/fixtures/tsx/keyword-error.tsx +0 -5
  259. package/tests/utils/linter/fixtures/tsx/missing-semicolon.tsx +0 -5
  260. package/tests/utils/linter/fixtures/tsx/syntax-error.tsx +0 -5
  261. package/tests/utils/linter/fixtures/tsx/undeclare-variable.tsx +0 -6
  262. package/tests/utils/linter/fixtures/tsx/unused-variable.tsx +0 -6
  263. package/tests/utils/linter/fixtures/tsx/valid-code.tsx +0 -5
  264. package/tests/utils/linter/fixtures/vue/keyword-error.vue +0 -6
  265. package/tests/utils/linter/fixtures/vue/missing-semicolon.vue +0 -6
  266. package/tests/utils/linter/fixtures/vue/syntax-error.vue +0 -6
  267. package/tests/utils/linter/fixtures/vue/undeclare-variable.vue +0 -6
  268. package/tests/utils/linter/fixtures/vue/unused-variable.vue +0 -7
  269. package/tests/utils/linter/fixtures/vue/valid-code.vue +0 -6
  270. package/tests/utils/linter/fixtures/yaml/keyword-error.yml +0 -1
  271. package/tests/utils/linter/fixtures/yaml/missing-semicolon.yml +0 -2
  272. package/tests/utils/linter/fixtures/yaml/syntax-error.yml +0 -1
  273. package/tests/utils/linter/fixtures/yaml/undeclare-variable.yml +0 -1
  274. package/tests/utils/linter/fixtures/yaml/unused-variable.yml +0 -2
  275. package/tests/utils/linter/fixtures/yaml/valid-code.yml +0 -3
  276. package/tests/utils/linter/index.test.mjs +0 -440
  277. package/tests/utils/linter/scan-results.mjs +0 -42
  278. package/tests/utils/load-config.test.mjs +0 -141
  279. package/tests/utils/markdown/index.test.mjs +0 -478
  280. package/tests/utils/mermaid-validator.test.mjs +0 -541
  281. package/tests/utils/mock-chat-model.mjs +0 -12
  282. package/tests/utils/preferences-utils.test.mjs +0 -465
  283. package/tests/utils/save-value-to-config.test.mjs +0 -483
  284. package/tests/utils/utils.test.mjs +0 -941
@@ -1,382 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test";
2
- import findUserPreferencesByPath from "../../../agents/utils/find-user-preferences-by-path.mjs";
3
-
4
- import * as preferencesUtils from "../../../utils/preferences-utils.mjs";
5
-
6
- describe("find-user-preferences-by-path", () => {
7
- // Spies for internal utils
8
- let getActiveRulesForScopeSpy;
9
-
10
- beforeEach(() => {
11
- // Set up spies for internal utils
12
- getActiveRulesForScopeSpy = spyOn(preferencesUtils, "getActiveRulesForScope").mockReturnValue(
13
- [],
14
- );
15
-
16
- // Clear spy call history
17
- getActiveRulesForScopeSpy.mockClear();
18
- });
19
-
20
- afterEach(() => {
21
- // Restore all spies
22
- getActiveRulesForScopeSpy?.mockRestore();
23
- });
24
-
25
- // BASIC FUNCTIONALITY TESTS
26
- test("should return empty preferences when no rules found", async () => {
27
- const result = await findUserPreferencesByPath({
28
- path: "/api/users",
29
- scope: "document",
30
- });
31
-
32
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledTimes(2);
33
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("global", []);
34
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("document", ["/api/users"]);
35
- expect(result).toEqual({
36
- userPreferences: "",
37
- });
38
- });
39
-
40
- test("should return global rules when only global rules exist", async () => {
41
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
42
- if (scope === "global") {
43
- return [
44
- { rule: "Always use clear and concise language" },
45
- { rule: "Include code examples when relevant" },
46
- ];
47
- }
48
- return [];
49
- });
50
-
51
- const result = await findUserPreferencesByPath({
52
- path: "/api/users",
53
- scope: "document",
54
- });
55
-
56
- expect(result).toEqual({
57
- userPreferences:
58
- "Always use clear and concise language\n\nInclude code examples when relevant",
59
- });
60
- });
61
-
62
- test("should return scope rules when only scope rules exist", async () => {
63
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
64
- if (scope === "document") {
65
- return [
66
- { rule: "Focus on API documentation standards" },
67
- { rule: "Include parameter details" },
68
- ];
69
- }
70
- return [];
71
- });
72
-
73
- const result = await findUserPreferencesByPath({
74
- path: "/api/users",
75
- scope: "document",
76
- });
77
-
78
- expect(result).toEqual({
79
- userPreferences: "Focus on API documentation standards\n\nInclude parameter details",
80
- });
81
- });
82
-
83
- test("should combine global and scope rules correctly", async () => {
84
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
85
- if (scope === "global") {
86
- return [{ rule: "Use consistent terminology" }, { rule: "Maintain professional tone" }];
87
- }
88
- if (scope === "document") {
89
- return [{ rule: "Include version information" }, { rule: "Add deprecation notices" }];
90
- }
91
- return [];
92
- });
93
-
94
- const result = await findUserPreferencesByPath({
95
- path: "/api/auth",
96
- scope: "document",
97
- });
98
-
99
- expect(result).toEqual({
100
- userPreferences:
101
- "Use consistent terminology\n\nMaintain professional tone\n\nInclude version information\n\nAdd deprecation notices",
102
- });
103
- });
104
-
105
- // SCOPE-SPECIFIC TESTS
106
- test("should handle document scope correctly", async () => {
107
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
108
- if (scope === "global") {
109
- return [{ rule: "Global rule" }];
110
- }
111
- if (scope === "document") {
112
- return [{ rule: "Document rule" }];
113
- }
114
- return [];
115
- });
116
-
117
- await findUserPreferencesByPath({
118
- path: "/docs/getting-started",
119
- scope: "document",
120
- });
121
-
122
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("global", []);
123
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("document", ["/docs/getting-started"]);
124
- });
125
-
126
- test("should handle translation scope correctly", async () => {
127
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
128
- if (scope === "global") {
129
- return [{ rule: "Global rule" }];
130
- }
131
- if (scope === "translation") {
132
- return [{ rule: "Translation rule" }];
133
- }
134
- return [];
135
- });
136
-
137
- await findUserPreferencesByPath({
138
- path: "/docs/api-reference",
139
- scope: "translation",
140
- });
141
-
142
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("global", []);
143
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("translation", ["/docs/api-reference"]);
144
- });
145
-
146
- test("should handle missing path parameter", async () => {
147
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
148
- if (scope === "global") {
149
- return [{ rule: "Global rule for all" }];
150
- }
151
- if (scope === "document") {
152
- return [{ rule: "Document rule for all" }];
153
- }
154
- return [];
155
- });
156
-
157
- const result = await findUserPreferencesByPath({
158
- scope: "document",
159
- });
160
-
161
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("global", []);
162
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("document", []);
163
- expect(result).toEqual({
164
- userPreferences: "Global rule for all\n\nDocument rule for all",
165
- });
166
- });
167
-
168
- test("should handle null path parameter", async () => {
169
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
170
- if (scope === "global") {
171
- return [{ rule: "Global rule" }];
172
- }
173
- return [];
174
- });
175
-
176
- const result = await findUserPreferencesByPath({
177
- path: null,
178
- scope: "translation",
179
- });
180
-
181
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("global", []);
182
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("translation", []);
183
- expect(result).toEqual({
184
- userPreferences: "Global rule",
185
- });
186
- });
187
-
188
- test("should handle empty path parameter", async () => {
189
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
190
- if (scope === "global") {
191
- return [{ rule: "Global rule" }];
192
- }
193
- return [];
194
- });
195
-
196
- const result = await findUserPreferencesByPath({
197
- path: "",
198
- scope: "document",
199
- });
200
-
201
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("global", []);
202
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("document", []);
203
- expect(result).toEqual({
204
- userPreferences: "Global rule",
205
- });
206
- });
207
-
208
- // RULE COMBINATION TESTS
209
- test("should handle single rule correctly", async () => {
210
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
211
- if (scope === "global") {
212
- return [{ rule: "Single global rule" }];
213
- }
214
- return [];
215
- });
216
-
217
- const result = await findUserPreferencesByPath({
218
- path: "/test",
219
- scope: "document",
220
- });
221
-
222
- expect(result).toEqual({
223
- userPreferences: "Single global rule",
224
- });
225
- });
226
-
227
- test("should handle multiple rules with proper formatting", async () => {
228
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
229
- if (scope === "global") {
230
- return [{ rule: "First rule" }, { rule: "Second rule" }, { rule: "Third rule" }];
231
- }
232
- return [];
233
- });
234
-
235
- const result = await findUserPreferencesByPath({
236
- path: "/test",
237
- scope: "document",
238
- });
239
-
240
- expect(result).toEqual({
241
- userPreferences: "First rule\n\nSecond rule\n\nThird rule",
242
- });
243
- });
244
-
245
- test("should handle rules with complex text", async () => {
246
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
247
- if (scope === "global") {
248
- return [
249
- {
250
- rule: "When writing API documentation, always include:\n- Request parameters\n- Response examples\n- Error codes",
251
- },
252
- ];
253
- }
254
- if (scope === "document") {
255
- return [
256
- {
257
- rule: "For authentication endpoints:\n1. Mention security considerations\n2. Include rate limiting info",
258
- },
259
- ];
260
- }
261
- return [];
262
- });
263
-
264
- const result = await findUserPreferencesByPath({
265
- path: "/api/auth/login",
266
- scope: "document",
267
- });
268
-
269
- expect(result.userPreferences).toContain("When writing API documentation");
270
- expect(result.userPreferences).toContain("For authentication endpoints");
271
- expect(result.userPreferences).toContain("\n\n");
272
- });
273
-
274
- // EDGE CASES
275
- test("should handle undefined scope parameter gracefully", async () => {
276
- const result = await findUserPreferencesByPath({
277
- path: "/test",
278
- });
279
-
280
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("global", []);
281
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith(undefined, ["/test"]);
282
- expect(result).toEqual({
283
- userPreferences: "",
284
- });
285
- });
286
-
287
- test("should handle rules with empty rule text", async () => {
288
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
289
- if (scope === "global") {
290
- return [{ rule: "Valid rule" }, { rule: "" }, { rule: "Another valid rule" }];
291
- }
292
- return [];
293
- });
294
-
295
- const result = await findUserPreferencesByPath({
296
- path: "/test",
297
- scope: "document",
298
- });
299
-
300
- expect(result).toEqual({
301
- userPreferences: "Valid rule\n\n\n\nAnother valid rule",
302
- });
303
- });
304
-
305
- test("should preserve rule order (global first, then scope)", async () => {
306
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
307
- if (scope === "global") {
308
- return [{ rule: "Global rule 1" }, { rule: "Global rule 2" }];
309
- }
310
- if (scope === "document") {
311
- return [{ rule: "Document rule 1" }, { rule: "Document rule 2" }];
312
- }
313
- return [];
314
- });
315
-
316
- const result = await findUserPreferencesByPath({
317
- path: "/test",
318
- scope: "document",
319
- });
320
-
321
- expect(result).toEqual({
322
- userPreferences: "Global rule 1\n\nGlobal rule 2\n\nDocument rule 1\n\nDocument rule 2",
323
- });
324
- });
325
-
326
- // PERFORMANCE AND EFFICIENCY TESTS
327
- test("should call getActiveRulesForScope exactly twice", async () => {
328
- await findUserPreferencesByPath({
329
- path: "/performance/test",
330
- scope: "translation",
331
- });
332
-
333
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledTimes(2);
334
- });
335
-
336
- test("should handle large number of rules efficiently", async () => {
337
- const manyRules = Array.from({ length: 100 }, (_, i) => ({
338
- rule: `Rule number ${i + 1}`,
339
- }));
340
-
341
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
342
- if (scope === "global") {
343
- return manyRules.slice(0, 50);
344
- }
345
- if (scope === "document") {
346
- return manyRules.slice(50);
347
- }
348
- return [];
349
- });
350
-
351
- const result = await findUserPreferencesByPath({
352
- path: "/large/test",
353
- scope: "document",
354
- });
355
-
356
- expect(result.userPreferences.split("\n\n")).toHaveLength(100);
357
- expect(result.userPreferences).toContain("Rule number 1");
358
- expect(result.userPreferences).toContain("Rule number 100");
359
- });
360
-
361
- // PARAMETER VALIDATION TESTS
362
- test("should work with various path formats", async () => {
363
- const testPaths = [
364
- "/simple",
365
- "/nested/path",
366
- "/deeply/nested/path/here",
367
- "/with-dashes",
368
- "/with_underscores",
369
- "/with.dots",
370
- "/api/v1/users/123",
371
- ];
372
-
373
- for (const path of testPaths) {
374
- await findUserPreferencesByPath({
375
- path,
376
- scope: "document",
377
- });
378
-
379
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("document", [path]);
380
- }
381
- });
382
- });