eslint-plugin-traceability 1.4.9 → 1.4.10
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.
|
@@ -35,16 +35,63 @@ function validateStoryPath(opts) {
|
|
|
35
35
|
requireExt,
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Report any problems related to the existence or accessibility of the
|
|
40
|
+
* referenced story file. Filesystem and I/O errors are surfaced with a
|
|
41
|
+
* dedicated diagnostic that differentiates them from missing files.
|
|
42
|
+
*
|
|
43
|
+
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
44
|
+
* @req REQ-FILE-EXISTENCE - Ensure referenced files exist
|
|
45
|
+
* @req REQ-ERROR-HANDLING - Differentiate missing files from filesystem errors
|
|
46
|
+
*/
|
|
47
|
+
function reportExistenceProblems(opts) {
|
|
48
|
+
const { storyPath, commentNode, context, cwd, storyDirs } = opts;
|
|
49
|
+
const result = (0, storyReferenceUtils_1.normalizeStoryPath)(storyPath, cwd, storyDirs);
|
|
50
|
+
const existenceResult = result.existence;
|
|
51
|
+
if (!existenceResult || existenceResult.status === "exists") {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (existenceResult.status === "missing") {
|
|
55
|
+
context.report({
|
|
56
|
+
node: commentNode,
|
|
57
|
+
messageId: "fileMissing",
|
|
58
|
+
data: { path: storyPath },
|
|
59
|
+
});
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (existenceResult.status === "fs-error") {
|
|
63
|
+
const rawError = existenceResult.error;
|
|
64
|
+
let errorMessage;
|
|
65
|
+
if (rawError == null) {
|
|
66
|
+
errorMessage = "Unknown filesystem error";
|
|
67
|
+
}
|
|
68
|
+
else if (rawError instanceof Error) {
|
|
69
|
+
errorMessage = rawError.message;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
errorMessage = String(rawError);
|
|
73
|
+
}
|
|
74
|
+
context.report({
|
|
75
|
+
node: commentNode,
|
|
76
|
+
messageId: "fileAccessError",
|
|
77
|
+
data: {
|
|
78
|
+
path: storyPath,
|
|
79
|
+
error: errorMessage,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
38
84
|
/**
|
|
39
85
|
* Process and validate the story path for security, extension, and existence.
|
|
40
86
|
* Filesystem and I/O errors are handled inside the underlying utilities
|
|
41
|
-
* (e.g. storyExists) and surfaced as missing-file
|
|
87
|
+
* (e.g. storyExists) and surfaced as missing-file or filesystem-error
|
|
88
|
+
* diagnostics where appropriate.
|
|
42
89
|
*
|
|
43
90
|
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
44
91
|
* @req REQ-FILE-EXISTENCE - Validate that story file paths reference existing files
|
|
45
92
|
* @req REQ-PATH-RESOLUTION - Resolve relative paths correctly and enforce configuration
|
|
46
93
|
* @req REQ-SECURITY-VALIDATION - Prevent path traversal and absolute path usage
|
|
47
|
-
* @req REQ-ERROR-HANDLING - Delegate filesystem and I/O error handling to utilities
|
|
94
|
+
* @req REQ-ERROR-HANDLING - Delegate filesystem and I/O error handling to utilities and differentiate error types
|
|
48
95
|
*/
|
|
49
96
|
function processStoryPath(opts) {
|
|
50
97
|
const { storyPath, commentNode, context, cwd, storyDirs, allowAbsolute, requireExt, } = opts;
|
|
@@ -80,16 +127,22 @@ function processStoryPath(opts) {
|
|
|
80
127
|
});
|
|
81
128
|
return;
|
|
82
129
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
130
|
+
/**
|
|
131
|
+
* Existence check:
|
|
132
|
+
* - Distinguish between missing files and filesystem errors.
|
|
133
|
+
* - Filesystem and I/O errors are surfaced with a dedicated diagnostic.
|
|
134
|
+
*
|
|
135
|
+
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
136
|
+
* @req REQ-FILE-EXISTENCE - Ensure referenced files exist
|
|
137
|
+
* @req REQ-ERROR-HANDLING - Differentiate missing files from filesystem errors
|
|
138
|
+
*/
|
|
139
|
+
reportExistenceProblems({
|
|
140
|
+
storyPath,
|
|
141
|
+
commentNode,
|
|
142
|
+
context,
|
|
143
|
+
cwd,
|
|
144
|
+
storyDirs,
|
|
145
|
+
});
|
|
93
146
|
}
|
|
94
147
|
/**
|
|
95
148
|
* Handle a single comment node by processing its lines.
|
|
@@ -130,6 +183,11 @@ exports.default = {
|
|
|
130
183
|
fileMissing: "Story file '{{path}}' not found",
|
|
131
184
|
invalidExtension: "Invalid story file extension for '{{path}}', expected '.story.md'",
|
|
132
185
|
invalidPath: "Invalid story path '{{path}}'",
|
|
186
|
+
/**
|
|
187
|
+
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
188
|
+
* @req REQ-ERROR-HANDLING - Provide clear diagnostics for filesystem errors
|
|
189
|
+
*/
|
|
190
|
+
fileAccessError: "Could not validate story file '{{path}}' due to a filesystem error: {{error}}. Please check file existence and permissions.",
|
|
133
191
|
},
|
|
134
192
|
schema: [
|
|
135
193
|
{
|
|
@@ -153,7 +211,7 @@ exports.default = {
|
|
|
153
211
|
/**
|
|
154
212
|
* Program-level handler: iterate comments and validate @story annotations.
|
|
155
213
|
* Filesystem and I/O errors are handled by underlying utilities and
|
|
156
|
-
* surfaced as missing-file diagnostics where appropriate.
|
|
214
|
+
* surfaced as missing-file or filesystem-error diagnostics where appropriate.
|
|
157
215
|
*
|
|
158
216
|
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
159
217
|
* @req REQ-ANNOTATION-VALIDATION - Discover and dispatch @story annotations for validation
|
|
@@ -1,22 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Describes the possible existence states for a checked path.
|
|
3
|
+
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
4
|
+
* @req REQ-FILE-EXISTENCE - Validate that story file paths reference existing files
|
|
5
|
+
* @req REQ-ERROR-HANDLING - Handle filesystem errors gracefully without throwing
|
|
6
|
+
* @req REQ-PERFORMANCE-OPTIMIZATION - Cache filesystem checks to avoid redundant work
|
|
7
|
+
*/
|
|
8
|
+
export type StoryExistenceStatus = "exists" | "missing" | "fs-error";
|
|
9
|
+
/**
|
|
10
|
+
* Result of checking a single candidate path.
|
|
11
|
+
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
12
|
+
* @req REQ-FILE-EXISTENCE - Validate that story file paths reference existing files
|
|
13
|
+
* @req REQ-ERROR-HANDLING - Handle filesystem errors gracefully without throwing
|
|
14
|
+
* @req REQ-PERFORMANCE-OPTIMIZATION - Cache filesystem checks to avoid redundant work
|
|
15
|
+
*/
|
|
16
|
+
export interface StoryPathCheckResult {
|
|
17
|
+
path: string;
|
|
18
|
+
status: StoryExistenceStatus;
|
|
19
|
+
error?: unknown;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Aggregated existence result across multiple candidate paths.
|
|
23
|
+
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
24
|
+
* @req REQ-FILE-EXISTENCE - Validate that story file paths reference existing files
|
|
25
|
+
* @req REQ-ERROR-HANDLING - Handle filesystem errors gracefully without throwing
|
|
26
|
+
* @req REQ-PERFORMANCE-OPTIMIZATION - Cache filesystem checks to avoid redundant work
|
|
27
|
+
*/
|
|
28
|
+
export interface StoryExistenceResult {
|
|
29
|
+
candidates: string[];
|
|
30
|
+
status: StoryExistenceStatus;
|
|
31
|
+
matchedPath?: string;
|
|
32
|
+
error?: unknown;
|
|
33
|
+
}
|
|
1
34
|
/**
|
|
2
35
|
* Build candidate file paths for a given story path.
|
|
3
36
|
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
4
37
|
* @req REQ-PATH-RESOLUTION - Resolve relative paths correctly and enforce configuration
|
|
5
38
|
*/
|
|
6
39
|
export declare function buildStoryCandidates(storyPath: string, cwd: string, storyDirs: string[]): string[];
|
|
40
|
+
/**
|
|
41
|
+
* Aggregate existence status across multiple candidate paths.
|
|
42
|
+
* Returns the first successful match (`exists`), or, if none exist,
|
|
43
|
+
* the first filesystem error encountered. If there are only missing
|
|
44
|
+
* candidates, returns a missing status.
|
|
45
|
+
*
|
|
46
|
+
* This function never throws and is the preferred richer API for callers
|
|
47
|
+
* that need more than a boolean.
|
|
48
|
+
*
|
|
49
|
+
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
50
|
+
* @req REQ-FILE-EXISTENCE - Validate that story file paths reference existing files
|
|
51
|
+
* @req REQ-ERROR-HANDLING - Handle filesystem errors gracefully without throwing
|
|
52
|
+
* @req REQ-PERFORMANCE-OPTIMIZATION - Cache filesystem checks to avoid redundant work
|
|
53
|
+
*/
|
|
54
|
+
export declare function getStoryExistence(candidates: string[]): StoryExistenceResult;
|
|
55
|
+
/**
|
|
56
|
+
* Check if any of the provided file paths exist.
|
|
57
|
+
* Handles filesystem errors (e.g., EACCES) gracefully by treating them as non-existent
|
|
58
|
+
* and never throwing.
|
|
59
|
+
*
|
|
60
|
+
* Internally delegates to the richer status-based helper while preserving the
|
|
61
|
+
* original boolean-only API for backwards compatibility.
|
|
62
|
+
*
|
|
63
|
+
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
64
|
+
* @req REQ-FILE-EXISTENCE - Validate that story file paths reference existing files
|
|
65
|
+
* @req REQ-ERROR-HANDLING - Handle filesystem errors gracefully without throwing
|
|
66
|
+
* @req REQ-PERFORMANCE-OPTIMIZATION - Cache filesystem checks to avoid redundant work
|
|
67
|
+
*/
|
|
7
68
|
export declare function storyExists(paths: string[]): boolean;
|
|
8
69
|
/**
|
|
9
70
|
* Normalize a story path to candidate absolute paths and check existence.
|
|
10
|
-
* Filesystem errors are handled via
|
|
11
|
-
* and treats such cases as non-existent
|
|
71
|
+
* Filesystem errors are handled via the status-aware helper, which suppresses
|
|
72
|
+
* exceptions and treats such cases as non-existent for the boolean flag while
|
|
73
|
+
* still surfacing error details in the status field.
|
|
74
|
+
*
|
|
12
75
|
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
13
76
|
* @req REQ-PATH-RESOLUTION - Resolve relative paths correctly and enforce configuration
|
|
14
77
|
* @req REQ-FILE-EXISTENCE - Validate that story file paths reference existing files
|
|
15
78
|
* @req REQ-ERROR-HANDLING - Handle filesystem errors gracefully without throwing
|
|
79
|
+
* @req REQ-PERFORMANCE-OPTIMIZATION - Cache filesystem checks to avoid redundant work
|
|
16
80
|
*/
|
|
17
81
|
export declare function normalizeStoryPath(storyPath: string, cwd: string, storyDirs: string[]): {
|
|
18
82
|
candidates: string[];
|
|
19
83
|
exists: boolean;
|
|
84
|
+
existence: StoryExistenceResult;
|
|
20
85
|
};
|
|
21
86
|
/**
|
|
22
87
|
* Check if the provided path is absolute.
|
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.buildStoryCandidates = buildStoryCandidates;
|
|
7
|
+
exports.getStoryExistence = getStoryExistence;
|
|
7
8
|
exports.storyExists = storyExists;
|
|
8
9
|
exports.normalizeStoryPath = normalizeStoryPath;
|
|
9
10
|
exports.isAbsolutePath = isAbsolutePath;
|
|
@@ -40,45 +41,126 @@ function buildStoryCandidates(storyPath, cwd, storyDirs) {
|
|
|
40
41
|
return candidates;
|
|
41
42
|
}
|
|
42
43
|
/**
|
|
43
|
-
*
|
|
44
|
-
* Handles filesystem errors (e.g., EACCES) gracefully by treating them as non-existent
|
|
45
|
-
* and never throwing.
|
|
44
|
+
* Cache of filesystem existence checks keyed by absolute path.
|
|
46
45
|
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
47
46
|
* @req REQ-FILE-EXISTENCE - Validate that story file paths reference existing files
|
|
48
47
|
* @req REQ-ERROR-HANDLING - Handle filesystem errors gracefully without throwing
|
|
48
|
+
* @req REQ-PERFORMANCE-OPTIMIZATION - Cache filesystem checks to avoid redundant work
|
|
49
49
|
*/
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
const fileExistStatusCache = new Map();
|
|
51
|
+
/**
|
|
52
|
+
* Check a single candidate path, with caching and robust error handling.
|
|
53
|
+
* All filesystem interactions are wrapped in try/catch and never throw.
|
|
54
|
+
*
|
|
55
|
+
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
56
|
+
* @req REQ-FILE-EXISTENCE - Validate that story file paths reference existing files
|
|
57
|
+
* @req REQ-ERROR-HANDLING - Handle filesystem errors gracefully without throwing
|
|
58
|
+
* @req REQ-PERFORMANCE-OPTIMIZATION - Cache filesystem checks to avoid redundant work
|
|
59
|
+
*/
|
|
60
|
+
function checkSingleCandidate(candidate) {
|
|
61
|
+
const cached = fileExistStatusCache.get(candidate);
|
|
62
|
+
if (cached) {
|
|
63
|
+
return cached;
|
|
64
|
+
}
|
|
65
|
+
let result;
|
|
66
|
+
try {
|
|
67
|
+
const exists = fs_1.default.existsSync(candidate);
|
|
68
|
+
if (!exists) {
|
|
69
|
+
result = { path: candidate, status: "missing" };
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
const stat = fs_1.default.statSync(candidate);
|
|
73
|
+
if (stat.isFile()) {
|
|
74
|
+
result = { path: candidate, status: "exists" };
|
|
57
75
|
}
|
|
58
|
-
|
|
59
|
-
|
|
76
|
+
else {
|
|
77
|
+
// Path exists but is not a file; treat as missing for story purposes.
|
|
78
|
+
result = { path: candidate, status: "missing" };
|
|
60
79
|
}
|
|
61
|
-
fileExistCache.set(candidate, ok);
|
|
62
80
|
}
|
|
63
|
-
|
|
64
|
-
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
// Any filesystem error is captured and surfaced as fs-error.
|
|
84
|
+
result = { path: candidate, status: "fs-error", error };
|
|
85
|
+
}
|
|
86
|
+
fileExistStatusCache.set(candidate, result);
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Aggregate existence status across multiple candidate paths.
|
|
91
|
+
* Returns the first successful match (`exists`), or, if none exist,
|
|
92
|
+
* the first filesystem error encountered. If there are only missing
|
|
93
|
+
* candidates, returns a missing status.
|
|
94
|
+
*
|
|
95
|
+
* This function never throws and is the preferred richer API for callers
|
|
96
|
+
* that need more than a boolean.
|
|
97
|
+
*
|
|
98
|
+
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
99
|
+
* @req REQ-FILE-EXISTENCE - Validate that story file paths reference existing files
|
|
100
|
+
* @req REQ-ERROR-HANDLING - Handle filesystem errors gracefully without throwing
|
|
101
|
+
* @req REQ-PERFORMANCE-OPTIMIZATION - Cache filesystem checks to avoid redundant work
|
|
102
|
+
*/
|
|
103
|
+
function getStoryExistence(candidates) {
|
|
104
|
+
let firstFsError;
|
|
105
|
+
for (const candidate of candidates) {
|
|
106
|
+
const res = checkSingleCandidate(candidate);
|
|
107
|
+
if (res.status === "exists") {
|
|
108
|
+
return {
|
|
109
|
+
candidates,
|
|
110
|
+
status: "exists",
|
|
111
|
+
matchedPath: res.path,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
if (res.status === "fs-error" && !firstFsError) {
|
|
115
|
+
firstFsError = res;
|
|
65
116
|
}
|
|
66
117
|
}
|
|
67
|
-
|
|
118
|
+
if (firstFsError) {
|
|
119
|
+
return {
|
|
120
|
+
candidates,
|
|
121
|
+
status: "fs-error",
|
|
122
|
+
error: firstFsError.error,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
candidates,
|
|
127
|
+
status: "missing",
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Check if any of the provided file paths exist.
|
|
132
|
+
* Handles filesystem errors (e.g., EACCES) gracefully by treating them as non-existent
|
|
133
|
+
* and never throwing.
|
|
134
|
+
*
|
|
135
|
+
* Internally delegates to the richer status-based helper while preserving the
|
|
136
|
+
* original boolean-only API for backwards compatibility.
|
|
137
|
+
*
|
|
138
|
+
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
139
|
+
* @req REQ-FILE-EXISTENCE - Validate that story file paths reference existing files
|
|
140
|
+
* @req REQ-ERROR-HANDLING - Handle filesystem errors gracefully without throwing
|
|
141
|
+
* @req REQ-PERFORMANCE-OPTIMIZATION - Cache filesystem checks to avoid redundant work
|
|
142
|
+
*/
|
|
143
|
+
function storyExists(paths) {
|
|
144
|
+
const result = getStoryExistence(paths);
|
|
145
|
+
return result.status === "exists";
|
|
68
146
|
}
|
|
69
147
|
/**
|
|
70
148
|
* Normalize a story path to candidate absolute paths and check existence.
|
|
71
|
-
* Filesystem errors are handled via
|
|
72
|
-
* and treats such cases as non-existent
|
|
149
|
+
* Filesystem errors are handled via the status-aware helper, which suppresses
|
|
150
|
+
* exceptions and treats such cases as non-existent for the boolean flag while
|
|
151
|
+
* still surfacing error details in the status field.
|
|
152
|
+
*
|
|
73
153
|
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
74
154
|
* @req REQ-PATH-RESOLUTION - Resolve relative paths correctly and enforce configuration
|
|
75
155
|
* @req REQ-FILE-EXISTENCE - Validate that story file paths reference existing files
|
|
76
156
|
* @req REQ-ERROR-HANDLING - Handle filesystem errors gracefully without throwing
|
|
157
|
+
* @req REQ-PERFORMANCE-OPTIMIZATION - Cache filesystem checks to avoid redundant work
|
|
77
158
|
*/
|
|
78
159
|
function normalizeStoryPath(storyPath, cwd, storyDirs) {
|
|
79
160
|
const candidates = buildStoryCandidates(storyPath, cwd, storyDirs);
|
|
80
|
-
const
|
|
81
|
-
|
|
161
|
+
const existence = getStoryExistence(candidates);
|
|
162
|
+
const exists = existence.status === "exists";
|
|
163
|
+
return { candidates, exists, existence };
|
|
82
164
|
}
|
|
83
165
|
/**
|
|
84
166
|
* Check if the provided path is absolute.
|
|
@@ -68,6 +68,37 @@ describe("Valid Story Reference Rule (Story 006.0-DEV-FILE-VALIDATION)", () => {
|
|
|
68
68
|
],
|
|
69
69
|
});
|
|
70
70
|
});
|
|
71
|
+
/**
|
|
72
|
+
* Helper to run the valid-story-reference rule against a single source string
|
|
73
|
+
* and collect reported diagnostics.
|
|
74
|
+
*
|
|
75
|
+
* @req REQ-ERROR-HANDLING - Used to verify fileAccessError reporting behavior
|
|
76
|
+
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
77
|
+
*/
|
|
78
|
+
function runRuleOnCode(code) {
|
|
79
|
+
const messages = [];
|
|
80
|
+
const context = {
|
|
81
|
+
report: (descriptor) => {
|
|
82
|
+
messages.push(descriptor);
|
|
83
|
+
},
|
|
84
|
+
getSourceCode: () => ({
|
|
85
|
+
text: code,
|
|
86
|
+
getAllComments: () => [
|
|
87
|
+
{
|
|
88
|
+
type: "Line",
|
|
89
|
+
value: code.replace(/^\/\//, "").trim(),
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
}),
|
|
93
|
+
options: [],
|
|
94
|
+
parserOptions: { ecmaVersion: 2020 },
|
|
95
|
+
};
|
|
96
|
+
const listeners = valid_story_reference_1.default.create(context);
|
|
97
|
+
if (typeof listeners.Program === "function") {
|
|
98
|
+
listeners.Program({});
|
|
99
|
+
}
|
|
100
|
+
return messages;
|
|
101
|
+
}
|
|
71
102
|
describe("Valid Story Reference Rule Error Handling (Story 006.0-DEV-FILE-VALIDATION)", () => {
|
|
72
103
|
/**
|
|
73
104
|
* @req REQ-ERROR-HANDLING - Verify storyExists swallows fs errors and returns false
|
|
@@ -92,4 +123,26 @@ describe("Valid Story Reference Rule Error Handling (Story 006.0-DEV-FILE-VALIDA
|
|
|
92
123
|
expect(() => (0, storyReferenceUtils_1.storyExists)(["docs/stories/permission-denied.story.md"])).not.toThrow();
|
|
93
124
|
expect((0, storyReferenceUtils_1.storyExists)(["docs/stories/permission-denied.story.md"])).toBe(false);
|
|
94
125
|
});
|
|
126
|
+
/**
|
|
127
|
+
* @req REQ-ERROR-HANDLING - Verify rule reports fileAccessError when filesystem operations fail
|
|
128
|
+
* instead of treating it as a missing file.
|
|
129
|
+
* @story docs/stories/006.0-DEV-FILE-VALIDATION.story.md
|
|
130
|
+
*/
|
|
131
|
+
it("[REQ-ERROR-HANDLING] rule reports fileAccessError when fs throws", () => {
|
|
132
|
+
const accessError = new Error("EACCES: permission denied while accessing");
|
|
133
|
+
accessError.code = "EACCES";
|
|
134
|
+
jest.spyOn(fs, "existsSync").mockImplementation(() => {
|
|
135
|
+
throw accessError;
|
|
136
|
+
});
|
|
137
|
+
jest.spyOn(fs, "statSync").mockImplementation(() => {
|
|
138
|
+
throw accessError;
|
|
139
|
+
});
|
|
140
|
+
const diagnostics = runRuleOnCode(`// @story docs/stories/fs-error.story.md`);
|
|
141
|
+
expect(diagnostics.length).toBeGreaterThan(0);
|
|
142
|
+
const fileAccessDiagnostics = diagnostics.filter((d) => d.messageId === "fileAccessError");
|
|
143
|
+
expect(fileAccessDiagnostics.length).toBeGreaterThan(0);
|
|
144
|
+
const errorData = fileAccessDiagnostics[0].data;
|
|
145
|
+
expect(errorData).toBeDefined();
|
|
146
|
+
expect(String(errorData.error)).toMatch(/EACCES/i);
|
|
147
|
+
});
|
|
95
148
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-traceability",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.10",
|
|
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",
|