eslint-plugin-traceability 1.6.4 → 1.7.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.
- package/README.md +38 -1
- package/lib/src/index.d.ts +28 -25
- package/lib/src/index.js +49 -31
- package/lib/src/maintenance/cli.d.ts +12 -0
- package/lib/src/maintenance/cli.js +279 -0
- package/lib/src/maintenance/detect.js +30 -15
- package/lib/src/maintenance/update.js +42 -34
- package/lib/src/maintenance/utils.js +30 -30
- package/lib/src/rules/helpers/require-story-io.js +51 -15
- package/lib/src/rules/helpers/require-story-visitors.js +5 -16
- package/lib/src/rules/helpers/valid-annotation-options.d.ts +118 -0
- package/lib/src/rules/helpers/valid-annotation-options.js +167 -0
- package/lib/src/rules/helpers/valid-annotation-utils.d.ts +68 -0
- package/lib/src/rules/helpers/valid-annotation-utils.js +103 -0
- package/lib/src/rules/helpers/valid-story-reference-helpers.d.ts +67 -0
- package/lib/src/rules/helpers/valid-story-reference-helpers.js +92 -0
- package/lib/src/rules/require-story-annotation.js +9 -14
- package/lib/src/rules/valid-annotation-format.js +168 -180
- package/lib/src/rules/valid-req-reference.js +139 -29
- package/lib/src/rules/valid-story-reference.d.ts +7 -0
- package/lib/src/rules/valid-story-reference.js +38 -80
- package/lib/src/utils/annotation-checker.js +2 -145
- package/lib/src/utils/branch-annotation-helpers.js +12 -3
- package/lib/src/utils/reqAnnotationDetection.d.ts +6 -0
- package/lib/src/utils/reqAnnotationDetection.js +152 -0
- package/lib/tests/maintenance/cli.test.d.ts +1 -0
- package/lib/tests/maintenance/cli.test.js +172 -0
- package/lib/tests/maintenance/detect-isolated.test.js +68 -1
- package/lib/tests/maintenance/report.test.js +2 -2
- package/lib/tests/rules/require-branch-annotation.test.js +3 -2
- package/lib/tests/rules/require-req-annotation.test.js +57 -68
- package/lib/tests/rules/require-story-annotation.test.js +13 -28
- package/lib/tests/rules/require-story-core-edgecases.test.js +3 -58
- package/lib/tests/rules/require-story-core.autofix.test.js +5 -41
- package/lib/tests/rules/valid-annotation-format.test.js +328 -51
- package/lib/tests/utils/annotation-checker.test.d.ts +23 -0
- package/lib/tests/utils/annotation-checker.test.js +24 -17
- package/lib/tests/utils/require-story-core-test-helpers.d.ts +10 -0
- package/lib/tests/utils/require-story-core-test-helpers.js +75 -0
- package/lib/tests/utils/ts-language-options.d.ts +22 -0
- package/lib/tests/utils/ts-language-options.js +27 -0
- package/package.json +12 -3
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared test helpers for require-story-core branch coverage.
|
|
4
|
+
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
5
|
+
* @req REQ-AUTOFIX - Provide reusable helpers to exercise autofix branches
|
|
6
|
+
*/
|
|
7
|
+
/* global jest, expect */
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.exerciseCreateAddStoryFixBranches = exerciseCreateAddStoryFixBranches;
|
|
10
|
+
const RANGE_ONE_START = 21;
|
|
11
|
+
const RANGE_ONE_END = 33;
|
|
12
|
+
const RANGE_TWO_START = 50;
|
|
13
|
+
const RANGE_TWO_END = 70;
|
|
14
|
+
const RANGE_PARENT_START = 5;
|
|
15
|
+
const RANGE_PARENT_END = 100;
|
|
16
|
+
const DEFAULT_ANNOTATION = "/** @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md */\n";
|
|
17
|
+
function baseFixer() {
|
|
18
|
+
return {
|
|
19
|
+
insertTextBeforeRange: jest.fn((r, t) => ({ r, t })),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function exerciseBranch1(createAddStoryFix, annotation) {
|
|
23
|
+
const fixer = baseFixer();
|
|
24
|
+
const fixFn = createAddStoryFix(null);
|
|
25
|
+
const res = fixFn(fixer);
|
|
26
|
+
expect(fixer.insertTextBeforeRange).toHaveBeenCalledTimes(1);
|
|
27
|
+
const args = fixer.insertTextBeforeRange.mock.calls[0];
|
|
28
|
+
expect(args[0]).toEqual([0, 0]);
|
|
29
|
+
expect(args[1]).toBe(annotation);
|
|
30
|
+
expect(res).toEqual({
|
|
31
|
+
r: [0, 0],
|
|
32
|
+
t: annotation,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function exerciseBranch2(createAddStoryFix, annotation) {
|
|
36
|
+
const target = {
|
|
37
|
+
type: "FunctionDeclaration",
|
|
38
|
+
range: [RANGE_ONE_START, RANGE_ONE_END],
|
|
39
|
+
parent: { type: "ClassBody" },
|
|
40
|
+
};
|
|
41
|
+
const fixer = baseFixer();
|
|
42
|
+
const fixFn = createAddStoryFix(target);
|
|
43
|
+
const res = fixFn(fixer);
|
|
44
|
+
expect(fixer.insertTextBeforeRange.mock.calls[0][0]).toEqual([RANGE_ONE_START, RANGE_ONE_START]);
|
|
45
|
+
expect(fixer.insertTextBeforeRange.mock.calls[0][1]).toBe(annotation);
|
|
46
|
+
expect(res).toEqual({
|
|
47
|
+
r: [RANGE_ONE_START, RANGE_ONE_START],
|
|
48
|
+
t: annotation,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function exerciseBranch3(createAddStoryFix, annotation) {
|
|
52
|
+
const target = {
|
|
53
|
+
type: "FunctionDeclaration",
|
|
54
|
+
range: [RANGE_TWO_START, RANGE_TWO_END],
|
|
55
|
+
parent: {
|
|
56
|
+
type: "ExportDefaultDeclaration",
|
|
57
|
+
range: [RANGE_PARENT_START, RANGE_PARENT_END],
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
const fixer = baseFixer();
|
|
61
|
+
const fixFn = createAddStoryFix(target);
|
|
62
|
+
const res = fixFn(fixer);
|
|
63
|
+
expect(fixer.insertTextBeforeRange.mock.calls[0][0]).toEqual([RANGE_PARENT_START, RANGE_PARENT_START]);
|
|
64
|
+
expect(fixer.insertTextBeforeRange.mock.calls[0][1]).toBe(annotation);
|
|
65
|
+
expect(res).toEqual({
|
|
66
|
+
r: [RANGE_PARENT_START, RANGE_PARENT_START],
|
|
67
|
+
t: annotation,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function exerciseCreateAddStoryFixBranches(createAddStoryFix, options = {}) {
|
|
71
|
+
const annotation = options.annotationText ?? DEFAULT_ANNOTATION;
|
|
72
|
+
exerciseBranch1(createAddStoryFix, annotation);
|
|
73
|
+
exerciseBranch2(createAddStoryFix, annotation);
|
|
74
|
+
exerciseBranch3(createAddStoryFix, annotation);
|
|
75
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared TypeScript RuleTester language options for traceability tests.
|
|
3
|
+
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
4
|
+
* @req REQ-TYPESCRIPT-SUPPORT - Provide reusable TypeScript parser setup for tests
|
|
5
|
+
*/
|
|
6
|
+
export declare const tsRuleTesterLanguageOptions: {
|
|
7
|
+
readonly parser: any;
|
|
8
|
+
readonly parserOptions: {
|
|
9
|
+
readonly ecmaVersion: 2022;
|
|
10
|
+
readonly sourceType: "module";
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Attach shared TypeScript RuleTester language options to a test case definition.
|
|
15
|
+
* This helper allows tests to avoid repeating the languageOptions assignment.
|
|
16
|
+
*
|
|
17
|
+
* @param testCase A RuleTester valid/invalid test case object
|
|
18
|
+
* @returns The same test case with TypeScript language options applied
|
|
19
|
+
*/
|
|
20
|
+
export declare function withTsLanguageOptions<T extends Record<string, unknown>>(testCase: T): T & {
|
|
21
|
+
languageOptions: typeof tsRuleTesterLanguageOptions;
|
|
22
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.tsRuleTesterLanguageOptions = void 0;
|
|
4
|
+
exports.withTsLanguageOptions = withTsLanguageOptions;
|
|
5
|
+
/**
|
|
6
|
+
* Shared TypeScript RuleTester language options for traceability tests.
|
|
7
|
+
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
8
|
+
* @req REQ-TYPESCRIPT-SUPPORT - Provide reusable TypeScript parser setup for tests
|
|
9
|
+
*/
|
|
10
|
+
exports.tsRuleTesterLanguageOptions = {
|
|
11
|
+
parser: require("@typescript-eslint/parser"),
|
|
12
|
+
// eslint-disable-next-line no-magic-numbers -- ECMAScript version constant
|
|
13
|
+
parserOptions: { ecmaVersion: 2022, sourceType: "module" },
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Attach shared TypeScript RuleTester language options to a test case definition.
|
|
17
|
+
* This helper allows tests to avoid repeating the languageOptions assignment.
|
|
18
|
+
*
|
|
19
|
+
* @param testCase A RuleTester valid/invalid test case object
|
|
20
|
+
* @returns The same test case with TypeScript language options applied
|
|
21
|
+
*/
|
|
22
|
+
function withTsLanguageOptions(testCase) {
|
|
23
|
+
return {
|
|
24
|
+
...testCase,
|
|
25
|
+
languageOptions: exports.tsRuleTesterLanguageOptions,
|
|
26
|
+
};
|
|
27
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-traceability",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "A customizable ESLint plugin that enforces traceability annotations in your code, ensuring each implementation is linked to its requirement or test case.",
|
|
5
5
|
"main": "lib/src/index.js",
|
|
6
6
|
"types": "lib/src/index.d.ts",
|
|
@@ -12,8 +12,12 @@
|
|
|
12
12
|
"directories": {
|
|
13
13
|
"doc": "docs"
|
|
14
14
|
},
|
|
15
|
+
"bin": {
|
|
16
|
+
"traceability-maint": "lib/src/maintenance/cli.js"
|
|
17
|
+
},
|
|
15
18
|
"scripts": {
|
|
16
19
|
"build": "tsc -p tsconfig.json",
|
|
20
|
+
"prepare": "husky install",
|
|
17
21
|
"type-check": "tsc --noEmit -p tsconfig.json",
|
|
18
22
|
"check:traceability": "node scripts/traceability-check.js",
|
|
19
23
|
"lint-plugin-check": "node scripts/lint-plugin-check.js",
|
|
@@ -26,10 +30,12 @@
|
|
|
26
30
|
"ci-verify:fast": "npm run type-check && npm run check:traceability && npm run duplication && jest --ci --bail --passWithNoTests --testPathPatterns 'tests/(unit|fast)'",
|
|
27
31
|
"format": "prettier --write .",
|
|
28
32
|
"format:check": "prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
33
|
+
"lint-staged": "lint-staged",
|
|
29
34
|
"duplication": "jscpd src tests --reporters console --threshold 3 --ignore tests/utils/**",
|
|
30
35
|
"audit:dev-high": "node scripts/generate-dev-deps-audit.js",
|
|
31
36
|
"safety:deps": "node scripts/ci-safety-deps.js",
|
|
32
37
|
"audit:ci": "node scripts/ci-audit.js",
|
|
38
|
+
"security:secrets": "secretlint \"**/*\" --no-color",
|
|
33
39
|
"smoke-test": "./scripts/smoke-test.sh"
|
|
34
40
|
},
|
|
35
41
|
"lint-staged": {
|
|
@@ -65,6 +71,7 @@
|
|
|
65
71
|
"@typescript-eslint/parser": "^8.46.4",
|
|
66
72
|
"@typescript-eslint/utils": "^8.46.4",
|
|
67
73
|
"actionlint": "^2.0.6",
|
|
74
|
+
"dry-aged-deps": "^2.3.1",
|
|
68
75
|
"eslint": "^9.39.1",
|
|
69
76
|
"husky": "^9.1.7",
|
|
70
77
|
"jest": "^30.2.0",
|
|
@@ -73,13 +80,15 @@
|
|
|
73
80
|
"prettier": "^3.6.2",
|
|
74
81
|
"semantic-release": "^21.1.2",
|
|
75
82
|
"ts-jest": "^29.4.5",
|
|
76
|
-
"typescript": "^5.9.3"
|
|
83
|
+
"typescript": "^5.9.3",
|
|
84
|
+
"secretlint": "11.2.5",
|
|
85
|
+
"@secretlint/secretlint-rule-preset-recommend": "11.2.5"
|
|
77
86
|
},
|
|
78
87
|
"peerDependencies": {
|
|
79
88
|
"eslint": "^9.0.0"
|
|
80
89
|
},
|
|
81
90
|
"engines": {
|
|
82
|
-
"node": ">=
|
|
91
|
+
"node": ">=18.18.0"
|
|
83
92
|
},
|
|
84
93
|
"overrides": {
|
|
85
94
|
"glob": "12.0.0",
|