eslint-plugin-traceability 1.8.0 → 1.8.2
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 +5 -5
- package/README.md +28 -29
- package/SECURITY.md +135 -0
- package/lib/src/index.d.ts +6 -35
- package/lib/src/index.js +8 -5
- package/lib/src/maintenance/cli.js +12 -16
- package/lib/src/maintenance/detect.js +28 -1
- package/lib/src/rules/helpers/require-story-io.d.ts +2 -2
- package/lib/src/rules/helpers/require-story-io.js +13 -13
- package/lib/src/rules/helpers/valid-annotation-format-internal.d.ts +2 -2
- package/lib/src/rules/helpers/valid-annotation-format-internal.js +3 -3
- package/lib/src/rules/helpers/valid-annotation-utils.d.ts +5 -0
- package/lib/src/rules/helpers/valid-annotation-utils.js +43 -5
- package/lib/src/rules/helpers/valid-implements-utils.d.ts +11 -11
- package/lib/src/rules/helpers/valid-implements-utils.js +11 -11
- package/lib/src/rules/helpers/valid-story-reference-helpers.js +19 -0
- package/lib/src/rules/prefer-implements-annotation.d.ts +7 -7
- package/lib/src/rules/prefer-implements-annotation.js +21 -21
- package/lib/src/rules/valid-annotation-format.js +50 -24
- package/lib/src/rules/valid-req-reference.js +9 -9
- package/lib/src/utils/annotation-checker.js +3 -1
- package/lib/src/utils/reqAnnotationDetection.d.ts +2 -2
- package/lib/src/utils/reqAnnotationDetection.js +28 -28
- package/lib/tests/config/flat-config-presets-integration.test.d.ts +1 -0
- package/lib/tests/config/flat-config-presets-integration.test.js +75 -0
- package/lib/tests/maintenance/batch.test.js +11 -11
- package/lib/tests/maintenance/cli.test.js +34 -27
- package/lib/tests/maintenance/report.test.js +7 -7
- package/lib/tests/plugin-default-export-and-configs.test.js +0 -2
- package/lib/tests/rules/prefer-implements-annotation.test.js +48 -15
- package/lib/tests/rules/require-branch-annotation.test.js +15 -36
- package/lib/tests/rules/require-req-annotation.test.js +31 -104
- package/lib/tests/rules/require-story-annotation.test.js +3 -3
- package/lib/tests/rules/require-story-io-behavior.test.js +2 -7
- package/lib/tests/rules/require-story-io.edgecases.test.js +2 -7
- package/lib/tests/rules/require-story-visitors-edgecases.test.js +8 -8
- package/lib/tests/rules/valid-annotation-format.test.js +23 -23
- package/lib/tests/rules/valid-req-reference.test.js +9 -9
- package/lib/tests/rules/valid-story-reference.test.js +4 -43
- package/lib/tests/utils/annotation-checker.test.js +2 -6
- package/lib/tests/utils/fsTestHelpers.d.ts +7 -0
- package/lib/tests/utils/fsTestHelpers.js +26 -0
- package/lib/tests/utils/ioTestHelpers.d.ts +7 -0
- package/lib/tests/utils/ioTestHelpers.js +24 -0
- package/lib/tests/utils/temp-dir-helpers.d.ts +14 -0
- package/lib/tests/utils/temp-dir-helpers.js +61 -0
- package/package.json +8 -7
- package/user-docs/api-reference.md +37 -20
- package/user-docs/eslint-9-setup-guide.md +89 -6
- package/user-docs/migration-guide.md +37 -21
- package/docs/ci-cd-pipeline.md +0 -224
- package/docs/cli-integration.md +0 -22
- package/docs/code-quality-refactor-opportunities-2025-12-03.md +0 -78
- package/docs/config-presets.md +0 -38
- package/docs/conventional-commits-guide.md +0 -185
- package/docs/custom-rules-development-guide.md +0 -659
- package/docs/decisions/0001-allow-dynamic-require-for-built-plugins.md +0 -26
- package/docs/decisions/001-typescript-for-eslint-plugin.accepted.md +0 -111
- package/docs/decisions/002-jest-for-eslint-testing.accepted.md +0 -137
- package/docs/decisions/003-code-quality-ratcheting-plan.md +0 -48
- package/docs/decisions/004-automated-version-bumping-for-ci-cd.md +0 -196
- package/docs/decisions/005-github-actions-validation-tooling.accepted.md +0 -144
- package/docs/decisions/006-semantic-release-for-automated-publishing.accepted.md +0 -227
- package/docs/decisions/007-github-releases-over-changelog.accepted.md +0 -216
- package/docs/decisions/008-ci-audit-flags.accepted.md +0 -60
- package/docs/decisions/009-security-focused-lint-rules.accepted.md +0 -64
- package/docs/decisions/010-implements-annotation-for-multi-story-requirements.proposed.md +0 -184
- package/docs/decisions/adr-0001-console-usage-for-cli-guards.md +0 -190
- package/docs/decisions/adr-accept-dev-dep-risk-glob.md +0 -40
- package/docs/decisions/adr-commit-branch-tests.md +0 -54
- package/docs/decisions/adr-maintenance-cli-interface.md +0 -140
- package/docs/decisions/adr-pre-push-parity.md +0 -112
- package/docs/decisions/code-quality-ratcheting-plan.md +0 -53
- package/docs/dependency-health.md +0 -238
- package/docs/eslint-9-setup-guide.md +0 -517
- package/docs/eslint-plugin-development-guide.md +0 -487
- package/docs/functionality-coverage-2025-12-03.md +0 -250
- package/docs/jest-testing-guide.md +0 -100
- package/docs/rules/prefer-implements-annotation.md +0 -219
- package/docs/rules/require-branch-annotation.md +0 -71
- package/docs/rules/require-req-annotation.md +0 -203
- package/docs/rules/require-story-annotation.md +0 -159
- package/docs/rules/valid-annotation-format.md +0 -418
- package/docs/rules/valid-req-reference.md +0 -153
- package/docs/rules/valid-story-reference.md +0 -120
- package/docs/security-incidents/2025-11-17-glob-cli-incident.md +0 -45
- package/docs/security-incidents/2025-11-18-brace-expansion-redos.md +0 -45
- package/docs/security-incidents/2025-11-18-bundled-dev-deps-accepted-risk.md +0 -93
- package/docs/security-incidents/2025-11-18-tar-race-condition.md +0 -43
- package/docs/security-incidents/2025-12-03-dependency-health-review.md +0 -58
- package/docs/security-incidents/SECURITY-INCIDENT-2025-11-18-semantic-release-bundled-npm.known-error.md +0 -104
- package/docs/security-incidents/SECURITY-INCIDENT-TEMPLATE.md +0 -37
- package/docs/security-incidents/dependency-override-rationale.md +0 -57
- package/docs/security-incidents/dev-deps-high.json +0 -116
- package/docs/security-incidents/handling-procedure.md +0 -54
- package/docs/stories/001.0-DEV-PLUGIN-SETUP.story.md +0 -92
- package/docs/stories/002.0-DEV-ESLINT-CONFIG.story.md +0 -82
- package/docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md +0 -112
- package/docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md +0 -153
- package/docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md +0 -138
- package/docs/stories/006.0-DEV-FILE-VALIDATION.story.md +0 -144
- package/docs/stories/007.0-DEV-ERROR-REPORTING.story.md +0 -163
- package/docs/stories/008.0-DEV-AUTO-FIX.story.md +0 -150
- package/docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md +0 -117
- package/docs/stories/010.0-DEV-DEEP-VALIDATION.story.md +0 -124
- package/docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md +0 -149
- package/docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md +0 -216
- package/docs/stories/010.3-DEV-MIGRATE-TO-IMPLEMENTS.story.md +0 -236
- package/docs/stories/developer-story.map.md +0 -120
- package/docs/ts-jest-presets-guide.md +0 -548
|
@@ -38,12 +38,16 @@ function createStoryFix(context, comment, fixed) {
|
|
|
38
38
|
const commentText = sourceCode.getText(comment);
|
|
39
39
|
const search = "@story";
|
|
40
40
|
const tagIndex = commentText.indexOf(search);
|
|
41
|
+
// @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
42
|
+
// @req REQ-AUTOFIX-SAFE - Skip auto-fix when @story tag cannot be reliably located
|
|
41
43
|
if (tagIndex === valid_annotation_utils_1.TAG_NOT_FOUND_INDEX) {
|
|
42
44
|
return null;
|
|
43
45
|
}
|
|
44
46
|
const afterTagIndex = tagIndex + search.length;
|
|
45
47
|
const rest = commentText.slice(afterTagIndex);
|
|
46
48
|
const valueMatch = rest.match(/[^\S\r\n]*([^\r\n*]+)/);
|
|
49
|
+
// @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
50
|
+
// @req REQ-AUTOFIX-SAFE - Abort auto-fix when story value range cannot be safely determined
|
|
47
51
|
if (!valueMatch || valueMatch.index === undefined) {
|
|
48
52
|
return null;
|
|
49
53
|
}
|
|
@@ -79,6 +83,8 @@ function createStoryFix(context, comment, fixed) {
|
|
|
79
83
|
*/
|
|
80
84
|
function reportInvalidStoryFormatWithFix(context, comment, collapsed, fixed) {
|
|
81
85
|
const fixFactory = createStoryFix(context, comment, fixed);
|
|
86
|
+
// @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
87
|
+
// @req REQ-AUTOFIX-SAFE - Fall back to reporting without fix when safe fix cannot be created
|
|
82
88
|
if (!fixFactory) {
|
|
83
89
|
reportInvalidStoryFormat(context, comment, collapsed, (0, valid_annotation_options_1.getResolvedDefaults)());
|
|
84
90
|
return;
|
|
@@ -108,6 +114,8 @@ function reportInvalidStoryFormatWithFix(context, comment, collapsed, fixed) {
|
|
|
108
114
|
*/
|
|
109
115
|
function validateStoryAnnotation(context, comment, rawValue, options) {
|
|
110
116
|
const trimmed = rawValue.trim();
|
|
117
|
+
// @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
118
|
+
// @req REQ-PATH-FORMAT - Treat missing @story value as a specific validation error
|
|
111
119
|
if (!trimmed) {
|
|
112
120
|
context.report({
|
|
113
121
|
node: comment,
|
|
@@ -118,14 +126,20 @@ function validateStoryAnnotation(context, comment, rawValue, options) {
|
|
|
118
126
|
}
|
|
119
127
|
const collapsed = (0, valid_annotation_utils_1.collapseAnnotationValue)(trimmed);
|
|
120
128
|
const pathPattern = options.storyPattern;
|
|
129
|
+
// @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
130
|
+
// @req REQ-PATH-FORMAT - Accept @story value when it matches configured storyPattern
|
|
121
131
|
if (pathPattern.test(collapsed)) {
|
|
122
132
|
return;
|
|
123
133
|
}
|
|
134
|
+
// @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
135
|
+
// @req REQ-PATH-FORMAT - Reject @story values containing internal whitespace as invalid
|
|
124
136
|
if (/\s/.test(trimmed)) {
|
|
125
137
|
reportInvalidStoryFormat(context, comment, collapsed, options);
|
|
126
138
|
return;
|
|
127
139
|
}
|
|
128
140
|
const fixed = (0, valid_annotation_utils_1.getFixedStoryPath)(collapsed);
|
|
141
|
+
// @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
142
|
+
// @req REQ-AUTOFIX-FORMAT - Apply suffix-only auto-fix when it yields a pattern-compliant path
|
|
129
143
|
if (fixed && pathPattern.test(fixed)) {
|
|
130
144
|
reportInvalidStoryFormatWithFix(context, comment, collapsed, fixed);
|
|
131
145
|
return;
|
|
@@ -146,6 +160,8 @@ function validateStoryAnnotation(context, comment, rawValue, options) {
|
|
|
146
160
|
*/
|
|
147
161
|
function validateReqAnnotation(context, comment, rawValue, options) {
|
|
148
162
|
const trimmed = rawValue.trim();
|
|
163
|
+
// @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
164
|
+
// @req REQ-REQ-FORMAT - Treat missing @req value as a specific validation error
|
|
149
165
|
if (!trimmed) {
|
|
150
166
|
context.report({
|
|
151
167
|
node: comment,
|
|
@@ -156,6 +172,8 @@ function validateReqAnnotation(context, comment, rawValue, options) {
|
|
|
156
172
|
}
|
|
157
173
|
const collapsed = (0, valid_annotation_utils_1.collapseAnnotationValue)(trimmed);
|
|
158
174
|
const reqPattern = options.reqPattern;
|
|
175
|
+
// @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
176
|
+
// @req REQ-REQ-FORMAT - Flag @req identifiers that do not match the configured pattern
|
|
159
177
|
if (!reqPattern.test(collapsed)) {
|
|
160
178
|
context.report({
|
|
161
179
|
node: comment,
|
|
@@ -165,10 +183,10 @@ function validateReqAnnotation(context, comment, rawValue, options) {
|
|
|
165
183
|
}
|
|
166
184
|
}
|
|
167
185
|
/**
|
|
168
|
-
* Validate an @
|
|
186
|
+
* Validate an @supports annotation value and report detailed errors when needed.
|
|
169
187
|
*
|
|
170
188
|
* Expected format:
|
|
171
|
-
* @
|
|
189
|
+
* @supports <storyPath> <REQ-ID> [<REQ-ID> ...]
|
|
172
190
|
*
|
|
173
191
|
* Validation rules:
|
|
174
192
|
* - Value must include at least a story path and one requirement ID.
|
|
@@ -179,7 +197,7 @@ function validateReqAnnotation(context, comment, rawValue, options) {
|
|
|
179
197
|
* requirement ID issues reuse the existing "invalidReqFormat" message.
|
|
180
198
|
*
|
|
181
199
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
182
|
-
* @req REQ-
|
|
200
|
+
* @req REQ-SUPPORTS-PARSE - Parse @supports annotations without affecting @story/@req
|
|
183
201
|
* @req REQ-FORMAT-VALIDATION - Validate @implements story path and requirement IDs
|
|
184
202
|
* @req REQ-MIXED-SUPPORT - Support mixed @story/@req/@implements usage in comments
|
|
185
203
|
*/
|
|
@@ -207,15 +225,15 @@ function validateImplementsAnnotation(context, comment, rawValue, options) {
|
|
|
207
225
|
* @req REQ-MIXED-SUPPORT - Support mixed @story/@req/@implements usage in comments
|
|
208
226
|
*/
|
|
209
227
|
function finalizePendingAnnotation(context, comment, options, pending) {
|
|
228
|
+
// @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
229
|
+
// @req REQ-MULTILINE-SUPPORT - Do nothing when there is no pending multi-line annotation to finalize
|
|
210
230
|
if (!pending) {
|
|
211
231
|
return null;
|
|
212
232
|
}
|
|
213
233
|
// @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
214
|
-
// @
|
|
215
|
-
// @
|
|
216
|
-
// @req REQ-
|
|
217
|
-
// @req REQ-AUTOFIX-FORMAT - Provide safe, minimal automatic fixes for common format issues
|
|
218
|
-
// @req REQ-MIXED-SUPPORT - Support mixed @story/@req/@implements usage in comments
|
|
234
|
+
// @req REQ-SYNTAX-VALIDATION - Dispatch to @story or @req validator based on pending annotation type
|
|
235
|
+
// @req REQ-AUTOFIX-FORMAT - Route to story validator which may apply safe auto-fixes
|
|
236
|
+
// @req REQ-MIXED-SUPPORT - Ensure @story and @req annotations are handled independently
|
|
219
237
|
if (pending.type === "story") {
|
|
220
238
|
validateStoryAnnotation(context, comment, pending.value, options);
|
|
221
239
|
}
|
|
@@ -233,20 +251,24 @@ function finalizePendingAnnotation(context, comment, options, pending) {
|
|
|
233
251
|
* @req REQ-SYNTAX-VALIDATION - Start new pending annotation when a tag is found
|
|
234
252
|
* @req REQ-MULTILINE-SUPPORT - Treat subsequent lines as continuation for pending annotation
|
|
235
253
|
* @req REQ-AUTOFIX-FORMAT - Provide safe, minimal automatic fixes for common format issues
|
|
236
|
-
* @req REQ-IMPLEMENTS-PARSE - Parse @
|
|
254
|
+
* @req REQ-IMPLEMENTS-PARSE - Parse @supports annotations without affecting @story/@req
|
|
237
255
|
* @req REQ-FORMAT-VALIDATION - Validate @implements story path and requirement IDs
|
|
238
256
|
* @req REQ-MIXED-SUPPORT - Support mixed @story/@req/@implements usage in comments
|
|
239
257
|
*/
|
|
240
258
|
function processCommentLine({ normalized, pending, context, comment, options, }) {
|
|
259
|
+
// @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
260
|
+
// @req REQ-FLEXIBLE-PARSING - Ignore empty normalized lines without affecting pending state
|
|
241
261
|
if (!normalized) {
|
|
242
262
|
return pending;
|
|
243
263
|
}
|
|
244
264
|
const isStory = /@story\b/.test(normalized);
|
|
245
265
|
const isReq = /@req\b/.test(normalized);
|
|
246
|
-
const isImplements = /@
|
|
247
|
-
// Handle @
|
|
266
|
+
const isImplements = /@supports\b/.test(normalized);
|
|
267
|
+
// Handle @supports as an immediate, single-line annotation
|
|
268
|
+
// @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
269
|
+
// @req REQ-IMPLEMENTS-PARSE - Immediately validate @supports without starting multi-line state
|
|
248
270
|
if (isImplements) {
|
|
249
|
-
const implementsValue = normalized.replace(/^@
|
|
271
|
+
const implementsValue = normalized.replace(/^@supports\b/, "").trim();
|
|
250
272
|
validateImplementsAnnotation(context, comment, implementsValue, options);
|
|
251
273
|
return pending;
|
|
252
274
|
}
|
|
@@ -268,11 +290,13 @@ function processCommentLine({ normalized, pending, context, comment, options, })
|
|
|
268
290
|
// @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
269
291
|
// @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
270
292
|
// @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
271
|
-
// @req REQ-MULTILINE-SUPPORT -
|
|
272
|
-
// @req REQ-AUTOFIX-FORMAT -
|
|
273
|
-
// @req REQ-MIXED-SUPPORT -
|
|
293
|
+
// @req REQ-MULTILINE-SUPPORT - Extend value of existing pending annotation across lines
|
|
294
|
+
// @req REQ-AUTOFIX-FORMAT - Maintain complete logical value for downstream validation and fixes
|
|
295
|
+
// @req REQ-MIXED-SUPPORT - Leave non-annotation lines untouched when no pending state exists
|
|
274
296
|
if (pending) {
|
|
275
297
|
const continuation = normalized.trim();
|
|
298
|
+
// @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
299
|
+
// @req REQ-MULTILINE-SUPPORT - Skip blank continuation lines without altering pending annotation
|
|
276
300
|
if (!continuation) {
|
|
277
301
|
return pending;
|
|
278
302
|
}
|
|
@@ -288,13 +312,13 @@ function processCommentLine({ normalized, pending, context, comment, options, })
|
|
|
288
312
|
return pending;
|
|
289
313
|
}
|
|
290
314
|
/**
|
|
291
|
-
* Process a single comment node and validate any @story/@req/@
|
|
315
|
+
* Process a single comment node and validate any @story/@req/@supports annotations it contains.
|
|
292
316
|
*
|
|
293
317
|
* Supports @story and @req annotations whose values span multiple lines within the same
|
|
294
318
|
* comment block, collapsing whitespace so that the logical value can be
|
|
295
319
|
* validated against the configured patterns.
|
|
296
320
|
*
|
|
297
|
-
* @
|
|
321
|
+
* @supports annotations are validated immediately per-line and are not
|
|
298
322
|
* accumulated into pending multi-line state.
|
|
299
323
|
*
|
|
300
324
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
@@ -303,7 +327,7 @@ function processCommentLine({ normalized, pending, context, comment, options, })
|
|
|
303
327
|
* @req REQ-MULTILINE-SUPPORT - Handle annotations split across multiple lines
|
|
304
328
|
* @req REQ-FLEXIBLE-PARSING - Support reasonable variations in whitespace and formatting
|
|
305
329
|
* @req REQ-AUTOFIX-FORMAT - Provide safe, minimal automatic fixes for common format issues
|
|
306
|
-
* @req REQ-IMPLEMENTS-PARSE - Parse @
|
|
330
|
+
* @req REQ-IMPLEMENTS-PARSE - Parse @supports annotations without affecting @story/@req
|
|
307
331
|
* @req REQ-FORMAT-VALIDATION - Validate @implements story path and requirement IDs
|
|
308
332
|
* @req REQ-MIXED-SUPPORT - Support mixed @story/@req/@implements usage in comments
|
|
309
333
|
*/
|
|
@@ -326,7 +350,7 @@ exports.default = {
|
|
|
326
350
|
meta: {
|
|
327
351
|
type: "problem",
|
|
328
352
|
docs: {
|
|
329
|
-
description: "Validate format and syntax of @story, @req, and @
|
|
353
|
+
description: "Validate format and syntax of @story, @req, and @supports annotations",
|
|
330
354
|
recommended: "error",
|
|
331
355
|
},
|
|
332
356
|
messages: {
|
|
@@ -346,8 +370,8 @@ exports.default = {
|
|
|
346
370
|
invalidReqFormat: "Invalid annotation format: {{details}}.",
|
|
347
371
|
/**
|
|
348
372
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
349
|
-
* @req REQ-ERROR-SPECIFIC - Provide specific details about invalid @
|
|
350
|
-
* @req REQ-ERROR-CONTEXT - Include human-readable details about the expected @
|
|
373
|
+
* @req REQ-ERROR-SPECIFIC - Provide specific details about invalid @supports annotation format
|
|
374
|
+
* @req REQ-ERROR-CONTEXT - Include human-readable details about the expected @supports annotation format
|
|
351
375
|
* @req REQ-ERROR-CONSISTENCY - Use shared "Invalid annotation format: {{details}}." message pattern across rules
|
|
352
376
|
* @req REQ-FORMAT-VALIDATION - Validate @implements story path and requirement IDs
|
|
353
377
|
*/
|
|
@@ -383,7 +407,7 @@ exports.default = {
|
|
|
383
407
|
* @req REQ-AUTOFIX-FORMAT - Provide safe, minimal automatic fixes for common format issues
|
|
384
408
|
* @req REQ-REGEX-VALIDATION - Derive validation regexes from shared options helper
|
|
385
409
|
* @req REQ-BACKWARD-COMP - Fall back to default patterns and continue validation on config errors
|
|
386
|
-
* @req REQ-IMPLEMENTS-PARSE - Parse @
|
|
410
|
+
* @req REQ-IMPLEMENTS-PARSE - Parse @supports annotations without affecting @story/@req
|
|
387
411
|
* @req REQ-FORMAT-VALIDATION - Validate @implements story path and requirement IDs
|
|
388
412
|
* @req REQ-MIXED-SUPPORT - Support mixed @story/@req/@implements usage in comments
|
|
389
413
|
*/
|
|
@@ -393,7 +417,7 @@ exports.default = {
|
|
|
393
417
|
const optionErrors = (0, valid_annotation_options_1.getOptionErrors)();
|
|
394
418
|
return {
|
|
395
419
|
/**
|
|
396
|
-
* Program-level handler that inspects all comments for @story, @req, and @
|
|
420
|
+
* Program-level handler that inspects all comments for @story, @req, and @supports tags
|
|
397
421
|
*
|
|
398
422
|
* @story docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md
|
|
399
423
|
* @story docs/stories/008.0-DEV-AUTO-FIX.story.md
|
|
@@ -404,11 +428,13 @@ exports.default = {
|
|
|
404
428
|
* @req REQ-AUTOFIX-FORMAT - Provide safe, minimal automatic fixes for common format issues
|
|
405
429
|
* @req REQ-REGEX-VALIDATION - Surface regex configuration errors without blocking validation
|
|
406
430
|
* @req REQ-BACKWARD-COMP - Continue validating comments using default patterns on error
|
|
407
|
-
* @req REQ-IMPLEMENTS-PARSE - Parse @
|
|
431
|
+
* @req REQ-IMPLEMENTS-PARSE - Parse @supports annotations without affecting @story/@req
|
|
408
432
|
* @req REQ-FORMAT-VALIDATION - Validate @implements story path and requirement IDs
|
|
409
433
|
* @req REQ-MIXED-SUPPORT - Support mixed @story/@req/@implements usage in comments
|
|
410
434
|
*/
|
|
411
435
|
Program(node) {
|
|
436
|
+
// @story docs/stories/010.1-DEV-CONFIGURABLE-PATTERNS.story.md
|
|
437
|
+
// @req REQ-REGEX-VALIDATION - Report any configuration errors discovered while resolving options
|
|
412
438
|
if (optionErrors && optionErrors.length > 0) {
|
|
413
439
|
optionErrors.forEach((details) => {
|
|
414
440
|
context.report({
|
|
@@ -15,7 +15,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
const fs_1 = __importDefault(require("fs"));
|
|
16
16
|
const path_1 = __importDefault(require("path"));
|
|
17
17
|
/**
|
|
18
|
-
* Token index configuration for @
|
|
18
|
+
* Token index configuration for @supports annotations.
|
|
19
19
|
* This clarifies the expected positions of the story path and first requirement ID
|
|
20
20
|
* and avoids hard-coded "magic number" indices in parsing logic.
|
|
21
21
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
@@ -175,11 +175,11 @@ function validateReqLine(opts) {
|
|
|
175
175
|
});
|
|
176
176
|
}
|
|
177
177
|
/**
|
|
178
|
-
* Parse
|
|
179
|
-
* Expects the format: "@
|
|
178
|
+
* Parse a @supports annotation line into its story path and requirement IDs.
|
|
179
|
+
* Expects the format: "@supports <storyPath> <REQ-ID-1> <REQ-ID-2> ..."
|
|
180
180
|
* Invalid formats (missing storyPath or reqIds) are ignored by this deep rule.
|
|
181
181
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
182
|
-
* @req REQ-IMPLEMENTS-VALIDATE - Support validation of @
|
|
182
|
+
* @req REQ-IMPLEMENTS-VALIDATE - Support validation of @supports annotations
|
|
183
183
|
* @req REQ-MIXED-SUPPORT - Allow mixed @story/@req/@implements usage in the same comment
|
|
184
184
|
* @req REQ-SCOPED-IDS - Treat requirement IDs as scoped to the referenced story file
|
|
185
185
|
*/
|
|
@@ -193,12 +193,12 @@ function parseImplementsLine(line) {
|
|
|
193
193
|
return { storyPath, reqIds };
|
|
194
194
|
}
|
|
195
195
|
/**
|
|
196
|
-
* Validate an @
|
|
196
|
+
* Validate an @supports annotation line against the referenced story content.
|
|
197
197
|
* Performs path validation, file reading, caching, and requirement existence checks
|
|
198
198
|
* for each requirement ID listed on the line.
|
|
199
199
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
200
|
-
* @req REQ-IMPLEMENTS-VALIDATE - Validate that all @
|
|
201
|
-
* @req REQ-MIXED-SUPPORT - Ensure @
|
|
200
|
+
* @req REQ-IMPLEMENTS-VALIDATE - Validate that all @supports requirement IDs exist
|
|
201
|
+
* @req REQ-MIXED-SUPPORT - Ensure @supports can coexist with @story/@req annotations
|
|
202
202
|
* @req REQ-SCOPED-IDS - Validate requirement IDs in the scope of their explicit story
|
|
203
203
|
*/
|
|
204
204
|
function validateImplementsLine(opts) {
|
|
@@ -234,7 +234,7 @@ function validateImplementsLine(opts) {
|
|
|
234
234
|
* @req REQ-DEEP-PARSE - Parse annotation lines for @story and @req tags
|
|
235
235
|
* @req REQ-DEEP-MATCH - Dispatch @req lines for validation against story requirements
|
|
236
236
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
237
|
-
* @req REQ-IMPLEMENTS-VALIDATE - Dispatch @
|
|
237
|
+
* @req REQ-IMPLEMENTS-VALIDATE - Dispatch @supports lines for validation
|
|
238
238
|
* @req REQ-MIXED-SUPPORT - Support mixed annotation types without interfering with each other
|
|
239
239
|
*/
|
|
240
240
|
function handleAnnotationLine(opts) {
|
|
@@ -247,7 +247,7 @@ function handleAnnotationLine(opts) {
|
|
|
247
247
|
validateReqLine({ comment, context, line, storyPath, cwd, reqCache });
|
|
248
248
|
return storyPath;
|
|
249
249
|
}
|
|
250
|
-
else if (line.startsWith("@
|
|
250
|
+
else if (line.startsWith("@supports")) {
|
|
251
251
|
validateImplementsLine({ comment, context, line, cwd, reqCache });
|
|
252
252
|
return storyPath;
|
|
253
253
|
}
|
|
@@ -76,13 +76,15 @@ function getFixTargetNode(node) {
|
|
|
76
76
|
* Returned function is a proper named function so no inline arrow is used.
|
|
77
77
|
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
78
78
|
* @req REQ-ANNOTATION-AUTOFIX - Provide autofix for missing @req annotation
|
|
79
|
+
* @implements docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md REQ-ANNOTATION-AUTOFIX REQ-ANNOTATION-REPORTING
|
|
79
80
|
*/
|
|
80
81
|
function createMissingReqFix(node) {
|
|
81
82
|
const target = getFixTargetNode(node);
|
|
82
83
|
/**
|
|
83
84
|
* Fixer used to insert a default @req annotation before the chosen target node.
|
|
84
85
|
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
85
|
-
* @req REQ-ANNOTATION-AUTOFIX -
|
|
86
|
+
* @req REQ-ANNOTATION-AUTOFIX - Implement autofix insertion for missing @req
|
|
87
|
+
* @req REQ-ANNOTATION-REPORTING - Support actionable fix in reported problem
|
|
86
88
|
*/
|
|
87
89
|
return function missingReqFix(fixer) {
|
|
88
90
|
return fixer.insertTextBefore(target, "/** @req <REQ-ID> */\n");
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Helper to determine whether a JSDoc or any nearby comments contain a requirement annotation.
|
|
3
|
-
* Treats both @req and @
|
|
3
|
+
* Treats both @req and @supports annotations as evidence of requirement coverage.
|
|
4
4
|
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
5
5
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
6
6
|
* @req REQ-ANNOTATION-REQ-DETECTION - Determine presence of @req annotation
|
|
7
|
-
* @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Accept @
|
|
7
|
+
* @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Accept @supports as requirement coverage
|
|
8
8
|
*/
|
|
9
9
|
export declare function hasReqAnnotation(jsdoc: any, comments: any[], context?: any, node?: any): boolean;
|
|
@@ -9,23 +9,23 @@ exports.hasReqAnnotation = hasReqAnnotation;
|
|
|
9
9
|
const require_story_io_1 = require("../rules/helpers/require-story-io");
|
|
10
10
|
/**
|
|
11
11
|
* Predicate helper to check whether a comment contains a requirement annotation.
|
|
12
|
-
* Treats both @req and @
|
|
12
|
+
* Treats both @req and @supports annotations as satisfying requirement presence checks.
|
|
13
13
|
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
14
14
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
15
15
|
* @req REQ-ANNOTATION-REQ-DETECTION - Detect @req tag inside a comment
|
|
16
|
-
* @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Accept @
|
|
16
|
+
* @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Accept @supports as requirement annotation
|
|
17
17
|
*/
|
|
18
18
|
function commentContainsReq(c) {
|
|
19
19
|
return (c &&
|
|
20
20
|
typeof c.value === "string" &&
|
|
21
|
-
(c.value.includes("@req") || c.value.includes("@
|
|
21
|
+
(c.value.includes("@req") || c.value.includes("@supports")));
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
24
|
* Line-based helper adapted from linesBeforeHasStory to detect requirement annotations.
|
|
25
|
-
* Lines containing either @req or @
|
|
25
|
+
* Lines containing either @req or @supports are treated as annotated.
|
|
26
26
|
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
27
27
|
* @req REQ-ANNOTATION-REQ-DETECTION - Detect @req in preceding source lines
|
|
28
|
-
* @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Accept @
|
|
28
|
+
* @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Accept @supports in preceding source lines
|
|
29
29
|
*/
|
|
30
30
|
function linesBeforeHasReq(sourceCode, node) {
|
|
31
31
|
const lines = sourceCode && sourceCode.lines;
|
|
@@ -40,18 +40,18 @@ function linesBeforeHasReq(sourceCode, node) {
|
|
|
40
40
|
}
|
|
41
41
|
const from = Math.max(0, startLine - 1 - require_story_io_1.LOOKBACK_LINES);
|
|
42
42
|
const to = Math.max(0, startLine - 1);
|
|
43
|
-
// Scan each physical line in the configured lookback window for @req or @
|
|
43
|
+
// Scan each physical line in the configured lookback window for @req or @supports markers.
|
|
44
44
|
// @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
45
45
|
// @req REQ-ANNOTATION-REQ-DETECTION - Search preceding lines for @req text
|
|
46
|
-
// @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Search preceding lines for @
|
|
46
|
+
// @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Search preceding lines for @supports text
|
|
47
47
|
for (let i = from; i < to; i++) {
|
|
48
48
|
const text = lines[i];
|
|
49
|
-
// When a line contains @req or @
|
|
49
|
+
// When a line contains @req or @supports we treat the function as already annotated.
|
|
50
50
|
// @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
51
51
|
// @req REQ-ANNOTATION-REQ-DETECTION - Detect @req marker in raw source lines
|
|
52
|
-
// @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Detect @
|
|
52
|
+
// @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Detect @supports marker in raw source lines
|
|
53
53
|
if (typeof text === "string" &&
|
|
54
|
-
(text.includes("@req") || text.includes("@
|
|
54
|
+
(text.includes("@req") || text.includes("@supports"))) {
|
|
55
55
|
return true;
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -59,34 +59,34 @@ function linesBeforeHasReq(sourceCode, node) {
|
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
61
61
|
* Parent-chain helper adapted from parentChainHasStory to detect requirement annotations.
|
|
62
|
-
* Accepts both @req and @
|
|
62
|
+
* Accepts both @req and @supports in parent-chain comments as satisfying requirement presence.
|
|
63
63
|
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
64
64
|
* @req REQ-ANNOTATION-REQ-DETECTION - Detect @req in parent-chain comments
|
|
65
|
-
* @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Accept @
|
|
65
|
+
* @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Accept @supports in parent-chain comments
|
|
66
66
|
*/
|
|
67
67
|
function parentChainHasReq(sourceCode, node) {
|
|
68
68
|
let p = node && node.parent;
|
|
69
69
|
// Walk up the parent chain and inspect comments attached to each ancestor.
|
|
70
|
-
// Accept both @req and @
|
|
70
|
+
// Accept both @req and @supports markers when local comments are absent.
|
|
71
71
|
// @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
72
72
|
// @req REQ-ANNOTATION-REQ-DETECTION - Traverse parent nodes when local comments are absent
|
|
73
|
-
// @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Allow @
|
|
73
|
+
// @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Allow @supports to satisfy requirement on parents
|
|
74
74
|
while (p) {
|
|
75
75
|
const pComments = typeof sourceCode?.getCommentsBefore === "function"
|
|
76
76
|
? sourceCode.getCommentsBefore(p) || []
|
|
77
77
|
: [];
|
|
78
|
-
// Look for @req or @
|
|
78
|
+
// Look for @req or @supports in comments immediately preceding each parent node.
|
|
79
79
|
// @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
80
80
|
// @req REQ-ANNOTATION-REQ-DETECTION - Detect @req markers in parent comments
|
|
81
|
-
// @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Detect @
|
|
81
|
+
// @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Detect @supports markers in parent comments
|
|
82
82
|
if (Array.isArray(pComments) && pComments.some(commentContainsReq)) {
|
|
83
83
|
return true;
|
|
84
84
|
}
|
|
85
85
|
const pLeading = p.leadingComments || [];
|
|
86
|
-
// Also inspect leadingComments attached directly to the parent node, accepting @req or @
|
|
86
|
+
// Also inspect leadingComments attached directly to the parent node, accepting @req or @supports.
|
|
87
87
|
// @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
88
88
|
// @req REQ-ANNOTATION-REQ-DETECTION - Detect @req markers in parent leadingComments
|
|
89
|
-
// @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Detect @
|
|
89
|
+
// @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Detect @supports markers in parent leadingComments
|
|
90
90
|
if (Array.isArray(pLeading) && pLeading.some(commentContainsReq)) {
|
|
91
91
|
return true;
|
|
92
92
|
}
|
|
@@ -96,11 +96,11 @@ function parentChainHasReq(sourceCode, node) {
|
|
|
96
96
|
}
|
|
97
97
|
/**
|
|
98
98
|
* Fallback text window helper adapted from fallbackTextBeforeHasStory to detect requirement annotations.
|
|
99
|
-
* Treats both @req and @
|
|
99
|
+
* Treats both @req and @supports in the fallback text window as requirement presence.
|
|
100
100
|
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
101
101
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
102
102
|
* @req REQ-ANNOTATION-REQ-DETECTION - Detect @req in fallback text window before node
|
|
103
|
-
* @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Accept @
|
|
103
|
+
* @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Accept @supports in fallback text window before node
|
|
104
104
|
*/
|
|
105
105
|
function fallbackTextBeforeHasReq(sourceCode, node) {
|
|
106
106
|
// Guard against unsupported sourceCode or nodes without a usable range.
|
|
@@ -120,13 +120,13 @@ function fallbackTextBeforeHasReq(sourceCode, node) {
|
|
|
120
120
|
try {
|
|
121
121
|
const start = Math.max(0, range[0] - require_story_io_1.FALLBACK_WINDOW);
|
|
122
122
|
const textBefore = sourceCode.getText().slice(start, range[0]);
|
|
123
|
-
// Detect @req or @
|
|
123
|
+
// Detect @req or @supports in the bounded text window immediately preceding the node.
|
|
124
124
|
// @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
125
125
|
// @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
126
126
|
// @req REQ-ANNOTATION-REQ-DETECTION - Detect @req marker in fallback text window
|
|
127
|
-
// @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Detect @
|
|
127
|
+
// @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Detect @supports marker in fallback text window
|
|
128
128
|
if (typeof textBefore === "string" &&
|
|
129
|
-
(textBefore.includes("@req") || textBefore.includes("@
|
|
129
|
+
(textBefore.includes("@req") || textBefore.includes("@supports"))) {
|
|
130
130
|
return true;
|
|
131
131
|
}
|
|
132
132
|
}
|
|
@@ -140,11 +140,11 @@ function fallbackTextBeforeHasReq(sourceCode, node) {
|
|
|
140
140
|
}
|
|
141
141
|
/**
|
|
142
142
|
* Helper to determine whether a JSDoc or any nearby comments contain a requirement annotation.
|
|
143
|
-
* Treats both @req and @
|
|
143
|
+
* Treats both @req and @supports annotations as evidence of requirement coverage.
|
|
144
144
|
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
145
145
|
* @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
146
146
|
* @req REQ-ANNOTATION-REQ-DETECTION - Determine presence of @req annotation
|
|
147
|
-
* @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Accept @
|
|
147
|
+
* @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Accept @supports as requirement coverage
|
|
148
148
|
*/
|
|
149
149
|
function hasReqAnnotation(jsdoc, comments, context, node) {
|
|
150
150
|
try {
|
|
@@ -154,7 +154,7 @@ function hasReqAnnotation(jsdoc, comments, context, node) {
|
|
|
154
154
|
// Prefer robust, location-based heuristics when sourceCode and node are available.
|
|
155
155
|
// @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
156
156
|
// @req REQ-ANNOTATION-REQ-DETECTION - Use multiple heuristics to detect @req markers around the node
|
|
157
|
-
// @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Use multiple heuristics to detect @
|
|
157
|
+
// @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS - Use multiple heuristics to detect @supports markers around the node
|
|
158
158
|
if (sourceCode && node) {
|
|
159
159
|
if (linesBeforeHasReq(sourceCode, node) ||
|
|
160
160
|
parentChainHasReq(sourceCode, node) ||
|
|
@@ -168,13 +168,13 @@ function hasReqAnnotation(jsdoc, comments, context, node) {
|
|
|
168
168
|
// @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
169
169
|
// @req REQ-ANNOTATION-REQ-DETECTION - Fail gracefully when advanced detection heuristics throw
|
|
170
170
|
}
|
|
171
|
-
// BRANCH requirement detection on JSDoc or comments, accepting both @req and @
|
|
171
|
+
// BRANCH requirement detection on JSDoc or comments, accepting both @req and @supports.
|
|
172
172
|
// @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
173
173
|
// @story docs/stories/010.2-DEV-MULTI-STORY-SUPPORT.story.md
|
|
174
174
|
// @req REQ-ANNOTATION-REQ-DETECTION
|
|
175
175
|
// @req REQ-REQUIRE-ACCEPTS-IMPLEMENTS
|
|
176
176
|
return ((jsdoc &&
|
|
177
177
|
typeof jsdoc.value === "string" &&
|
|
178
|
-
(jsdoc.value.includes("@req") || jsdoc.value.includes("@
|
|
178
|
+
(jsdoc.value.includes("@req") || jsdoc.value.includes("@supports"))) ||
|
|
179
179
|
comments.some(commentContainsReq));
|
|
180
180
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,75 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
/**
|
|
37
|
+
* Tests for: docs/stories/002.0-DEV-ESLINT-CONFIG.story.md
|
|
38
|
+
* @story docs/stories/002.0-DEV-ESLINT-CONFIG.story.md
|
|
39
|
+
* @req REQ-CONFIG-PRESETS - Validate flat-config presets register traceability plugin and rules
|
|
40
|
+
* @req REQ-FLAT-CONFIG - Ensure presets work with ESLint v9 flat config
|
|
41
|
+
* @req REQ-PROJECT-INTEGRATION - Support seamless integration via documented preset usage
|
|
42
|
+
*/
|
|
43
|
+
const use_at_your_own_risk_1 = require("eslint/use-at-your-own-risk");
|
|
44
|
+
const index_1 = __importStar(require("../../src/index"));
|
|
45
|
+
const baseConfig = {
|
|
46
|
+
plugins: {
|
|
47
|
+
traceability: index_1.default,
|
|
48
|
+
},
|
|
49
|
+
rules: {},
|
|
50
|
+
};
|
|
51
|
+
async function lintTextWithConfig(text, config) {
|
|
52
|
+
const eslint = new use_at_your_own_risk_1.FlatESLint({
|
|
53
|
+
overrideConfig: config,
|
|
54
|
+
overrideConfigFile: true,
|
|
55
|
+
ignore: false,
|
|
56
|
+
});
|
|
57
|
+
const [result] = await eslint.lintText(text, { filePath: "example.js" });
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
describe("Flat config presets integration (Story 002.0-DEV-ESLINT-CONFIG)", () => {
|
|
61
|
+
it("[REQ-CONFIG-PRESETS] recommended preset enables traceability rules via documented usage", async () => {
|
|
62
|
+
const config = [baseConfig, ...index_1.configs.recommended];
|
|
63
|
+
const code = "function foo() {}";
|
|
64
|
+
const result = await lintTextWithConfig(code, config);
|
|
65
|
+
const ruleIds = result.messages.map((m) => m.ruleId).sort();
|
|
66
|
+
expect(ruleIds).toContain("traceability/require-story-annotation");
|
|
67
|
+
});
|
|
68
|
+
it("[REQ-CONFIG-PRESETS] strict preset also enables traceability rules via documented usage", async () => {
|
|
69
|
+
const config = [baseConfig, ...index_1.configs.strict];
|
|
70
|
+
const code = "function bar() {}";
|
|
71
|
+
const result = await lintTextWithConfig(code, config);
|
|
72
|
+
const ruleIds = result.messages.map((m) => m.ruleId).sort();
|
|
73
|
+
expect(ruleIds).toContain("traceability/require-story-annotation");
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -41,39 +41,39 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
41
41
|
*/
|
|
42
42
|
const fs = __importStar(require("fs"));
|
|
43
43
|
const path = __importStar(require("path"));
|
|
44
|
-
const
|
|
44
|
+
const temp_dir_helpers_1 = require("../utils/temp-dir-helpers");
|
|
45
45
|
const batch_1 = require("../../src/maintenance/batch");
|
|
46
46
|
describe("batchUpdateAnnotations (Story 009.0-DEV-MAINTENANCE-TOOLS)", () => {
|
|
47
|
-
let
|
|
47
|
+
let temp;
|
|
48
48
|
beforeAll(() => {
|
|
49
|
-
|
|
49
|
+
temp = (0, temp_dir_helpers_1.createTempDir)("batch-test-");
|
|
50
50
|
});
|
|
51
51
|
afterAll(() => {
|
|
52
|
-
|
|
52
|
+
temp.cleanup();
|
|
53
53
|
});
|
|
54
54
|
it("[REQ-MAINT-BATCH] should return 0 when no mappings applied", () => {
|
|
55
|
-
const count = (0, batch_1.batchUpdateAnnotations)(
|
|
55
|
+
const count = (0, batch_1.batchUpdateAnnotations)(temp.dir, []);
|
|
56
56
|
expect(count).toBe(0);
|
|
57
57
|
});
|
|
58
58
|
});
|
|
59
59
|
describe("verifyAnnotations (Story 009.0-DEV-MAINTENANCE-TOOLS)", () => {
|
|
60
|
-
let
|
|
60
|
+
let temp;
|
|
61
61
|
beforeAll(() => {
|
|
62
|
-
|
|
62
|
+
temp = (0, temp_dir_helpers_1.createTempDir)("verify-test-");
|
|
63
63
|
const tsContent = `
|
|
64
64
|
/**
|
|
65
65
|
* Tests for: my-story.story.md
|
|
66
66
|
* @story my-story.story.md
|
|
67
67
|
*/
|
|
68
68
|
`;
|
|
69
|
-
fs.writeFileSync(path.join(
|
|
70
|
-
fs.writeFileSync(path.join(
|
|
69
|
+
fs.writeFileSync(path.join(temp.dir, "test.ts"), tsContent);
|
|
70
|
+
fs.writeFileSync(path.join(temp.dir, "my-story.story.md"), "# Dummy Story");
|
|
71
71
|
});
|
|
72
72
|
afterAll(() => {
|
|
73
|
-
|
|
73
|
+
temp.cleanup();
|
|
74
74
|
});
|
|
75
75
|
it("[REQ-MAINT-VERIFY] should return true when annotations are valid", () => {
|
|
76
|
-
const valid = (0, batch_1.verifyAnnotations)(
|
|
76
|
+
const valid = (0, batch_1.verifyAnnotations)(temp.dir);
|
|
77
77
|
expect(valid).toBe(true);
|
|
78
78
|
});
|
|
79
79
|
});
|