@sarj/eslint-plugin 16.35.0 → 16.36.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/dist/{_docs-Bq5OCcWF.d.cts → _docs-IZjowAEc.d.cts} +21 -1
- package/dist/{_docs-Bq5OCcWF.d.ts → _docs-IZjowAEc.d.ts} +21 -1
- package/dist/index.cjs +341 -337
- package/dist/index.d.cts +175 -502
- package/dist/index.d.ts +175 -502
- package/dist/index.js +341 -337
- package/dist/rule-examples.cjs +49 -0
- package/dist/rule-examples.js +49 -0
- package/package.json +1 -1
package/dist/rule-examples.cjs
CHANGED
|
@@ -125,6 +125,9 @@ async function verifyExample(linter, config, example, root, ruleId) {
|
|
|
125
125
|
if (messages.length !== example.expectedCount) {
|
|
126
126
|
throw new Error(`${example.id}: expected ${example.expectedCount} findings, received ${messages.length}`);
|
|
127
127
|
}
|
|
128
|
+
if (example.expectedDiagnostics !== void 0) {
|
|
129
|
+
verifyExpectedDiagnostics(example, messages, focus.source, lines);
|
|
130
|
+
}
|
|
128
131
|
for (const expected of example.fixedFiles ?? []) {
|
|
129
132
|
const input = example.files.find((file) => file.path === expected.path);
|
|
130
133
|
if (input === void 0) throw new Error(`${example.id}: fixed file has no original`);
|
|
@@ -138,6 +141,52 @@ async function verifyExample(linter, config, example, root, ruleId) {
|
|
|
138
141
|
}
|
|
139
142
|
}
|
|
140
143
|
}
|
|
144
|
+
function verifyExpectedDiagnostics(example, messages, source, lines) {
|
|
145
|
+
const expectations = example.expectedDiagnostics ?? [];
|
|
146
|
+
if (expectations.some((item) => !physicalExpectedLocation(item.location, lines))) {
|
|
147
|
+
throw new Error(`${example.id}: invalid expected diagnostic location`);
|
|
148
|
+
}
|
|
149
|
+
const expected = expectations.map(expectedDiagnosticKey).sort();
|
|
150
|
+
const actual = messages.map((message) => JSON.stringify([
|
|
151
|
+
message.messageId,
|
|
152
|
+
message.message,
|
|
153
|
+
[message.line, message.column, message.endLine, message.endColumn],
|
|
154
|
+
message.fix !== void 0,
|
|
155
|
+
(message.suggestions ?? []).map((suggestion) => [
|
|
156
|
+
suggestion.messageId,
|
|
157
|
+
applySuggestion(source, suggestion.fix, example.id)
|
|
158
|
+
])
|
|
159
|
+
])).sort();
|
|
160
|
+
if (JSON.stringify(actual) !== JSON.stringify(expected)) {
|
|
161
|
+
throw new Error(`${example.id}: unexpected diagnostics
|
|
162
|
+
expected: ${JSON.stringify(expected)}
|
|
163
|
+
received: ${JSON.stringify(actual)}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
function expectedDiagnosticKey(expected) {
|
|
167
|
+
return JSON.stringify([
|
|
168
|
+
expected.messageId,
|
|
169
|
+
expected.message,
|
|
170
|
+
[expected.location.line, expected.location.column, expected.location.end?.line, expected.location.end?.column],
|
|
171
|
+
expected.automaticFix,
|
|
172
|
+
expected.suggestions.map((suggestion) => [suggestion.messageId, suggestion.output])
|
|
173
|
+
]);
|
|
174
|
+
}
|
|
175
|
+
function applySuggestion(source, fix, exampleId) {
|
|
176
|
+
const bom = source.startsWith("\uFEFF") ? "\uFEFF" : "";
|
|
177
|
+
const text = bom === "" ? source : source.slice(1);
|
|
178
|
+
const [start, end] = fix.range;
|
|
179
|
+
if (!Number.isSafeInteger(start) || !Number.isSafeInteger(end) || start > end || start < (bom === "" ? 0 : -1) || end < 0 || end > text.length) {
|
|
180
|
+
throw new Error(`${exampleId}: invalid suggestion edit range`);
|
|
181
|
+
}
|
|
182
|
+
const prefix = start < 0 && end >= 0 || start === 0 && fix.text.startsWith("\uFEFF") ? "" : bom;
|
|
183
|
+
return prefix + text.slice(0, Math.max(0, start)) + fix.text + text.slice(end);
|
|
184
|
+
}
|
|
185
|
+
function physicalExpectedLocation(location, lines) {
|
|
186
|
+
if (!physicalPosition(lines, location.line, location.column)) return false;
|
|
187
|
+
if (location.end === void 0) return true;
|
|
188
|
+
return physicalPosition(lines, location.end.line, location.end.column) && (location.end.line > location.line || location.end.line === location.line && location.end.column >= location.column);
|
|
189
|
+
}
|
|
141
190
|
function physicalDiagnosticLocation(message, lines) {
|
|
142
191
|
if (!physicalPosition(lines, message.line, message.column)) return false;
|
|
143
192
|
if (message.endLine === void 0 && message.endColumn === void 0) return true;
|
package/dist/rule-examples.js
CHANGED
|
@@ -91,6 +91,9 @@ async function verifyExample(linter, config, example, root, ruleId) {
|
|
|
91
91
|
if (messages.length !== example.expectedCount) {
|
|
92
92
|
throw new Error(`${example.id}: expected ${example.expectedCount} findings, received ${messages.length}`);
|
|
93
93
|
}
|
|
94
|
+
if (example.expectedDiagnostics !== void 0) {
|
|
95
|
+
verifyExpectedDiagnostics(example, messages, focus.source, lines);
|
|
96
|
+
}
|
|
94
97
|
for (const expected of example.fixedFiles ?? []) {
|
|
95
98
|
const input = example.files.find((file) => file.path === expected.path);
|
|
96
99
|
if (input === void 0) throw new Error(`${example.id}: fixed file has no original`);
|
|
@@ -104,6 +107,52 @@ async function verifyExample(linter, config, example, root, ruleId) {
|
|
|
104
107
|
}
|
|
105
108
|
}
|
|
106
109
|
}
|
|
110
|
+
function verifyExpectedDiagnostics(example, messages, source, lines) {
|
|
111
|
+
const expectations = example.expectedDiagnostics ?? [];
|
|
112
|
+
if (expectations.some((item) => !physicalExpectedLocation(item.location, lines))) {
|
|
113
|
+
throw new Error(`${example.id}: invalid expected diagnostic location`);
|
|
114
|
+
}
|
|
115
|
+
const expected = expectations.map(expectedDiagnosticKey).sort();
|
|
116
|
+
const actual = messages.map((message) => JSON.stringify([
|
|
117
|
+
message.messageId,
|
|
118
|
+
message.message,
|
|
119
|
+
[message.line, message.column, message.endLine, message.endColumn],
|
|
120
|
+
message.fix !== void 0,
|
|
121
|
+
(message.suggestions ?? []).map((suggestion) => [
|
|
122
|
+
suggestion.messageId,
|
|
123
|
+
applySuggestion(source, suggestion.fix, example.id)
|
|
124
|
+
])
|
|
125
|
+
])).sort();
|
|
126
|
+
if (JSON.stringify(actual) !== JSON.stringify(expected)) {
|
|
127
|
+
throw new Error(`${example.id}: unexpected diagnostics
|
|
128
|
+
expected: ${JSON.stringify(expected)}
|
|
129
|
+
received: ${JSON.stringify(actual)}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function expectedDiagnosticKey(expected) {
|
|
133
|
+
return JSON.stringify([
|
|
134
|
+
expected.messageId,
|
|
135
|
+
expected.message,
|
|
136
|
+
[expected.location.line, expected.location.column, expected.location.end?.line, expected.location.end?.column],
|
|
137
|
+
expected.automaticFix,
|
|
138
|
+
expected.suggestions.map((suggestion) => [suggestion.messageId, suggestion.output])
|
|
139
|
+
]);
|
|
140
|
+
}
|
|
141
|
+
function applySuggestion(source, fix, exampleId) {
|
|
142
|
+
const bom = source.startsWith("\uFEFF") ? "\uFEFF" : "";
|
|
143
|
+
const text = bom === "" ? source : source.slice(1);
|
|
144
|
+
const [start, end] = fix.range;
|
|
145
|
+
if (!Number.isSafeInteger(start) || !Number.isSafeInteger(end) || start > end || start < (bom === "" ? 0 : -1) || end < 0 || end > text.length) {
|
|
146
|
+
throw new Error(`${exampleId}: invalid suggestion edit range`);
|
|
147
|
+
}
|
|
148
|
+
const prefix = start < 0 && end >= 0 || start === 0 && fix.text.startsWith("\uFEFF") ? "" : bom;
|
|
149
|
+
return prefix + text.slice(0, Math.max(0, start)) + fix.text + text.slice(end);
|
|
150
|
+
}
|
|
151
|
+
function physicalExpectedLocation(location, lines) {
|
|
152
|
+
if (!physicalPosition(lines, location.line, location.column)) return false;
|
|
153
|
+
if (location.end === void 0) return true;
|
|
154
|
+
return physicalPosition(lines, location.end.line, location.end.column) && (location.end.line > location.line || location.end.line === location.line && location.end.column >= location.column);
|
|
155
|
+
}
|
|
107
156
|
function physicalDiagnosticLocation(message, lines) {
|
|
108
157
|
if (!physicalPosition(lines, message.line, message.column)) return false;
|
|
109
158
|
if (message.endLine === void 0 && message.endColumn === void 0) return true;
|