eslint-plugin-traceability 1.0.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/.env.example +6 -0
- package/.github/workflows/ci-cd.yml +56 -0
- package/.husky/pre-commit +1 -0
- package/.husky/pre-push +1 -0
- package/.prettierignore +23 -0
- package/.prettierrc +4 -0
- package/.voder/history.md +164 -0
- package/.voder/implementation-progress.md +145 -0
- package/.voder/last-action.md +106 -0
- package/.voder/plan.md +15 -0
- package/.voder/progress-chart.png +0 -0
- package/.voder/progress-log-areas.csv +34 -0
- package/.voder/progress-log.csv +33 -0
- package/.voder/traceability/docs-stories-001.0-DEV-PLUGIN-SETUP.story.xml +17 -0
- package/.voder/traceability/docs-stories-002.0-DEV-ESLINT-CONFIG.story.xml +13 -0
- package/.voder/traceability/docs-stories-003.0-DEV-FUNCTION-ANNOTATIONS.story.xml +9 -0
- package/.voder/traceability/docs-stories-004.0-DEV-BRANCH-ANNOTATIONS.story.xml +9 -0
- package/.voder/traceability/docs-stories-005.0-DEV-ANNOTATION-VALIDATION.story.xml +9 -0
- package/.voder/traceability/docs-stories-006.0-DEV-FILE-VALIDATION.story.xml +9 -0
- package/.voder/traceability/docs-stories-007.0-DEV-ERROR-REPORTING.story.xml +9 -0
- package/.voder/traceability/docs-stories-008.0-DEV-AUTO-FIX.story.xml +9 -0
- package/.voder/traceability/docs-stories-009.0-DEV-MAINTENANCE-TOOLS.story.xml +16 -0
- package/.voder/traceability/docs-stories-010.0-DEV-DEEP-VALIDATION.story.xml +11 -0
- package/CHANGELOG.md +31 -0
- package/CONTRIBUTING.md +97 -0
- package/LICENSE +21 -0
- package/README.md +159 -0
- package/cli-integration.js +157 -0
- package/docs/cli-integration.md +103 -0
- package/docs/config-presets.md +38 -0
- package/docs/decisions/001-typescript-for-eslint-plugin.accepted.md +111 -0
- package/docs/decisions/002-jest-for-eslint-testing.accepted.md +137 -0
- package/docs/decisions/003-code-quality-ratcheting-plan.md +48 -0
- package/docs/eslint-9-setup-guide.md +517 -0
- package/docs/eslint-plugin-development-guide.md +483 -0
- package/docs/jest-testing-guide.md +100 -0
- package/docs/rules/require-branch-annotation.md +34 -0
- package/docs/rules/require-req-annotation.md +39 -0
- package/docs/rules/require-story-annotation.md +36 -0
- package/docs/rules/valid-annotation-format.md +52 -0
- package/docs/rules/valid-req-reference.md +58 -0
- package/docs/rules/valid-story-reference.md +47 -0
- package/docs/security-incidents/unresolved-vulnerabilities.md +11 -0
- package/docs/stories/001.0-DEV-PLUGIN-SETUP.story.md +82 -0
- package/docs/stories/002.0-DEV-ESLINT-CONFIG.story.md +82 -0
- package/docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md +85 -0
- package/docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md +107 -0
- package/docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md +119 -0
- package/docs/stories/006.0-DEV-FILE-VALIDATION.story.md +127 -0
- package/docs/stories/007.0-DEV-ERROR-REPORTING.story.md +89 -0
- package/docs/stories/008.0-DEV-AUTO-FIX.story.md +104 -0
- package/docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md +104 -0
- package/docs/stories/010.0-DEV-DEEP-VALIDATION.story.md +110 -0
- package/docs/stories/developer-story.map.md +118 -0
- package/eslint.config.js +146 -0
- package/jest.config.js +21 -0
- package/lib/index.d.ts +26 -0
- package/lib/index.js +11 -0
- package/lib/src/index.d.ts +80 -0
- package/lib/src/index.js +58 -0
- package/lib/src/maintenance/batch.d.ts +16 -0
- package/lib/src/maintenance/batch.js +28 -0
- package/lib/src/maintenance/detect.d.ts +6 -0
- package/lib/src/maintenance/detect.js +69 -0
- package/lib/src/maintenance/index.d.ts +14 -0
- package/lib/src/maintenance/index.js +22 -0
- package/lib/src/maintenance/report.d.ts +7 -0
- package/lib/src/maintenance/report.js +17 -0
- package/lib/src/maintenance/update.d.ts +6 -0
- package/lib/src/maintenance/update.js +67 -0
- package/lib/src/maintenance/utils.d.ts +6 -0
- package/lib/src/maintenance/utils.js +64 -0
- package/lib/src/rules/require-branch-annotation.d.ts +7 -0
- package/lib/src/rules/require-branch-annotation.js +111 -0
- package/lib/src/rules/require-req-annotation.d.ts +7 -0
- package/lib/src/rules/require-req-annotation.js +38 -0
- package/lib/src/rules/require-story-annotation.d.ts +7 -0
- package/lib/src/rules/require-story-annotation.js +50 -0
- package/lib/src/rules/valid-annotation-format.d.ts +10 -0
- package/lib/src/rules/valid-annotation-format.js +60 -0
- package/lib/src/rules/valid-req-reference.d.ts +3 -0
- package/lib/src/rules/valid-req-reference.js +104 -0
- package/lib/src/rules/valid-story-reference.d.ts +3 -0
- package/lib/src/rules/valid-story-reference.js +168 -0
- package/lib/tests/basic.test.d.ts +1 -0
- package/lib/tests/basic.test.js +51 -0
- package/lib/tests/fixtures/stale/example.d.ts +0 -0
- package/lib/tests/fixtures/stale/example.js +3 -0
- package/lib/tests/fixtures/update/example.d.ts +0 -0
- package/lib/tests/fixtures/update/example.js +3 -0
- package/lib/tests/fixtures/valid-annotations/example.d.ts +0 -0
- package/lib/tests/fixtures/valid-annotations/example.js +3 -0
- package/lib/tests/index.test.d.ts +1 -0
- package/lib/tests/index.test.js +68 -0
- package/lib/tests/integration/file-validation.test.d.ts +1 -0
- package/lib/tests/integration/file-validation.test.js +60 -0
- package/lib/tests/integration/plugin-validation.test.d.ts +1 -0
- package/lib/tests/integration/plugin-validation.test.js +77 -0
- package/lib/tests/maintenance/batch.test.d.ts +1 -0
- package/lib/tests/maintenance/batch.test.js +79 -0
- package/lib/tests/maintenance/detect-isolated.test.d.ts +1 -0
- package/lib/tests/maintenance/detect-isolated.test.js +90 -0
- package/lib/tests/maintenance/detect.test.d.ts +1 -0
- package/lib/tests/maintenance/detect.test.js +23 -0
- package/lib/tests/maintenance/report.test.d.ts +1 -0
- package/lib/tests/maintenance/report.test.js +67 -0
- package/lib/tests/maintenance/update-isolated.test.d.ts +1 -0
- package/lib/tests/maintenance/update-isolated.test.js +66 -0
- package/lib/tests/maintenance/update.test.d.ts +1 -0
- package/lib/tests/maintenance/update.test.js +26 -0
- package/lib/tests/rules/require-branch-annotation.test.d.ts +1 -0
- package/lib/tests/rules/require-branch-annotation.test.js +251 -0
- package/lib/tests/rules/require-req-annotation.test.d.ts +1 -0
- package/lib/tests/rules/require-req-annotation.test.js +41 -0
- package/lib/tests/rules/require-story-annotation.test.d.ts +1 -0
- package/lib/tests/rules/require-story-annotation.test.js +35 -0
- package/lib/tests/rules/valid-annotation-format.test.d.ts +1 -0
- package/lib/tests/rules/valid-annotation-format.test.js +58 -0
- package/lib/tests/rules/valid-req-reference.test.d.ts +1 -0
- package/lib/tests/rules/valid-req-reference.test.js +87 -0
- package/lib/tests/rules/valid-story-reference.test.d.ts +1 -0
- package/lib/tests/rules/valid-story-reference.test.js +69 -0
- package/package.json +67 -0
- package/src/index.ts +56 -0
- package/src/maintenance/batch.ts +29 -0
- package/src/maintenance/detect.ts +42 -0
- package/src/maintenance/index.ts +14 -0
- package/src/maintenance/report.ts +15 -0
- package/src/maintenance/update.ts +40 -0
- package/src/maintenance/utils.ts +28 -0
- package/src/rules/require-branch-annotation.ts +114 -0
- package/src/rules/require-req-annotation.ts +36 -0
- package/src/rules/require-story-annotation.ts +52 -0
- package/src/rules/valid-annotation-format.ts +62 -0
- package/src/rules/valid-req-reference.ts +114 -0
- package/src/rules/valid-story-reference.ts +213 -0
- package/tests/basic.test.ts +17 -0
- package/tests/fixtures/stale/example.ts +2 -0
- package/tests/fixtures/story_bullet.md +6 -0
- package/tests/fixtures/update/example.ts +2 -0
- package/tests/fixtures/valid-annotations/example.ts +2 -0
- package/tests/index.test.ts +46 -0
- package/tests/integration/file-validation.test.ts +67 -0
- package/tests/integration/plugin-validation.test.ts +79 -0
- package/tests/maintenance/batch.test.ts +55 -0
- package/tests/maintenance/detect-isolated.test.ts +61 -0
- package/tests/maintenance/detect.test.ts +19 -0
- package/tests/maintenance/report.test.ts +37 -0
- package/tests/maintenance/update-isolated.test.ts +39 -0
- package/tests/maintenance/update.test.ts +21 -0
- package/tests/rules/require-branch-annotation.test.ts +248 -0
- package/tests/rules/require-req-annotation.test.ts +38 -0
- package/tests/rules/require-story-annotation.test.ts +32 -0
- package/tests/rules/valid-annotation-format.test.ts +55 -0
- package/tests/rules/valid-req-reference.test.ts +85 -0
- package/tests/rules/valid-story-reference.test.ts +66 -0
- package/tsconfig.json +15 -0
- package/user-docs/api-reference.md +135 -0
- package/user-docs/examples.md +73 -0
|
@@ -0,0 +1,51 @@
|
|
|
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 basic plugin structure
|
|
38
|
+
* @story docs/stories/001.0-DEV-PLUGIN-SETUP.story.md
|
|
39
|
+
* @req REQ-PLUGIN-STRUCTURE - plugin exports rules and configs
|
|
40
|
+
*/
|
|
41
|
+
const index_1 = __importStar(require("../lib/index"));
|
|
42
|
+
describe("Traceability ESLint Plugin (Story 001.0-DEV-PLUGIN-SETUP)", () => {
|
|
43
|
+
it("[REQ-PLUGIN-STRUCTURE] plugin exports rules and configs", () => {
|
|
44
|
+
expect(index_1.rules).toBeDefined();
|
|
45
|
+
expect(index_1.configs).toBeDefined();
|
|
46
|
+
expect(typeof index_1.rules).toBe("object");
|
|
47
|
+
expect(typeof index_1.configs).toBe("object");
|
|
48
|
+
expect(index_1.default.rules).toBe(index_1.rules);
|
|
49
|
+
expect(index_1.default.configs).toBe(index_1.configs);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
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/001.0-DEV-PLUGIN-SETUP.story.md
|
|
38
|
+
* @story docs/stories/001.0-DEV-PLUGIN-SETUP.story.md
|
|
39
|
+
* @req REQ-PLUGIN-STRUCTURE - Validate plugin default export and configs in src/index.ts
|
|
40
|
+
*/
|
|
41
|
+
const index_1 = __importStar(require("../src/index"));
|
|
42
|
+
describe("Plugin Default Export and Configs (Story 001.0-DEV-PLUGIN-SETUP)", () => {
|
|
43
|
+
it("[REQ-PLUGIN-STRUCTURE] default export includes rules and configs", () => {
|
|
44
|
+
expect(index_1.default.rules).toBe(index_1.rules);
|
|
45
|
+
expect(index_1.default.configs).toBe(index_1.configs);
|
|
46
|
+
});
|
|
47
|
+
it("[REQ-PLUGIN-STRUCTURE] rules object has correct rule names", () => {
|
|
48
|
+
const expected = [
|
|
49
|
+
"require-story-annotation",
|
|
50
|
+
"require-req-annotation",
|
|
51
|
+
"require-branch-annotation",
|
|
52
|
+
"valid-annotation-format",
|
|
53
|
+
"valid-story-reference",
|
|
54
|
+
"valid-req-reference",
|
|
55
|
+
];
|
|
56
|
+
expect(Object.keys(index_1.rules).sort()).toEqual(expected.sort());
|
|
57
|
+
});
|
|
58
|
+
it("[REQ-RULE-REGISTRY] configs.recommended contains correct rule configuration", () => {
|
|
59
|
+
const recommendedRules = index_1.configs.recommended[0].rules;
|
|
60
|
+
expect(recommendedRules).toHaveProperty("traceability/require-story-annotation", "error");
|
|
61
|
+
expect(recommendedRules).toHaveProperty("traceability/require-req-annotation", "error");
|
|
62
|
+
expect(recommendedRules).toHaveProperty("traceability/require-branch-annotation", "error");
|
|
63
|
+
});
|
|
64
|
+
it("[REQ-CONFIG-SYSTEM] configs.strict contains same rules as recommended", () => {
|
|
65
|
+
const strictRules = index_1.configs.strict[0].rules;
|
|
66
|
+
expect(strictRules).toEqual(index_1.configs.recommended[0].rules);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
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
|
+
* Integration tests for file-validation rules via ESLint CLI
|
|
8
|
+
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
9
|
+
* @req REQ-PERFORMANCE-OPTIMIZATION - Verify CLI integration of valid-story-reference and valid-req-reference rules
|
|
10
|
+
*/
|
|
11
|
+
const child_process_1 = require("child_process");
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
// Ensure ESLint CLI uses built plugin
|
|
14
|
+
const eslintBin = path_1.default.resolve(__dirname, "../../node_modules/.bin/eslint");
|
|
15
|
+
const configPath = path_1.default.resolve(__dirname, "../../eslint.config.js");
|
|
16
|
+
describe("File and Req Validation CLI Integration (Story 006.0-DEV-FILE-VALIDATION)", () => {
|
|
17
|
+
function runLint(code, rules) {
|
|
18
|
+
const ruleArgs = [
|
|
19
|
+
"--rule",
|
|
20
|
+
"no-unused-vars:off",
|
|
21
|
+
...rules.flatMap((r) => ["--rule", r]),
|
|
22
|
+
];
|
|
23
|
+
return (0, child_process_1.spawnSync)("node", [
|
|
24
|
+
eslintBin,
|
|
25
|
+
"--no-config-lookup",
|
|
26
|
+
"--config",
|
|
27
|
+
configPath,
|
|
28
|
+
"--stdin",
|
|
29
|
+
"--stdin-filename",
|
|
30
|
+
"foo.js",
|
|
31
|
+
...ruleArgs,
|
|
32
|
+
], {
|
|
33
|
+
encoding: "utf-8",
|
|
34
|
+
input: code,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
it("[REQ-FILE-EXISTENCE] reports missing story file via CLI", () => {
|
|
38
|
+
const code = "// @story docs/stories/missing-file.story.md";
|
|
39
|
+
const res = runLint(code, ["traceability/valid-story-reference:error"]);
|
|
40
|
+
expect(res.status).toBe(1);
|
|
41
|
+
expect(res.stdout).toContain("Story file");
|
|
42
|
+
});
|
|
43
|
+
it("[REQ-EXTENSION] reports invalid extension via CLI", () => {
|
|
44
|
+
const code = "// @story docs/stories/001.0-DEV-PLUGIN-SETUP.md";
|
|
45
|
+
const res = runLint(code, ["traceability/valid-story-reference:error"]);
|
|
46
|
+
expect(res.status).toBe(1);
|
|
47
|
+
expect(res.stdout).toContain("Invalid story file extension");
|
|
48
|
+
});
|
|
49
|
+
it("[REQ-DEEP-PARSE] reports missing requirement via CLI", () => {
|
|
50
|
+
const code = "// @story docs/stories/001.0-DEV-PLUGIN-SETUP.story.md\n// @req REQ-UNKNOWN";
|
|
51
|
+
const res = runLint(code, ["traceability/valid-req-reference:error"]);
|
|
52
|
+
expect(res.status).toBe(1);
|
|
53
|
+
expect(res.stdout).toContain("Requirement 'REQ-UNKNOWN' not found");
|
|
54
|
+
});
|
|
55
|
+
it("[REQ-DEEP-MATCH] valid story and requirement via CLI", () => {
|
|
56
|
+
const code = "// @story docs/stories/001.0-DEV-PLUGIN-SETUP.story.md\n// @req REQ-PLUGIN-STRUCTURE";
|
|
57
|
+
const res = runLint(code, ["traceability/valid-req-reference:error"]);
|
|
58
|
+
expect(res.status).toBe(0);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,77 @@
|
|
|
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
|
+
* Integration tests for ESLint plugin via CLI
|
|
8
|
+
* @story docs/stories/001.0-DEV-PLUGIN-SETUP.story.md
|
|
9
|
+
* @req REQ-PLUGIN-STRUCTURE - Validate plugin registers via CLI
|
|
10
|
+
*/
|
|
11
|
+
/* eslint-env node, jest */
|
|
12
|
+
const child_process_1 = require("child_process");
|
|
13
|
+
const path_1 = __importDefault(require("path"));
|
|
14
|
+
const eslintBin = path_1.default.resolve(__dirname, "../../node_modules/.bin/eslint");
|
|
15
|
+
const configPath = path_1.default.resolve(__dirname, "../../eslint.config.js");
|
|
16
|
+
function runEslint(code, rule) {
|
|
17
|
+
const args = [
|
|
18
|
+
"--no-config-lookup",
|
|
19
|
+
"--config",
|
|
20
|
+
configPath,
|
|
21
|
+
"--stdin",
|
|
22
|
+
"--stdin-filename",
|
|
23
|
+
"foo.js",
|
|
24
|
+
"--rule",
|
|
25
|
+
"no-unused-vars:off",
|
|
26
|
+
"--rule",
|
|
27
|
+
rule,
|
|
28
|
+
];
|
|
29
|
+
// Use Node to run the ESLint CLI script
|
|
30
|
+
return (0, child_process_1.spawnSync)("node", [eslintBin, ...args], {
|
|
31
|
+
encoding: "utf-8",
|
|
32
|
+
input: code,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
const cliTests = [
|
|
36
|
+
{
|
|
37
|
+
name: "[REQ-PLUGIN-STRUCTURE] reports error when @story annotation is missing",
|
|
38
|
+
code: "function foo() {}",
|
|
39
|
+
rule: "traceability/require-story-annotation:error",
|
|
40
|
+
expectedStatus: 1,
|
|
41
|
+
stdoutRegex: /require-story-annotation/,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: "does not report error when @story annotation is present",
|
|
45
|
+
code: `
|
|
46
|
+
/**
|
|
47
|
+
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
48
|
+
*/
|
|
49
|
+
function foo() {}
|
|
50
|
+
`,
|
|
51
|
+
rule: "traceability/require-story-annotation:error",
|
|
52
|
+
expectedStatus: 0,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: "Require Req Annotation CLI (Story 003.0-DEV-FUNCTION-ANNOTATIONS)",
|
|
56
|
+
code: "function foo() {}",
|
|
57
|
+
rule: "traceability/require-req-annotation:error",
|
|
58
|
+
expectedStatus: 1,
|
|
59
|
+
stdoutRegex: /require-req-annotation/,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: "Require Branch Annotation CLI (Story 004.0-DEV-BRANCH-ANNOTATIONS)",
|
|
63
|
+
code: "if (condition) {}",
|
|
64
|
+
rule: "traceability/require-branch-annotation:error",
|
|
65
|
+
expectedStatus: 1,
|
|
66
|
+
stdoutRegex: /require-branch-annotation/,
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
describe("ESLint CLI Integration (Story 001.0-DEV-PLUGIN-SETUP)", () => {
|
|
70
|
+
test.each(cliTests)("$name", ({ code, rule, expectedStatus, stdoutRegex }) => {
|
|
71
|
+
const result = runEslint(code, rule);
|
|
72
|
+
expect(result.status).toBe(expectedStatus);
|
|
73
|
+
if (stdoutRegex) {
|
|
74
|
+
expect(result.stdout).toMatch(stdoutRegex);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
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/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
38
|
+
* @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
39
|
+
* @req REQ-MAINT-BATCH - Perform batch updates
|
|
40
|
+
* @req REQ-MAINT-VERIFY - Verify annotation references
|
|
41
|
+
*/
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
const os = __importStar(require("os"));
|
|
45
|
+
const batch_1 = require("../../src/maintenance/batch");
|
|
46
|
+
describe("batchUpdateAnnotations (Story 009.0-DEV-MAINTENANCE-TOOLS)", () => {
|
|
47
|
+
let tmpDir;
|
|
48
|
+
beforeAll(() => {
|
|
49
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "batch-test-"));
|
|
50
|
+
});
|
|
51
|
+
afterAll(() => {
|
|
52
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
53
|
+
});
|
|
54
|
+
it("[REQ-MAINT-BATCH] should return 0 when no mappings applied", () => {
|
|
55
|
+
const count = (0, batch_1.batchUpdateAnnotations)(tmpDir, []);
|
|
56
|
+
expect(count).toBe(0);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe("verifyAnnotations (Story 009.0-DEV-MAINTENANCE-TOOLS)", () => {
|
|
60
|
+
let tmpDir;
|
|
61
|
+
beforeAll(() => {
|
|
62
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "verify-test-"));
|
|
63
|
+
const tsContent = `
|
|
64
|
+
/**
|
|
65
|
+
* Tests for: my-story.story.md
|
|
66
|
+
* @story my-story.story.md
|
|
67
|
+
*/
|
|
68
|
+
`;
|
|
69
|
+
fs.writeFileSync(path.join(tmpDir, "test.ts"), tsContent);
|
|
70
|
+
fs.writeFileSync(path.join(tmpDir, "my-story.story.md"), "# Dummy Story");
|
|
71
|
+
});
|
|
72
|
+
afterAll(() => {
|
|
73
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
74
|
+
});
|
|
75
|
+
it("[REQ-MAINT-VERIFY] should return true when annotations are valid", () => {
|
|
76
|
+
const valid = (0, batch_1.verifyAnnotations)(tmpDir);
|
|
77
|
+
expect(valid).toBe(true);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,90 @@
|
|
|
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/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
38
|
+
* @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
39
|
+
* @req REQ-MAINT-DETECT - Detect stale annotation references
|
|
40
|
+
*/
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const os = __importStar(require("os"));
|
|
44
|
+
const detect_1 = require("../../src/maintenance/detect");
|
|
45
|
+
describe("detectStaleAnnotations isolated (Story 009.0-DEV-MAINTENANCE-TOOLS)", () => {
|
|
46
|
+
it("[REQ-MAINT-DETECT] returns empty array when directory does not exist", () => {
|
|
47
|
+
const result = (0, detect_1.detectStaleAnnotations)("non-existent-dir");
|
|
48
|
+
expect(result).toEqual([]);
|
|
49
|
+
});
|
|
50
|
+
it("[REQ-MAINT-DETECT] detects stale annotations in nested directories", () => {
|
|
51
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "tmp-nested-"));
|
|
52
|
+
const nestedDir = path.join(tmpDir, "nested");
|
|
53
|
+
fs.mkdirSync(nestedDir);
|
|
54
|
+
const filePath1 = path.join(tmpDir, "file1.ts");
|
|
55
|
+
const filePath2 = path.join(nestedDir, "file2.ts");
|
|
56
|
+
const content1 = `
|
|
57
|
+
/**
|
|
58
|
+
* @story stale1.story.md
|
|
59
|
+
*/
|
|
60
|
+
`;
|
|
61
|
+
fs.writeFileSync(filePath1, content1, "utf8");
|
|
62
|
+
const content2 = `
|
|
63
|
+
/**
|
|
64
|
+
* @story stale2.story.md
|
|
65
|
+
*/
|
|
66
|
+
`;
|
|
67
|
+
fs.writeFileSync(filePath2, content2, "utf8");
|
|
68
|
+
const result = (0, detect_1.detectStaleAnnotations)(tmpDir);
|
|
69
|
+
expect(result.sort()).toEqual(["stale1.story.md", "stale2.story.md"].sort());
|
|
70
|
+
});
|
|
71
|
+
it("[REQ-MAINT-DETECT] throws error on permission denied", () => {
|
|
72
|
+
const tmpDir2 = fs.mkdtempSync(path.join(os.tmpdir(), "tmp-perm-"));
|
|
73
|
+
const dir = path.join(tmpDir2, "subdir");
|
|
74
|
+
fs.mkdirSync(dir);
|
|
75
|
+
const filePath = path.join(dir, "file.ts");
|
|
76
|
+
const content = `
|
|
77
|
+
/**
|
|
78
|
+
* @story none.story.md
|
|
79
|
+
*/
|
|
80
|
+
`;
|
|
81
|
+
fs.writeFileSync(filePath, content, "utf8");
|
|
82
|
+
// Remove read permission
|
|
83
|
+
fs.chmodSync(dir, 0o000);
|
|
84
|
+
expect(() => (0, detect_1.detectStaleAnnotations)(tmpDir2)).toThrow();
|
|
85
|
+
// Restore permissions
|
|
86
|
+
fs.chmodSync(dir, 0o700);
|
|
87
|
+
// Cleanup temporary directory
|
|
88
|
+
fs.rmSync(tmpDir2, { recursive: true, force: true });
|
|
89
|
+
});
|
|
90
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
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/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
8
|
+
* @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
9
|
+
* @req REQ-MAINT-DETECT - Detect stale annotation references
|
|
10
|
+
*/
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const os_1 = __importDefault(require("os"));
|
|
14
|
+
const detect_1 = require("../../src/maintenance/detect");
|
|
15
|
+
describe("detectStaleAnnotations (Story 009.0-DEV-MAINTENANCE-TOOLS)", () => {
|
|
16
|
+
it("[REQ-MAINT-DETECT] should return empty array when no stale annotations", () => {
|
|
17
|
+
const tmpDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), "detect-test-"));
|
|
18
|
+
// No annotation files are created in tmpDir to simulate no stale annotations
|
|
19
|
+
const result = (0, detect_1.detectStaleAnnotations)(tmpDir);
|
|
20
|
+
expect(result).toEqual([]);
|
|
21
|
+
fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
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/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
38
|
+
* @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
39
|
+
* @req REQ-MAINT-REPORT - Generate maintenance report
|
|
40
|
+
* @req REQ-MAINT-SAFE - Ensure operations are safe and reversible
|
|
41
|
+
*/
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
const os = __importStar(require("os"));
|
|
45
|
+
const report_1 = require("../../src/maintenance/report");
|
|
46
|
+
describe("generateMaintenanceReport (Story 009.0-DEV-MAINTENANCE-TOOLS)", () => {
|
|
47
|
+
let tmpDir;
|
|
48
|
+
beforeAll(() => {
|
|
49
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "report-test-"));
|
|
50
|
+
});
|
|
51
|
+
afterAll(() => {
|
|
52
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
53
|
+
});
|
|
54
|
+
it("[REQ-MAINT-REPORT] should return empty string when no operations", () => {
|
|
55
|
+
const report = (0, report_1.generateMaintenanceReport)(tmpDir);
|
|
56
|
+
expect(report).toBe("");
|
|
57
|
+
});
|
|
58
|
+
it("[REQ-MAINT-REPORT] should report stale story annotation", () => {
|
|
59
|
+
const filePath = path.join(tmpDir, "stub.md");
|
|
60
|
+
const content = `/**
|
|
61
|
+
* @story non-existent.md
|
|
62
|
+
*/`;
|
|
63
|
+
fs.writeFileSync(filePath, content);
|
|
64
|
+
const report = (0, report_1.generateMaintenanceReport)(tmpDir);
|
|
65
|
+
expect(report).toContain("non-existent.md");
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,66 @@
|
|
|
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/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
38
|
+
* @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
39
|
+
* @req REQ-MAINT-UPDATE - Update annotation references
|
|
40
|
+
*/
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const os = __importStar(require("os"));
|
|
44
|
+
const update_1 = require("../../src/maintenance/update");
|
|
45
|
+
describe("updateAnnotationReferences isolated (Story 009.0-DEV-MAINTENANCE-TOOLS)", () => {
|
|
46
|
+
it("[REQ-MAINT-UPDATE] updates @story annotations in files", () => {
|
|
47
|
+
// Create a temporary directory for testing
|
|
48
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "tmp-"));
|
|
49
|
+
const filePath = path.join(tmpDir, "file.ts");
|
|
50
|
+
const originalContent = `
|
|
51
|
+
/**
|
|
52
|
+
* @story old.path.md
|
|
53
|
+
*/
|
|
54
|
+
function foo() {}
|
|
55
|
+
`;
|
|
56
|
+
fs.writeFileSync(filePath, originalContent, "utf8");
|
|
57
|
+
// Run the function under test
|
|
58
|
+
const count = (0, update_1.updateAnnotationReferences)(tmpDir, "old.path.md", "new.path.md");
|
|
59
|
+
expect(count).toBe(1);
|
|
60
|
+
// Verify the file content was updated
|
|
61
|
+
const updatedContent = fs.readFileSync(filePath, "utf8");
|
|
62
|
+
expect(updatedContent).toContain("@story new.path.md");
|
|
63
|
+
// Cleanup temporary directory
|
|
64
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
65
|
+
});
|
|
66
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
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/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
8
|
+
* @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
9
|
+
* @req REQ-MAINT-UPDATE - Update annotation references
|
|
10
|
+
*/
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const os_1 = __importDefault(require("os"));
|
|
13
|
+
const path_1 = __importDefault(require("path"));
|
|
14
|
+
const update_1 = require("../../src/maintenance/update");
|
|
15
|
+
describe("updateAnnotationReferences (Story 009.0-DEV-MAINTENANCE-TOOLS)", () => {
|
|
16
|
+
it("[REQ-MAINT-UPDATE] should return 0 when no updates made", () => {
|
|
17
|
+
const tmpDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), "update-test-"));
|
|
18
|
+
try {
|
|
19
|
+
const count = (0, update_1.updateAnnotationReferences)(tmpDir, "old.md", "new.md");
|
|
20
|
+
expect(count).toBe(0);
|
|
21
|
+
}
|
|
22
|
+
finally {
|
|
23
|
+
fs_1.default.rmSync(tmpDir, { recursive: true, force: true });
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
});
|