Skip to content

Commit 026b1fb

Browse files
committed
fix: resolve all biome lint warnings with recommended rules
- Enable biome recommended rules with zero rule-level exceptions - Fix noNonNullAssertion (44 places) with guard clauses and fallbacks - Convert forEach to for...of loops (useIterableCallbackReturn) - Convert static-only classes to plain objects (noStaticOnlyClass) - Fix noAccumulatingSpread with push-based loops - Extract VS Code placeholder strings to placeholders.ts (noTemplateCurlyInString) - Fix noAssignInExpressions, noExplicitAny, and other minor warnings - Add __mocks__ override for mock-specific lint exceptions
1 parent 1ce995b commit 026b1fb

File tree

82 files changed

+1093
-690
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+1093
-690
lines changed

__mocks__/vscode.ts

Lines changed: 98 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
1-
import { vi } from 'vitest';
1+
import { readFile } from 'node:fs/promises';
22
import { glob } from 'glob';
33
import { minimatch } from 'minimatch';
4-
import { readFile } from 'node:fs/promises';
5-
import {
6-
CancellationToken, DocumentFilter, MarkdownString, TestController, TestCoverageCount, TestItem, TestItemCollection,
7-
TestRunRequest as BaseTestRunRequest, TestTag, TextDocument, WorkspaceFolder,
4+
import { vi } from 'vitest';
5+
import type {
6+
TestRunRequest as BaseTestRunRequest,
7+
CancellationToken,
8+
DocumentFilter,
9+
MarkdownString,
10+
TestController,
11+
TestCoverageCount,
12+
TestItem,
13+
TestItemCollection,
14+
TestTag,
15+
TextDocument,
16+
WorkspaceFolder,
817
} from 'vscode';
918
import { URI } from 'vscode-uri';
1019

@@ -83,7 +92,9 @@ class FakeTestItemCollection implements Iterable<[id: string, testItem: TestItem
8392

8493
replace(items: readonly TestItem[]) {
8594
this.items.clear();
86-
items.forEach((item) => this.add(item));
95+
for (const item of items) {
96+
this.add(item);
97+
}
8798
}
8899

89100
forEach(
@@ -111,16 +122,18 @@ const createTestItem = vi
111122

112123
const createRunProfile = vi
113124
.fn()
114-
.mockImplementation((
115-
label: string,
116-
kind: TestRunProfileKind,
117-
runHandler: (
118-
request: BaseTestRunRequest,
119-
token: CancellationToken,
120-
) => Thenable<void> | void,
121-
isDefault?: boolean,
122-
tag?: TestTag,
123-
) => ({ label, kind, isDefault, tag, runHandler }));
125+
.mockImplementation(
126+
(
127+
label: string,
128+
kind: TestRunProfileKind,
129+
runHandler: (
130+
request: BaseTestRunRequest,
131+
token: CancellationToken,
132+
) => Thenable<void> | void,
133+
isDefault?: boolean,
134+
tag?: TestTag,
135+
) => ({ label, kind, isDefault, tag, runHandler }),
136+
);
124137

125138
const createTestRun = vi
126139
.fn()
@@ -175,25 +188,37 @@ class Disposable {
175188
}
176189

177190
class FakeLocation {
178-
constructor(public uri: URI, public range: any) {}
191+
constructor(
192+
public uri: URI,
193+
public range: any,
194+
) {}
179195
}
180196
const Location = FakeLocation;
181197

182198
class FakeRange {
183-
constructor(public start: any, public end: any) {}
199+
constructor(
200+
public start: any,
201+
public end: any,
202+
) {}
184203
}
185204
const Range = FakeRange;
186205

187206
class Position {
188-
constructor(public line: number, public character: number) {}
207+
constructor(
208+
public line: number,
209+
public character: number,
210+
) {}
189211

190212
translate(lineDelta?: number, characterDelta?: number) {
191213
return new Position(this.line + (lineDelta ?? 0), characterDelta ?? this.character);
192214
}
193215
}
194216

195217
class FakeDocumentLink {
196-
constructor(public range: any, public target?: URI) {}
218+
constructor(
219+
public range: any,
220+
public target?: URI,
221+
) {}
197222
}
198223
const DocumentLink = FakeDocumentLink;
199224

@@ -210,7 +235,9 @@ class FakeCancellationTokenSource {
210235

211236
cancel() {
212237
this.token.isCancellationRequested = true;
213-
this.listeners.forEach((fn) => fn());
238+
for (const fn of this.listeners) {
239+
fn();
240+
}
214241
}
215242

216243
dispose() {}
@@ -223,7 +250,7 @@ export class Configuration {
223250
constructor(items: Map<string, unknown> | { [p: string]: string } | undefined = undefined) {
224251
if (items instanceof Map) {
225252
this.items = items;
226-
} else if (!!items) {
253+
} else if (items) {
227254
for (const x in items) {
228255
this.items.set(x, items[x]);
229256
}
@@ -261,25 +288,33 @@ const workspace = {
261288
uri.toString().includes(folder.uri.toString()),
262289
);
263290
},
264-
findFiles: Object.assign(vi.fn().mockImplementation(async (pattern, exclude: any | undefined) => {
265-
workspace.findFiles._concurrentCount++;
266-
workspace.findFiles._maxConcurrent = Math.max(
267-
workspace.findFiles._maxConcurrent,
268-
workspace.findFiles._concurrentCount,
269-
);
270-
try {
271-
const splitPattern = (pattern: string) => {
272-
return pattern.replace(/^{|}$/g, '').split(',').map((v) => v.trim());
273-
};
274-
return (await glob(splitPattern(pattern.pattern), {
275-
absolute: true,
276-
ignore: exclude ? splitPattern(exclude.pattern) : undefined,
277-
cwd: pattern.uri.fsPath,
278-
})).map((file) => URI.file(file.replace(/^\w:/, (matched) => matched.toLowerCase())));
279-
} finally {
280-
workspace.findFiles._concurrentCount--;
281-
}
282-
}), { _concurrentCount: 0, _maxConcurrent: 0 }),
291+
findFiles: Object.assign(
292+
vi.fn().mockImplementation(async (pattern, exclude: any | undefined) => {
293+
workspace.findFiles._concurrentCount++;
294+
workspace.findFiles._maxConcurrent = Math.max(
295+
workspace.findFiles._maxConcurrent,
296+
workspace.findFiles._concurrentCount,
297+
);
298+
try {
299+
const splitPattern = (pattern: string) => {
300+
return pattern
301+
.replace(/^{|}$/g, '')
302+
.split(',')
303+
.map((v) => v.trim());
304+
};
305+
return (
306+
await glob(splitPattern(pattern.pattern), {
307+
absolute: true,
308+
ignore: exclude ? splitPattern(exclude.pattern) : undefined,
309+
cwd: pattern.uri.fsPath,
310+
})
311+
).map((file) => URI.file(file.replace(/^\w:/, (matched) => matched.toLowerCase())));
312+
} finally {
313+
workspace.findFiles._concurrentCount--;
314+
}
315+
}),
316+
{ _concurrentCount: 0, _maxConcurrent: 0 },
317+
),
283318
createFileSystemWatcher: vi.fn().mockImplementation(() => {
284319
return {
285320
onDidCreate: vi.fn(),
@@ -342,13 +377,15 @@ const window = {
342377
showQuickPick: vi.fn(),
343378
};
344379

345-
const commands = (function () {
380+
const commands = (() => {
346381
const commands = new Map<string, (...rest: any[]) => void>();
347382
return {
348-
registerCommand: vi.fn().mockImplementation((command: string, callback: (...rest: any[]) => void) => {
349-
commands.set(command, callback);
350-
return new Disposable();
351-
}),
383+
registerCommand: vi
384+
.fn()
385+
.mockImplementation((command: string, callback: (...rest: any[]) => void) => {
386+
commands.set(command, callback);
387+
return new Disposable();
388+
}),
352389
executeCommand: async (command: string, ...rest: any[]) => {
353390
return commands.get(command)!(...rest);
354391
},
@@ -364,7 +401,9 @@ class FakeEventEmitter<T = void> {
364401
};
365402

366403
fire(data: T) {
367-
this.listeners.forEach((fn) => fn(data));
404+
for (const fn of this.listeners) {
405+
fn(data);
406+
}
368407
}
369408

370409
dispose() {
@@ -381,15 +420,24 @@ const extensions = {
381420
};
382421

383422
class FileCoverage {
384-
constructor(public uri: URI, public statementCoverage: TestCoverageCount) {}
423+
constructor(
424+
public uri: URI,
425+
public statementCoverage: TestCoverageCount,
426+
) {}
385427
}
386428

387429
class TestCoverageCount {
388-
constructor(public covered: number, public total: number) {}
430+
constructor(
431+
public covered: number,
432+
public total: number,
433+
) {}
389434
}
390435

391436
class StatementCoverage {
392-
constructor(public executed: number | boolean, public location: any) {}
437+
constructor(
438+
public executed: number | boolean,
439+
public location: any,
440+
) {}
393441
}
394442

395443
const debug = {

biome.json

Lines changed: 15 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,34 @@
11
{
22
"$schema": "https://biomejs.dev/schemas/2.3.15/schema.json",
3-
"vcs": {
4-
"enabled": true,
5-
"clientKind": "git",
6-
"useIgnoreFile": true
7-
},
3+
"vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true },
84
"files": {
95
"includes": ["**", "!**/out", "!**/dist", "!**/coverage", "!**/.vscode-test", "!**/*.d.ts"]
106
},
11-
"formatter": {
12-
"indentStyle": "space",
13-
"indentWidth": 4,
14-
"lineWidth": 100
15-
},
7+
"formatter": { "indentStyle": "space", "indentWidth": 4, "lineWidth": 100 },
168
"javascript": {
17-
"parser": {
18-
"unsafeParameterDecoratorsEnabled": true
19-
},
20-
"formatter": {
21-
"quoteStyle": "single",
22-
"trailingCommas": "all"
23-
}
9+
"parser": { "unsafeParameterDecoratorsEnabled": true },
10+
"formatter": { "quoteStyle": "single", "trailingCommas": "all" }
2411
},
2512
"linter": {
2613
"rules": {
27-
"style": {
28-
"noNonNullAssertion": "warn"
29-
},
30-
"complexity": {
31-
"noStaticOnlyClass": "warn",
32-
"noBannedTypes": "warn"
33-
},
34-
"performance": {
35-
"noAccumulatingSpread": "warn"
36-
},
37-
"suspicious": {
38-
"noDoubleEquals": "warn",
39-
"noExplicitAny": "error",
40-
"noNonNullAssertedOptionalChain": "warn",
41-
"useIterableCallbackReturn": "warn",
42-
"noDuplicateTestHooks": "warn",
43-
"noAssignInExpressions": "warn",
44-
"noImplicitAnyLet": "warn",
45-
"noExportsInTest": "warn",
46-
"noTemplateCurlyInString": "warn"
47-
},
48-
"correctness": {
49-
"noUnusedVariables": "warn",
50-
"noUnusedImports": "warn",
51-
"noUnsafeOptionalChaining": "warn"
52-
}
14+
"recommended": true
5315
}
5416
},
5517
"overrides": [
5618
{
57-
"includes": ["**/*.test.ts"],
19+
"includes": ["**/*.test.ts", "**/test/**"],
5820
"linter": {
5921
"rules": {
6022
"suspicious": { "noConsole": "off", "noExportsInTest": "off" },
61-
"correctness": { "noUnusedFunctionParameters": "off" },
23+
"correctness": { "noUnusedFunctionParameters": "off" }
24+
}
25+
}
26+
},
27+
{
28+
"includes": ["**/__mocks__/**"],
29+
"linter": {
30+
"rules": {
31+
"suspicious": { "noExplicitAny": "off", "noRedeclare": "off" },
6232
"style": { "noNonNullAssertion": "off" }
6333
}
6434
}

src/Commands/PHPUnitLinkProvider.test.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import { relative } from 'node:path';
22
import { beforeEach, describe, expect, it } from 'vitest';
3-
import { type CancellationToken, type DocumentLink, Position, Range, type TextDocument as VscodeTextDocument } from 'vscode';
3+
import {
4+
type CancellationToken,
5+
type DocumentLink,
6+
Position,
7+
Range,
8+
type TextDocument as VscodeTextDocument,
9+
} from 'vscode';
410
import { PHPUnitXML } from '../PHPUnit';
511
import { phpUnitProject } from '../PHPUnit/__tests__/utils';
612
import { PHPUnitLinkProvider } from './PHPUnitLinkProvider';
@@ -67,7 +73,7 @@ MockeryExceptionInvalidCountException: Method test(<Any Arguments>) from Mockery
6773
document as unknown as VscodeTextDocument,
6874
{} as unknown as CancellationToken,
6975
) as DocumentLink[]
70-
).map((link) => [normalizePath(link.target!.fsPath), link.target!.fragment]);
76+
).map((link) => [normalizePath(link.target?.fsPath), link.target?.fragment]);
7177

7278
expect(links).toEqual([
7379
['vendor/mockery/mockery/library/Mockery/CountValidator/Exact.php', 'L32'],
@@ -125,7 +131,7 @@ at src/Calculator.php:7
125131
document as unknown as VscodeTextDocument,
126132
{} as unknown as CancellationToken,
127133
) as DocumentLink[]
128-
).map((link) => [normalizePath(link.target!.fsPath), link.target!.fragment]);
134+
).map((link) => [normalizePath(link.target?.fsPath), link.target?.fragment]);
129135

130136
expect(links).toEqual([
131137
['src/Calculator.php', 'L7'],

src/Commands/PHPUnitLinkProvider.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
type TextDocument,
99
} from 'vscode';
1010
import { URI } from 'vscode-uri';
11-
import { PHPUnitXML } from '../PHPUnit';
11+
import type { PHPUnitXML } from '../PHPUnit';
1212

1313
export class PHPUnitLinkProvider implements DocumentLinkProvider {
1414
private regex = /((?:[A-Z]:)?(?:\.{0,2}[\\/])?[^\s:]+\.php):(\d+)(?::(\d+))?/gi;
@@ -26,7 +26,11 @@ export class PHPUnitLinkProvider implements DocumentLinkProvider {
2626
const line = document.lineAt(lineIndex);
2727
let match: RegExpExecArray | null;
2828

29-
while ((match = this.regex.exec(line.text)) !== null) {
29+
while (true) {
30+
match = this.regex.exec(line.text);
31+
if (match === null) {
32+
break;
33+
}
3034
const [fullMatch, filePath, lineStr] = match;
3135
const lineNumber = parseInt(lineStr, 10);
3236

0 commit comments

Comments
 (0)