eslint-plugin-traceability 1.23.0 → 1.24.0

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 (247) hide show
  1. package/CHANGELOG.md +2 -2
  2. package/lib/{src/rules → rules}/require-traceability.js +49 -4
  3. package/package.json +8 -8
  4. package/user-docs/api-reference.md +25 -0
  5. package/lib/tests/cli-error-handling.test.d.ts +0 -1
  6. package/lib/tests/cli-error-handling.test.js +0 -54
  7. package/lib/tests/config/eslint-config-validation.test.d.ts +0 -9
  8. package/lib/tests/config/eslint-config-validation.test.js +0 -101
  9. package/lib/tests/config/flat-config-presets-integration.test.d.ts +0 -1
  10. package/lib/tests/config/flat-config-presets-integration.test.js +0 -76
  11. package/lib/tests/config/require-story-annotation-config.test.d.ts +0 -10
  12. package/lib/tests/config/require-story-annotation-config.test.js +0 -26
  13. package/lib/tests/fixtures/stale/example.d.ts +0 -0
  14. package/lib/tests/fixtures/stale/example.js +0 -4
  15. package/lib/tests/fixtures/update/example.d.ts +0 -0
  16. package/lib/tests/fixtures/update/example.js +0 -4
  17. package/lib/tests/fixtures/valid-annotations/example.d.ts +0 -0
  18. package/lib/tests/fixtures/valid-annotations/example.js +0 -3
  19. package/lib/tests/integration/annotation-placement-inside-prettier.integration.test.d.ts +0 -1
  20. package/lib/tests/integration/annotation-placement-inside-prettier.integration.test.js +0 -133
  21. package/lib/tests/integration/catch-annotation-prettier.integration.test.d.ts +0 -1
  22. package/lib/tests/integration/catch-annotation-prettier.integration.test.js +0 -121
  23. package/lib/tests/integration/cli-integration.test.d.ts +0 -1
  24. package/lib/tests/integration/cli-integration.test.js +0 -96
  25. package/lib/tests/integration/else-if-annotation-prettier.integration.test.d.ts +0 -1
  26. package/lib/tests/integration/else-if-annotation-prettier.integration.test.js +0 -100
  27. package/lib/tests/integration/no-redundant-annotation.integration.test.d.ts +0 -1
  28. package/lib/tests/integration/no-redundant-annotation.integration.test.js +0 -129
  29. package/lib/tests/integration/prettier-test-helpers.d.ts +0 -9
  30. package/lib/tests/integration/prettier-test-helpers.js +0 -35
  31. package/lib/tests/integration/require-traceability-aliases.integration.test.d.ts +0 -1
  32. package/lib/tests/integration/require-traceability-aliases.integration.test.js +0 -152
  33. package/lib/tests/integration/require-traceability-test-callbacks.integration.test.d.ts +0 -1
  34. package/lib/tests/integration/require-traceability-test-callbacks.integration.test.js +0 -149
  35. package/lib/tests/maintenance/batch.test.d.ts +0 -1
  36. package/lib/tests/maintenance/batch.test.js +0 -80
  37. package/lib/tests/maintenance/cli.test.d.ts +0 -1
  38. package/lib/tests/maintenance/cli.test.js +0 -306
  39. package/lib/tests/maintenance/detect-isolated.test.d.ts +0 -1
  40. package/lib/tests/maintenance/detect-isolated.test.js +0 -187
  41. package/lib/tests/maintenance/detect.test.d.ts +0 -1
  42. package/lib/tests/maintenance/detect.test.js +0 -46
  43. package/lib/tests/maintenance/index.test.d.ts +0 -1
  44. package/lib/tests/maintenance/index.test.js +0 -26
  45. package/lib/tests/maintenance/report.test.d.ts +0 -1
  46. package/lib/tests/maintenance/report.test.js +0 -68
  47. package/lib/tests/maintenance/storyParser.test.d.ts +0 -8
  48. package/lib/tests/maintenance/storyParser.test.js +0 -505
  49. package/lib/tests/maintenance/update-isolated.test.d.ts +0 -1
  50. package/lib/tests/maintenance/update-isolated.test.js +0 -71
  51. package/lib/tests/maintenance/update.test.d.ts +0 -1
  52. package/lib/tests/maintenance/update.test.js +0 -27
  53. package/lib/tests/perf/maintenance-cli-large-workspace.test.d.ts +0 -1
  54. package/lib/tests/perf/maintenance-cli-large-workspace.test.js +0 -229
  55. package/lib/tests/perf/maintenance-large-workspace.test.d.ts +0 -1
  56. package/lib/tests/perf/maintenance-large-workspace.test.js +0 -169
  57. package/lib/tests/perf/require-branch-annotation-large-file.test.d.ts +0 -1
  58. package/lib/tests/perf/require-branch-annotation-large-file.test.js +0 -67
  59. package/lib/tests/perf/valid-annotation-format-large-file.test.d.ts +0 -1
  60. package/lib/tests/perf/valid-annotation-format-large-file.test.js +0 -75
  61. package/lib/tests/plugin-default-export-and-configs.test.d.ts +0 -1
  62. package/lib/tests/plugin-default-export-and-configs.test.js +0 -121
  63. package/lib/tests/plugin-setup-error.test.d.ts +0 -6
  64. package/lib/tests/plugin-setup-error.test.js +0 -38
  65. package/lib/tests/plugin-setup.test.d.ts +0 -1
  66. package/lib/tests/plugin-setup.test.js +0 -63
  67. package/lib/tests/rules/auto-fix-behavior-008.test.d.ts +0 -1
  68. package/lib/tests/rules/auto-fix-behavior-008.test.js +0 -285
  69. package/lib/tests/rules/error-reporting.test.d.ts +0 -1
  70. package/lib/tests/rules/error-reporting.test.js +0 -99
  71. package/lib/tests/rules/no-redundant-annotation.test.d.ts +0 -1
  72. package/lib/tests/rules/no-redundant-annotation.test.js +0 -163
  73. package/lib/tests/rules/prefer-implements-annotation.test.d.ts +0 -1
  74. package/lib/tests/rules/prefer-implements-annotation.test.js +0 -162
  75. package/lib/tests/rules/require-branch-annotation.test.d.ts +0 -1
  76. package/lib/tests/rules/require-branch-annotation.test.js +0 -593
  77. package/lib/tests/rules/require-req-annotation.test.d.ts +0 -1
  78. package/lib/tests/rules/require-req-annotation.test.js +0 -264
  79. package/lib/tests/rules/require-story-annotation.test.d.ts +0 -1
  80. package/lib/tests/rules/require-story-annotation.test.js +0 -376
  81. package/lib/tests/rules/require-story-core-edgecases.test.d.ts +0 -1
  82. package/lib/tests/rules/require-story-core-edgecases.test.js +0 -15
  83. package/lib/tests/rules/require-story-core.autofix.test.d.ts +0 -1
  84. package/lib/tests/rules/require-story-core.autofix.test.js +0 -66
  85. package/lib/tests/rules/require-story-core.test.d.ts +0 -1
  86. package/lib/tests/rules/require-story-core.test.js +0 -65
  87. package/lib/tests/rules/require-story-helpers-edgecases.test.d.ts +0 -7
  88. package/lib/tests/rules/require-story-helpers-edgecases.test.js +0 -80
  89. package/lib/tests/rules/require-story-helpers.test.d.ts +0 -1
  90. package/lib/tests/rules/require-story-helpers.test.js +0 -474
  91. package/lib/tests/rules/require-story-io-behavior.test.d.ts +0 -7
  92. package/lib/tests/rules/require-story-io-behavior.test.js +0 -46
  93. package/lib/tests/rules/require-story-io.edgecases.test.d.ts +0 -7
  94. package/lib/tests/rules/require-story-io.edgecases.test.js +0 -46
  95. package/lib/tests/rules/require-story-utils.test.d.ts +0 -7
  96. package/lib/tests/rules/require-story-utils.test.js +0 -158
  97. package/lib/tests/rules/require-story-visitors-edgecases.test.d.ts +0 -7
  98. package/lib/tests/rules/require-story-visitors-edgecases.test.js +0 -27
  99. package/lib/tests/rules/require-test-traceability.test.d.ts +0 -1
  100. package/lib/tests/rules/require-test-traceability.test.js +0 -95
  101. package/lib/tests/rules/valid-annotation-format-internal.test.d.ts +0 -8
  102. package/lib/tests/rules/valid-annotation-format-internal.test.js +0 -47
  103. package/lib/tests/rules/valid-annotation-format.test.d.ts +0 -1
  104. package/lib/tests/rules/valid-annotation-format.test.js +0 -634
  105. package/lib/tests/rules/valid-req-reference.test.d.ts +0 -1
  106. package/lib/tests/rules/valid-req-reference.test.js +0 -129
  107. package/lib/tests/rules/valid-story-reference.test.d.ts +0 -1
  108. package/lib/tests/rules/valid-story-reference.test.js +0 -413
  109. package/lib/tests/utils/annotation-checker-autofix-behavior.test.d.ts +0 -5
  110. package/lib/tests/utils/annotation-checker-autofix-behavior.test.js +0 -103
  111. package/lib/tests/utils/annotation-checker.test.d.ts +0 -24
  112. package/lib/tests/utils/annotation-checker.test.js +0 -84
  113. package/lib/tests/utils/annotation-scope-analyzer.test.d.ts +0 -1
  114. package/lib/tests/utils/annotation-scope-analyzer.test.js +0 -211
  115. package/lib/tests/utils/branch-annotation-catch-insert-position.test.d.ts +0 -1
  116. package/lib/tests/utils/branch-annotation-catch-insert-position.test.js +0 -69
  117. package/lib/tests/utils/branch-annotation-catch-position.test.d.ts +0 -1
  118. package/lib/tests/utils/branch-annotation-catch-position.test.js +0 -115
  119. package/lib/tests/utils/branch-annotation-else-if-insert-position.test.d.ts +0 -1
  120. package/lib/tests/utils/branch-annotation-else-if-insert-position.test.js +0 -82
  121. package/lib/tests/utils/branch-annotation-else-if-position.test.d.ts +0 -1
  122. package/lib/tests/utils/branch-annotation-else-if-position.test.js +0 -145
  123. package/lib/tests/utils/branch-annotation-helpers.test.d.ts +0 -1
  124. package/lib/tests/utils/branch-annotation-helpers.test.js +0 -462
  125. package/lib/tests/utils/fsTestHelpers.d.ts +0 -7
  126. package/lib/tests/utils/fsTestHelpers.js +0 -26
  127. package/lib/tests/utils/ioTestHelpers.d.ts +0 -7
  128. package/lib/tests/utils/ioTestHelpers.js +0 -24
  129. package/lib/tests/utils/req-annotation-detection.test.d.ts +0 -1
  130. package/lib/tests/utils/req-annotation-detection.test.js +0 -358
  131. package/lib/tests/utils/require-story-core-test-helpers.d.ts +0 -10
  132. package/lib/tests/utils/require-story-core-test-helpers.js +0 -75
  133. package/lib/tests/utils/temp-dir-helpers.d.ts +0 -19
  134. package/lib/tests/utils/temp-dir-helpers.js +0 -62
  135. package/lib/tests/utils/ts-language-options.d.ts +0 -16
  136. package/lib/tests/utils/ts-language-options.js +0 -30
  137. /package/lib/{src/index.d.ts → index.d.ts} +0 -0
  138. /package/lib/{src/index.js → index.js} +0 -0
  139. /package/lib/{src/maintenance → maintenance}/batch.d.ts +0 -0
  140. /package/lib/{src/maintenance → maintenance}/batch.js +0 -0
  141. /package/lib/{src/maintenance → maintenance}/cli.d.ts +0 -0
  142. /package/lib/{src/maintenance → maintenance}/cli.js +0 -0
  143. /package/lib/{src/maintenance → maintenance}/commands.d.ts +0 -0
  144. /package/lib/{src/maintenance → maintenance}/commands.js +0 -0
  145. /package/lib/{src/maintenance → maintenance}/detect.d.ts +0 -0
  146. /package/lib/{src/maintenance → maintenance}/detect.js +0 -0
  147. /package/lib/{src/maintenance → maintenance}/flags.d.ts +0 -0
  148. /package/lib/{src/maintenance → maintenance}/flags.js +0 -0
  149. /package/lib/{src/maintenance → maintenance}/index.d.ts +0 -0
  150. /package/lib/{src/maintenance → maintenance}/index.js +0 -0
  151. /package/lib/{src/maintenance → maintenance}/report.d.ts +0 -0
  152. /package/lib/{src/maintenance → maintenance}/report.js +0 -0
  153. /package/lib/{src/maintenance → maintenance}/storyParser.d.ts +0 -0
  154. /package/lib/{src/maintenance → maintenance}/storyParser.js +0 -0
  155. /package/lib/{src/maintenance → maintenance}/update.d.ts +0 -0
  156. /package/lib/{src/maintenance → maintenance}/update.js +0 -0
  157. /package/lib/{src/maintenance → maintenance}/utils.d.ts +0 -0
  158. /package/lib/{src/maintenance → maintenance}/utils.js +0 -0
  159. /package/lib/{src/rules → rules}/helpers/pattern-validators.d.ts +0 -0
  160. /package/lib/{src/rules → rules}/helpers/pattern-validators.js +0 -0
  161. /package/lib/{src/rules → rules}/helpers/prefer-implements-inline.d.ts +0 -0
  162. /package/lib/{src/rules → rules}/helpers/prefer-implements-inline.js +0 -0
  163. /package/lib/{src/rules → rules}/helpers/require-story-comment-detection.d.ts +0 -0
  164. /package/lib/{src/rules → rules}/helpers/require-story-comment-detection.js +0 -0
  165. /package/lib/{src/rules → rules}/helpers/require-story-core.d.ts +0 -0
  166. /package/lib/{src/rules → rules}/helpers/require-story-core.js +0 -0
  167. /package/lib/{src/rules → rules}/helpers/require-story-helpers.d.ts +0 -0
  168. /package/lib/{src/rules → rules}/helpers/require-story-helpers.js +0 -0
  169. /package/lib/{src/rules → rules}/helpers/require-story-io.d.ts +0 -0
  170. /package/lib/{src/rules → rules}/helpers/require-story-io.js +0 -0
  171. /package/lib/{src/rules → rules}/helpers/require-story-name-extraction.d.ts +0 -0
  172. /package/lib/{src/rules → rules}/helpers/require-story-name-extraction.js +0 -0
  173. /package/lib/{src/rules → rules}/helpers/require-story-node-utils.d.ts +0 -0
  174. /package/lib/{src/rules → rules}/helpers/require-story-node-utils.js +0 -0
  175. /package/lib/{src/rules → rules}/helpers/require-story-utils.d.ts +0 -0
  176. /package/lib/{src/rules → rules}/helpers/require-story-utils.js +0 -0
  177. /package/lib/{src/rules → rules}/helpers/require-story-visitors.d.ts +0 -0
  178. /package/lib/{src/rules → rules}/helpers/require-story-visitors.js +0 -0
  179. /package/lib/{src/rules → rules}/helpers/require-test-traceability-helpers.d.ts +0 -0
  180. /package/lib/{src/rules → rules}/helpers/require-test-traceability-helpers.js +0 -0
  181. /package/lib/{src/rules → rules}/helpers/test-callback-exclusion.d.ts +0 -0
  182. /package/lib/{src/rules → rules}/helpers/test-callback-exclusion.js +0 -0
  183. /package/lib/{src/rules → rules}/helpers/valid-annotation-format-internal.d.ts +0 -0
  184. /package/lib/{src/rules → rules}/helpers/valid-annotation-format-internal.js +0 -0
  185. /package/lib/{src/rules → rules}/helpers/valid-annotation-format-validators.d.ts +0 -0
  186. /package/lib/{src/rules → rules}/helpers/valid-annotation-format-validators.js +0 -0
  187. /package/lib/{src/rules → rules}/helpers/valid-annotation-options.d.ts +0 -0
  188. /package/lib/{src/rules → rules}/helpers/valid-annotation-options.js +0 -0
  189. /package/lib/{src/rules → rules}/helpers/valid-annotation-utils.d.ts +0 -0
  190. /package/lib/{src/rules → rules}/helpers/valid-annotation-utils.js +0 -0
  191. /package/lib/{src/rules → rules}/helpers/valid-implements-utils.d.ts +0 -0
  192. /package/lib/{src/rules → rules}/helpers/valid-implements-utils.js +0 -0
  193. /package/lib/{src/rules → rules}/helpers/valid-req-reference-helpers.d.ts +0 -0
  194. /package/lib/{src/rules → rules}/helpers/valid-req-reference-helpers.js +0 -0
  195. /package/lib/{src/rules → rules}/helpers/valid-story-reference-helpers.d.ts +0 -0
  196. /package/lib/{src/rules → rules}/helpers/valid-story-reference-helpers.js +0 -0
  197. /package/lib/{src/rules → rules}/no-redundant-annotation.d.ts +0 -0
  198. /package/lib/{src/rules → rules}/no-redundant-annotation.js +0 -0
  199. /package/lib/{src/rules → rules}/prefer-implements-annotation.d.ts +0 -0
  200. /package/lib/{src/rules → rules}/prefer-implements-annotation.js +0 -0
  201. /package/lib/{src/rules → rules}/require-branch-annotation.d.ts +0 -0
  202. /package/lib/{src/rules → rules}/require-branch-annotation.js +0 -0
  203. /package/lib/{src/rules → rules}/require-req-annotation.d.ts +0 -0
  204. /package/lib/{src/rules → rules}/require-req-annotation.js +0 -0
  205. /package/lib/{src/rules → rules}/require-story-annotation.d.ts +0 -0
  206. /package/lib/{src/rules → rules}/require-story-annotation.js +0 -0
  207. /package/lib/{src/rules → rules}/require-test-traceability.d.ts +0 -0
  208. /package/lib/{src/rules → rules}/require-test-traceability.js +0 -0
  209. /package/lib/{src/rules → rules}/require-traceability.d.ts +0 -0
  210. /package/lib/{src/rules → rules}/valid-annotation-format.d.ts +0 -0
  211. /package/lib/{src/rules → rules}/valid-annotation-format.js +0 -0
  212. /package/lib/{src/rules → rules}/valid-req-reference.d.ts +0 -0
  213. /package/lib/{src/rules → rules}/valid-req-reference.js +0 -0
  214. /package/lib/{src/rules → rules}/valid-story-reference.d.ts +0 -0
  215. /package/lib/{src/rules → rules}/valid-story-reference.js +0 -0
  216. /package/lib/{src/utils → utils}/annotation-checker.d.ts +0 -0
  217. /package/lib/{src/utils → utils}/annotation-checker.js +0 -0
  218. /package/lib/{src/utils → utils}/annotation-scope-analyzer.d.ts +0 -0
  219. /package/lib/{src/utils → utils}/annotation-scope-analyzer.js +0 -0
  220. /package/lib/{src/utils → utils}/branch-annotation-catch-helpers.d.ts +0 -0
  221. /package/lib/{src/utils → utils}/branch-annotation-catch-helpers.js +0 -0
  222. /package/lib/{src/utils → utils}/branch-annotation-helpers.d.ts +0 -0
  223. /package/lib/{src/utils → utils}/branch-annotation-helpers.js +0 -0
  224. /package/lib/{src/utils → utils}/branch-annotation-if-helpers.d.ts +0 -0
  225. /package/lib/{src/utils → utils}/branch-annotation-if-helpers.js +0 -0
  226. /package/lib/{src/utils → utils}/branch-annotation-indent-helpers.d.ts +0 -0
  227. /package/lib/{src/utils → utils}/branch-annotation-indent-helpers.js +0 -0
  228. /package/lib/{src/utils → utils}/branch-annotation-loop-helpers.d.ts +0 -0
  229. /package/lib/{src/utils → utils}/branch-annotation-loop-helpers.js +0 -0
  230. /package/lib/{src/utils → utils}/branch-annotation-report-helpers.d.ts +0 -0
  231. /package/lib/{src/utils → utils}/branch-annotation-report-helpers.js +0 -0
  232. /package/lib/{src/utils → utils}/branch-annotation-story-fix-helpers.d.ts +0 -0
  233. /package/lib/{src/utils → utils}/branch-annotation-story-fix-helpers.js +0 -0
  234. /package/lib/{src/utils → utils}/branch-annotation-switch-helpers.d.ts +0 -0
  235. /package/lib/{src/utils → utils}/branch-annotation-switch-helpers.js +0 -0
  236. /package/lib/{src/utils → utils}/branch-validation.d.ts +0 -0
  237. /package/lib/{src/utils → utils}/branch-validation.js +0 -0
  238. /package/lib/{src/utils → utils}/comment-text-helpers.d.ts +0 -0
  239. /package/lib/{src/utils → utils}/comment-text-helpers.js +0 -0
  240. /package/lib/{src/utils → utils}/function-annotation-helpers.d.ts +0 -0
  241. /package/lib/{src/utils → utils}/function-annotation-helpers.js +0 -0
  242. /package/lib/{src/utils → utils}/redundancy-detector.d.ts +0 -0
  243. /package/lib/{src/utils → utils}/redundancy-detector.js +0 -0
  244. /package/lib/{src/utils → utils}/reqAnnotationDetection.d.ts +0 -0
  245. /package/lib/{src/utils → utils}/reqAnnotationDetection.js +0 -0
  246. /package/lib/{src/utils → utils}/storyReferenceUtils.d.ts +0 -0
  247. /package/lib/{src/utils → utils}/storyReferenceUtils.js +0 -0
@@ -1,129 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- /****
7
- * Tests for: docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
8
- * @story docs/stories/010.0-DEV-DEEP-VALIDATION.story.md
9
- * @req REQ-DEEP-PARSE - Verify valid-req-reference rule enforces existing requirement content
10
- *
11
- * Additional coverage for error reporting behavior:
12
- * @story docs/stories/007.0-DEV-ERROR-REPORTING.story.md
13
- * @req REQ-ERROR-SPECIFIC - Verify requirement-level errors identify the exact missing requirement
14
- * @req REQ-ERROR-CONTEXT - Verify requirement-level errors include relevant story path context
15
- * @req REQ-ERROR-CONSISTENCY - Verify requirement-level error messages are consistent across cases
16
- * @supports docs/stories/010.0-DEV-DEEP-VALIDATION.story.md REQ-DEEP-PARSE REQ-DEEP-BULLET REQ-DEEP-IMPLEMENTS REQ-DEEP-MATCH
17
- * @supports docs/stories/007.0-DEV-ERROR-REPORTING.story.md REQ-ERROR-SPECIFIC REQ-ERROR-CONTEXT REQ-ERROR-CONSISTENCY
18
- */
19
- const eslint_1 = require("eslint");
20
- const valid_req_reference_1 = __importDefault(require("../../src/rules/valid-req-reference"));
21
- const ruleTester = new eslint_1.RuleTester({
22
- languageOptions: { parserOptions: { ecmaVersion: 2020 } },
23
- });
24
- describe("Valid Req Reference Rule (Story 010.0-DEV-DEEP-VALIDATION)", () => {
25
- ruleTester.run("valid-req-reference", valid_req_reference_1.default, {
26
- valid: [
27
- {
28
- name: "[REQ-DEEP-PARSE] valid requirement reference existing in story file",
29
- code: `// @story docs/stories/001.0-DEV-PLUGIN-SETUP.story.md
30
- // @req REQ-PLUGIN-STRUCTURE`,
31
- },
32
- {
33
- name: "[REQ-DEEP-BULLET] valid bullet list requirement existing in bullet story fixture",
34
- code: `// @story tests/fixtures/story_bullet.md
35
- // @req REQ-BULLET-LIST`,
36
- },
37
- {
38
- name: "[REQ-DEEP-IMPLEMENTS] single supports line with multiple requirements in multi-story fixture (see 010.2-DEV-MULTI-STORY-SUPPORT)",
39
- code: `// @supports tests/fixtures/story_multi_a.md REQ-SHARED-ID REQ-ONLY-A`,
40
- },
41
- {
42
- name: "[REQ-DEEP-IMPLEMENTS] multi-story supports with shared requirement IDs (see 010.2-DEV-MULTI-STORY-SUPPORT)",
43
- code: `// @supports tests/fixtures/story_multi_a.md REQ-SHARED-ID REQ-ONLY-A
44
- // @supports tests/fixtures/story_multi_b.md REQ-SHARED-ID REQ-ONLY-B`,
45
- },
46
- ],
47
- invalid: [
48
- {
49
- name: "[REQ-DEEP-MATCH] missing requirement in story file",
50
- code: `// @story docs/stories/001.0-DEV-PLUGIN-SETUP.story.md
51
- // @req REQ-NON-EXISTENT`,
52
- errors: [
53
- {
54
- messageId: "reqMissing",
55
- data: {
56
- reqId: "REQ-NON-EXISTENT",
57
- storyPath: "docs/stories/001.0-DEV-PLUGIN-SETUP.story.md",
58
- },
59
- },
60
- ],
61
- },
62
- {
63
- name: "[REQ-DEEP-PARSE] disallow path traversal in story path",
64
- code: `// @story ../docs/stories/001.0-DEV-PLUGIN-SETUP.story.md
65
- // @req REQ-PLUGIN-STRUCTURE`,
66
- errors: [
67
- {
68
- messageId: "invalidPath",
69
- data: {
70
- storyPath: "../docs/stories/001.0-DEV-PLUGIN-SETUP.story.md",
71
- },
72
- },
73
- ],
74
- },
75
- {
76
- name: "[REQ-DEEP-PARSE] disallow absolute path in story path",
77
- code: `// @story /absolute/path/docs/stories/001.0-DEV-PLUGIN-SETUP.story.md
78
- // @req REQ-PLUGIN-STRUCTURE`,
79
- errors: [
80
- {
81
- messageId: "invalidPath",
82
- data: {
83
- storyPath: "/absolute/path/docs/stories/001.0-DEV-PLUGIN-SETUP.story.md",
84
- },
85
- },
86
- ],
87
- },
88
- {
89
- name: "[REQ-DEEP-BULLET] missing bullet list requirement in bullet story fixture",
90
- code: `// @story tests/fixtures/story_bullet.md
91
- // @req REQ-MISSING-BULLET`,
92
- errors: [
93
- {
94
- messageId: "reqMissing",
95
- data: {
96
- reqId: "REQ-MISSING-BULLET",
97
- storyPath: "tests/fixtures/story_bullet.md",
98
- },
99
- },
100
- ],
101
- },
102
- {
103
- name: "[REQ-DEEP-IMPLEMENTS] missing supports requirement in multi-story fixture (see 010.2-DEV-MULTI-STORY-SUPPORT)",
104
- code: `// @supports tests/fixtures/story_multi_a.md REQ-NOT-IN-A`,
105
- errors: [
106
- {
107
- messageId: "reqMissing",
108
- data: {
109
- reqId: "REQ-NOT-IN-A",
110
- storyPath: "tests/fixtures/story_multi_a.md",
111
- },
112
- },
113
- ],
114
- },
115
- {
116
- name: "[REQ-DEEP-IMPLEMENTS] disallow path traversal in supports story path (see 010.2-DEV-MULTI-STORY-SUPPORT)",
117
- code: `// @supports ../tests/fixtures/story_multi_a.md REQ-SHARED-ID`,
118
- errors: [
119
- {
120
- messageId: "invalidPath",
121
- data: {
122
- storyPath: "../tests/fixtures/story_multi_a.md",
123
- },
124
- },
125
- ],
126
- },
127
- ],
128
- });
129
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,413 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- /**
40
- * Tests for: docs/stories/006.0-DEV-FILE-VALIDATION.story.md
41
- * @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
42
- * @req REQ-FILE-EXISTENCE - Verify valid-story-reference rule enforces existing .story.md files
43
- * @story docs/stories/007.0-DEV-ERROR-REPORTING.story.md
44
- * @req REQ-ERROR-SPECIFIC - Verify file-related error messages are specific about failure causes
45
- * @req REQ-ERROR-CONTEXT - Verify file-related error messages include contextual information (path, underlying error)
46
- * @req REQ-ERROR-CONSISTENCY - Verify file-related error messages follow consistent formatting and identifiers
47
- * @req REQ-ERROR-HANDLING - Verify file-related errors are reported via diagnostics instead of uncaught exceptions
48
- * @supports docs/stories/006.0-DEV-FILE-VALIDATION.story.md REQ-FILE-EXISTENCE REQ-CONFIGURABLE-PATHS
49
- * @supports docs/stories/007.0-DEV-ERROR-REPORTING.story.md REQ-ERROR-SPECIFIC REQ-ERROR-CONTEXT REQ-ERROR-CONSISTENCY REQ-ERROR-HANDLING
50
- */
51
- const eslint_1 = require("eslint");
52
- const valid_story_reference_1 = __importDefault(require("../../src/rules/valid-story-reference"));
53
- const storyReferenceUtils_1 = require("../../src/utils/storyReferenceUtils");
54
- const path = __importStar(require("path"));
55
- const fsTestHelpers_1 = require("../utils/fsTestHelpers");
56
- const ruleTester = new eslint_1.RuleTester({
57
- languageOptions: { parserOptions: { ecmaVersion: 2020 } },
58
- });
59
- describe("Valid Story Reference Rule (Story 006.0-DEV-FILE-VALIDATION)", () => {
60
- ruleTester.run("valid-story-reference", valid_story_reference_1.default, {
61
- valid: [
62
- {
63
- name: "[REQ-FILE-EXISTENCE] valid story file reference",
64
- code: `// @story docs/stories/001.0-DEV-PLUGIN-SETUP.story.md`,
65
- },
66
- {
67
- name: "[REQ-EXTENSION] valid .story.md extension",
68
- code: `// @story docs/stories/002.0-DEV-ESLINT-CONFIG.story.md`,
69
- },
70
- {
71
- name: "[REQ-PATH-RESOLUTION] valid relative path with ./ prefix",
72
- code: `// @story ./docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md`,
73
- },
74
- ],
75
- invalid: [
76
- {
77
- name: "[REQ-PATH-RESOLUTION] missing file",
78
- code: `// @story docs/stories/missing-file.story.md`,
79
- errors: [
80
- {
81
- messageId: "fileMissing",
82
- data: { path: "docs/stories/missing-file.story.md" },
83
- },
84
- ],
85
- },
86
- {
87
- name: "[REQ-EXTENSION] invalid extension",
88
- code: `// @story docs/stories/001.0-DEV-PLUGIN-SETUP.md`,
89
- errors: [
90
- {
91
- messageId: "invalidExtension",
92
- data: { path: "docs/stories/001.0-DEV-PLUGIN-SETUP.md" },
93
- },
94
- ],
95
- },
96
- {
97
- name: "[REQ-PATH-SECURITY] path traversal",
98
- code: `// @story ../outside.story.md`,
99
- errors: [
100
- { messageId: "invalidPath", data: { path: "../outside.story.md" } },
101
- ],
102
- },
103
- {
104
- name: "[REQ-ABSOLUTE-PATH] absolute path not allowed",
105
- code: `// @story /etc/passwd.story.md`,
106
- errors: [
107
- { messageId: "invalidPath", data: { path: "/etc/passwd.story.md" } },
108
- ],
109
- },
110
- ],
111
- });
112
- });
113
- // @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
114
- // @req REQ-CONFIGURABLE-PATHS - Verify custom storyDirectories behavior
115
- const configurablePathsTester = new eslint_1.RuleTester({
116
- languageOptions: { parserOptions: { ecmaVersion: 2020 } },
117
- });
118
- configurablePathsTester.run("valid-story-reference", valid_story_reference_1.default, {
119
- valid: [
120
- {
121
- name: "[REQ-CONFIGURABLE-PATHS] honors custom storyDirectories using docs/stories",
122
- code: `// @story 001.0-DEV-PLUGIN-SETUP.story.md\n// @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md`,
123
- options: [{ storyDirectories: ["docs/stories"] }],
124
- },
125
- ],
126
- invalid: [],
127
- });
128
- // @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
129
- // @req REQ-CONFIGURABLE-PATHS - Verify allowAbsolutePaths behavior
130
- const allowAbsolutePathsTester = new eslint_1.RuleTester({
131
- languageOptions: { parserOptions: { ecmaVersion: 2020 } },
132
- });
133
- const absoluteStoryPath = path.resolve(process.cwd(), "docs/stories/001.0-DEV-PLUGIN-SETUP.story.md");
134
- allowAbsolutePathsTester.run("valid-story-reference", valid_story_reference_1.default, {
135
- valid: [
136
- {
137
- name: "[REQ-CONFIGURABLE-PATHS] allowAbsolutePaths accepts existing absolute .story.md inside project",
138
- code: `// @story ${absoluteStoryPath}\n// @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md`,
139
- options: [
140
- {
141
- allowAbsolutePaths: true,
142
- storyDirectories: ["docs/stories"],
143
- },
144
- ],
145
- },
146
- ],
147
- invalid: [
148
- {
149
- name: "[REQ-CONFIGURABLE-PATHS] disallows absolute paths when allowAbsolutePaths is false",
150
- code: `// @story ${absoluteStoryPath}\n// @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md`,
151
- options: [
152
- {
153
- allowAbsolutePaths: false,
154
- storyDirectories: ["docs/stories"],
155
- },
156
- ],
157
- errors: [
158
- {
159
- messageId: "invalidPath",
160
- },
161
- ],
162
- },
163
- ],
164
- });
165
- // @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
166
- // @req REQ-CONFIGURABLE-PATHS - Verify requireStoryExtension behavior
167
- const relaxedExtensionTester = new eslint_1.RuleTester({
168
- languageOptions: { parserOptions: { ecmaVersion: 2020 } },
169
- });
170
- relaxedExtensionTester.run("valid-story-reference", valid_story_reference_1.default, {
171
- valid: [
172
- {
173
- name: "[REQ-CONFIGURABLE-PATHS] accepts .story.md story path when requireStoryExtension is false (still valid and existing)",
174
- code: `// @story docs/stories/001.0-DEV-PLUGIN-SETUP.story.md\n// @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md`,
175
- options: [
176
- {
177
- storyDirectories: ["docs/stories"],
178
- requireStoryExtension: false,
179
- },
180
- ],
181
- },
182
- ],
183
- invalid: [],
184
- });
185
- // @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
186
- // @req REQ-PROJECT-BOUNDARY - Verify project boundary handling
187
- const projectBoundaryTester = new eslint_1.RuleTester({
188
- languageOptions: { parserOptions: { ecmaVersion: 2020 } },
189
- });
190
- projectBoundaryTester.run("valid-story-reference", valid_story_reference_1.default, {
191
- valid: [],
192
- invalid: [
193
- {
194
- name: "[REQ-PROJECT-BOUNDARY] story reference outside project root is rejected when discovered via absolute path",
195
- code: `// @story ${path.resolve(path.sep, "outside-project", "001.0-DEV-PLUGIN-SETUP.story.md")}\n// @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md`,
196
- options: [
197
- {
198
- allowAbsolutePaths: true,
199
- storyDirectories: [path.resolve(path.sep, "outside-project")],
200
- },
201
- ],
202
- errors: [
203
- {
204
- messageId: "invalidPath",
205
- },
206
- ],
207
- },
208
- ],
209
- });
210
- describe("Valid Story Reference Rule Configuration and Boundaries (Story 006.0-DEV-FILE-VALIDATION)", () => {
211
- const fs = require("fs");
212
- const pathModule = require("path");
213
- let tempDirs = [];
214
- afterEach(() => {
215
- for (const dir of tempDirs) {
216
- try {
217
- fs.rmSync(dir, { recursive: true, force: true });
218
- }
219
- catch {
220
- // ignore cleanup errors
221
- }
222
- }
223
- tempDirs = [];
224
- (0, storyReferenceUtils_1.__resetStoryExistenceCacheForTests)();
225
- jest.restoreAllMocks();
226
- });
227
- it("[REQ-CONFIGURABLE-PATHS] uses storyDirectories when resolving relative paths (Story 006.0-DEV-FILE-VALIDATION)", () => {
228
- const storyPath = pathModule.join(process.cwd(), "docs/stories/001.0-DEV-PLUGIN-SETUP.story.md");
229
- (0, fsTestHelpers_1.mockFsForExistingFile)(fs, storyPath);
230
- const diagnostics = runRuleOnCode(`// @story 001.0-DEV-PLUGIN-SETUP.story.md`, [{ storyDirectories: ["docs/stories"] }]);
231
- // When storyDirectories is configured, the underlying resolution should
232
- // treat the path as valid; absence of errors is asserted via RuleTester
233
- // above. Here we just ensure no crash path via storyExists cache reset.
234
- expect(Array.isArray(diagnostics)).toBe(true);
235
- });
236
- it("[REQ-CONFIGURABLE-PATHS] allowAbsolutePaths permits absolute paths inside project when enabled (Story 006.0-DEV-FILE-VALIDATION)", () => {
237
- const absPath = pathModule.resolve(process.cwd(), "docs/stories/001.0-DEV-PLUGIN-SETUP.story.md");
238
- const diagnostics = runRuleOnCode(`// @story ${absPath}`, [
239
- {
240
- allowAbsolutePaths: true,
241
- storyDirectories: ["docs/stories"],
242
- },
243
- ]);
244
- // Detailed behavior is verified by RuleTester above; this Jest test
245
- // ensures helper path construction does not throw and diagnostics are collected.
246
- expect(Array.isArray(diagnostics)).toBe(true);
247
- });
248
- it("[REQ-PROJECT-BOUNDARY] storyDirectories cannot escape project even when normalize resolves outside cwd (Story 006.0-DEV-FILE-VALIDATION)", () => {
249
- const ruleModule = require("../../src/rules/valid-story-reference");
250
- const originalCreate = ruleModule.default.create || ruleModule.create;
251
- // Spy on create to intercept normalizeStoryPath behavior indirectly if needed
252
- expect(typeof originalCreate).toBe("function");
253
- const diagnostics = runRuleOnCode(`// @story ../outside-boundary.story.md\n// @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md`);
254
- // Behavior of reporting invalidPath for outside project is ensured
255
- // in RuleTester projectBoundaryTester above; here ensure diagnostics collected.
256
- expect(Array.isArray(diagnostics)).toBe(true);
257
- });
258
- /**
259
- * @req REQ-PROJECT-BOUNDARY - Verify misconfigured storyDirectories pointing outside
260
- * the project cannot cause external files to be treated as valid, and invalidPath is reported.
261
- * @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
262
- */
263
- it("[REQ-PROJECT-BOUNDARY] misconfigured storyDirectories outside project cannot validate external files", () => {
264
- const fs = require("fs");
265
- const pathModule = require("path");
266
- const outsideDir = pathModule.resolve(pathModule.sep, "tmp", "outside");
267
- const outsideFile = pathModule.join(outsideDir, "external-story.story.md");
268
- (0, fsTestHelpers_1.mockFsForExistingFile)(fs, outsideFile);
269
- const diagnostics = runRuleOnCode(`// @story ${outsideFile}\n// @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md`, [
270
- {
271
- allowAbsolutePaths: true,
272
- storyDirectories: [outsideDir],
273
- },
274
- ]);
275
- expect(Array.isArray(diagnostics)).toBe(true);
276
- const invalidPathDiagnostics = diagnostics.filter((d) => d.messageId === "invalidPath");
277
- expect(invalidPathDiagnostics.length).toBeGreaterThan(0);
278
- });
279
- /**
280
- * @req REQ-CONFIGURABLE-PATHS - Verify requireStoryExtension: false allows .md story
281
- * files that do not end with .story.md when they exist in storyDirectories.
282
- * @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
283
- */
284
- it("[REQ-CONFIGURABLE-PATHS] requireStoryExtension=false accepts existing .md story file", () => {
285
- const fs = require("fs");
286
- const pathModule = require("path");
287
- const storyPath = pathModule.join(process.cwd(), "docs/stories/developer-story.map.md");
288
- (0, fsTestHelpers_1.mockFsForExistingFile)(fs, storyPath);
289
- const diagnostics = runRuleOnCode(`// @story docs/stories/developer-story.map.md\n// @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md`, [
290
- {
291
- storyDirectories: ["docs/stories"],
292
- requireStoryExtension: false,
293
- },
294
- ]);
295
- expect(Array.isArray(diagnostics)).toBe(true);
296
- const invalidExtensionDiagnostics = diagnostics.filter((d) => d.messageId === "invalidExtension");
297
- expect(invalidExtensionDiagnostics.length).toBe(0);
298
- });
299
- });
300
- /**
301
- * Helper to run the valid-story-reference rule against a single source string
302
- * and collect reported diagnostics.
303
- *
304
- * @req REQ-ERROR-HANDLING - Used to verify fileAccessError reporting behavior
305
- * @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
306
- */
307
- function runRuleOnCode(code, options = []) {
308
- const messages = [];
309
- const context = {
310
- report: (descriptor) => {
311
- messages.push(descriptor);
312
- },
313
- getSourceCode: () => ({
314
- text: code,
315
- getAllComments: () => [
316
- {
317
- type: "Line",
318
- value: code.replace(/^\/\//, "").trim(),
319
- },
320
- ],
321
- }),
322
- options,
323
- parserOptions: { ecmaVersion: 2020 },
324
- };
325
- const listeners = valid_story_reference_1.default.create(context);
326
- if (typeof listeners.Program === "function") {
327
- listeners.Program({});
328
- }
329
- return messages;
330
- }
331
- describe("Valid Story Reference Rule Error Handling (Story 006.0-DEV-FILE-VALIDATION)", () => {
332
- /**
333
- * @req REQ-ERROR-HANDLING - Verify storyExists swallows fs errors and returns false
334
- * instead of throwing when filesystem operations fail.
335
- * @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
336
- */
337
- const fs = require("fs");
338
- afterEach(() => {
339
- jest.restoreAllMocks();
340
- });
341
- it("[REQ-ERROR-HANDLING] storyExists returns false when fs throws", () => {
342
- jest.spyOn(fs, "existsSync").mockImplementation(() => {
343
- const err = new Error("EACCES: permission denied");
344
- err.code = "EACCES";
345
- throw err;
346
- });
347
- jest.spyOn(fs, "statSync").mockImplementation(() => {
348
- const err = new Error("EACCES: permission denied");
349
- err.code = "EACCES";
350
- throw err;
351
- });
352
- expect(() => (0, storyReferenceUtils_1.storyExists)(["docs/stories/permission-denied.story.md"])).not.toThrow();
353
- expect((0, storyReferenceUtils_1.storyExists)(["docs/stories/permission-denied.story.md"])).toBe(false);
354
- });
355
- /**
356
- * @req REQ-ERROR-HANDLING - Verify storyExists handles EIO from fs.statSync
357
- * by returning false and not throwing when fs.existsSync returns true.
358
- * @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
359
- */
360
- it("[REQ-ERROR-HANDLING] storyExists returns false when fs.statSync throws EIO and existsSync is true", () => {
361
- jest.spyOn(fs, "existsSync").mockImplementation(() => true);
362
- jest.spyOn(fs, "statSync").mockImplementation(() => {
363
- const err = new Error("EIO: i/o error while reading file");
364
- err.code = "EIO";
365
- throw err;
366
- });
367
- expect(() => (0, storyReferenceUtils_1.storyExists)(["docs/stories/io-error.story.md"])).not.toThrow();
368
- expect((0, storyReferenceUtils_1.storyExists)(["docs/stories/io-error.story.md"])).toBe(false);
369
- });
370
- /**
371
- * @req REQ-ERROR-HANDLING - Verify rule reports fileAccessError when fs.statSync throws
372
- * and fs.existsSync returns true, treating it as a filesystem access problem
373
- * rather than a missing file.
374
- * @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
375
- */
376
- it("[REQ-ERROR-HANDLING] rule reports fileAccessError when fs.statSync throws and existsSync is true", () => {
377
- const accessError = new Error("EIO: i/o error while reading file metadata");
378
- accessError.code = "EIO";
379
- jest.spyOn(fs, "existsSync").mockImplementation(() => true);
380
- jest.spyOn(fs, "statSync").mockImplementation(() => {
381
- throw accessError;
382
- });
383
- const diagnostics = runRuleOnCode(`// @story docs/stories/fs-stat-io-error.story.md`);
384
- expect(diagnostics.length).toBeGreaterThan(0);
385
- const fileAccessDiagnostics = diagnostics.filter((d) => d.messageId === "fileAccessError");
386
- expect(fileAccessDiagnostics.length).toBeGreaterThan(0);
387
- const errorData = fileAccessDiagnostics[0].data;
388
- expect(errorData).toBeDefined();
389
- expect(String(errorData.error)).toMatch(/EIO/i);
390
- });
391
- /**
392
- * @req REQ-ERROR-HANDLING - Verify rule reports fileAccessError when filesystem operations fail
393
- * instead of treating it as a missing file.
394
- * @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
395
- */
396
- it("[REQ-ERROR-HANDLING] rule reports fileAccessError when fs throws", () => {
397
- const accessError = new Error("EACCES: permission denied while accessing");
398
- accessError.code = "EACCES";
399
- jest.spyOn(fs, "existsSync").mockImplementation(() => {
400
- throw accessError;
401
- });
402
- jest.spyOn(fs, "statSync").mockImplementation(() => {
403
- throw accessError;
404
- });
405
- const diagnostics = runRuleOnCode(`// @story docs/stories/fs-error.story.md`);
406
- expect(diagnostics.length).toBeGreaterThan(0);
407
- const fileAccessDiagnostics = diagnostics.filter((d) => d.messageId === "fileAccessError");
408
- expect(fileAccessDiagnostics.length).toBeGreaterThan(0);
409
- const errorData = fileAccessDiagnostics[0].data;
410
- expect(errorData).toBeDefined();
411
- expect(String(errorData.error)).toMatch(/EACCES/i);
412
- });
413
- });
@@ -1,5 +0,0 @@
1
- /**
2
- * Focused autofix behavior tests for annotation-checker helper.
3
- * @supports docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md REQ-ANNOTATION-AUTOFIX REQ-ANNOTATION-REPORTING
4
- */
5
- export {};
@@ -1,103 +0,0 @@
1
- "use strict";
2
- /**
3
- * Focused autofix behavior tests for annotation-checker helper.
4
- * @supports docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md REQ-ANNOTATION-AUTOFIX REQ-ANNOTATION-REPORTING
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- jest.mock("../../src/utils/reqAnnotationDetection", () => ({
8
- // Always report that no requirement annotation is present so we exercise
9
- // the missing-annotation reporting and autofix paths in the helper.
10
- hasReqAnnotation: jest.fn(() => false),
11
- }));
12
- jest.mock("../../src/rules/helpers/require-story-utils", () => ({
13
- // Provide a stable, human-readable name so reporting paths are predictable
14
- // without depending on the full real implementation.
15
- getNodeName: jest.fn(() => "mockName"),
16
- }));
17
- const annotation_checker_1 = require("../../src/utils/annotation-checker");
18
- /**
19
- * Build a minimal ESLint rule context stub that captures report() calls.
20
- *
21
- * @supports docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md REQ-ANNOTATION-REPORTING
22
- */
23
- function createContextStub() {
24
- const report = jest.fn();
25
- const sourceCode = {
26
- getJSDocComment: jest.fn(() => null),
27
- getCommentsBefore: jest.fn(() => []),
28
- };
29
- const context = {
30
- getSourceCode() {
31
- return sourceCode;
32
- },
33
- report,
34
- };
35
- return { context, report };
36
- }
37
- describe("annotation-checker helper autofix behavior (Story 003.0-DEV-FUNCTION-ANNOTATIONS)", () => {
38
- it("[REQ-ANNOTATION-AUTOFIX] attaches fix directly to node when parent is missing", () => {
39
- const { context, report } = createContextStub();
40
- const node = { type: "FunctionDeclaration" }; // no parent property
41
- (0, annotation_checker_1.checkReqAnnotation)(context, node, { enableFix: true });
42
- expect(report).toHaveBeenCalledTimes(1);
43
- const reportArg = report.mock.calls[0][0];
44
- expect(reportArg).toHaveProperty("fix");
45
- const fixer = { insertTextBefore: jest.fn() };
46
- reportArg.fix(fixer);
47
- expect(fixer.insertTextBefore).toHaveBeenCalledWith(node, "/** @req <REQ-ID> */\n");
48
- });
49
- it("[REQ-ANNOTATION-AUTOFIX] attaches fix to MethodDefinition wrapper when parent is a method", () => {
50
- const { context, report } = createContextStub();
51
- const methodParent = { type: "MethodDefinition" };
52
- const node = {
53
- type: "FunctionExpression",
54
- parent: methodParent,
55
- id: { type: "Identifier", name: "methodImpl" },
56
- };
57
- (0, annotation_checker_1.checkReqAnnotation)(context, node, { enableFix: true });
58
- expect(report).toHaveBeenCalledTimes(1);
59
- const reportArg = report.mock.calls[0][0];
60
- const fixer = { insertTextBefore: jest.fn() };
61
- reportArg.fix(fixer);
62
- expect(fixer.insertTextBefore).toHaveBeenCalledWith(methodParent, "/** @req <REQ-ID> */\n");
63
- });
64
- it("[REQ-ANNOTATION-AUTOFIX] attaches fix to VariableDeclarator when node is its init", () => {
65
- const { context, report } = createContextStub();
66
- const declarator = { type: "VariableDeclarator" };
67
- const node = { type: "FunctionExpression", parent: declarator };
68
- declarator.init = node;
69
- (0, annotation_checker_1.checkReqAnnotation)(context, node, { enableFix: true });
70
- expect(report).toHaveBeenCalledTimes(1);
71
- const reportArg = report.mock.calls[0][0];
72
- const fixer = { insertTextBefore: jest.fn() };
73
- reportArg.fix(fixer);
74
- expect(fixer.insertTextBefore).toHaveBeenCalledWith(declarator, "/** @req <REQ-ID> */\n");
75
- });
76
- it("[REQ-ANNOTATION-AUTOFIX] attaches fix to ExpressionStatement wrapper when parent is an expression", () => {
77
- const { context, report } = createContextStub();
78
- const expressionParent = { type: "ExpressionStatement" };
79
- const node = {
80
- type: "FunctionExpression",
81
- parent: expressionParent,
82
- id: { type: "Identifier", name: "iife" },
83
- };
84
- (0, annotation_checker_1.checkReqAnnotation)(context, node, { enableFix: true });
85
- expect(report).toHaveBeenCalledTimes(1);
86
- const reportArg = report.mock.calls[0][0];
87
- const fixer = { insertTextBefore: jest.fn() };
88
- reportArg.fix(fixer);
89
- expect(fixer.insertTextBefore).toHaveBeenCalledWith(expressionParent, "/** @req <REQ-ID> */\n");
90
- });
91
- it("[REQ-ANNOTATION-AUTOFIX] omits fix when enableFix is false", () => {
92
- const { context, report } = createContextStub();
93
- const node = {
94
- type: "FunctionDeclaration",
95
- parent: { type: "Program" },
96
- id: { type: "Identifier", name: "noFix" },
97
- };
98
- (0, annotation_checker_1.checkReqAnnotation)(context, node, { enableFix: false });
99
- expect(report).toHaveBeenCalledTimes(1);
100
- const reportArg = report.mock.calls[0][0];
101
- expect(reportArg.fix).toBeUndefined();
102
- });
103
- });