Skip to content

Commit 7491a3d

Browse files
committed
test(linter/plugins): improve test isolation (#16009)
Use a `beforeEach` hook to reset internal state and set `sourceText` before each test. In tests which need to use a different `sourceText`, they can just set it to a different string before calling any token methods. This makes isolation of all tests automatic, and avoids a problem where one test's assetions failing could result in `resetSourceAndAst()` not getting called to set `sourceText` back to the "standard" value before the end of the test function. This could cause unrelated test failures.
1 parent 9e61beb commit 7491a3d

File tree

1 file changed

+13
-35
lines changed

1 file changed

+13
-35
lines changed

apps/oxlint/test/tokens.test.ts

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import assert from 'node:assert';
2-
import { describe, it, vi } from 'vitest';
2+
import { beforeEach, describe, it, vi } from 'vitest';
33
import {
44
getTokens,
55
getTokensBefore,
@@ -22,7 +22,11 @@ import {
2222
import { resetSourceAndAst } from '../src-js/plugins/source_code.js';
2323
import type { Node } from '../src-js/plugins/types.js';
2424

25-
let sourceText = '/*A*/var answer/*B*/=/*C*/a/*D*/* b/*E*///F\n call();\n/*Z*/';
25+
// Source text used for most tests
26+
const SOURCE_TEXT = '/*A*/var answer/*B*/=/*C*/a/*D*/* b/*E*///F\n call();\n/*Z*/';
27+
28+
// Mock `source_code.ts` to inject source text from `sourceText` defined here
29+
let sourceText: string;
2630

2731
vi.mock('../src-js/plugins/source_code.ts', async (importOriginal) => {
2832
const original: any = await importOriginal();
@@ -31,14 +35,16 @@ vi.mock('../src-js/plugins/source_code.ts', async (importOriginal) => {
3135
get sourceText() {
3236
return sourceText;
3337
},
34-
resetSourceAndAst() {
35-
// TODO: refactor this quick fix to get the tests working
36-
original.resetSourceAndAst();
37-
sourceText = '/*A*/var answer/*B*/=/*C*/a/*D*/* b/*E*///F\n call();\n/*Z*/';
38-
},
3938
};
4039
});
4140

41+
// Reset global state and set source text to `SOURCE_TEXT` before each test.
42+
// Individual tests can set `sourceText` to a different value if required before calling token methods.
43+
beforeEach(() => {
44+
resetSourceAndAst();
45+
sourceText = SOURCE_TEXT;
46+
});
47+
4248
// TODO: We are lying about `Program`'s range here.
4349
// The range provided by `@typescript-eslint/typescript-estree` does not match the assertions for that of `espree`.
4450
// The deviation is being corrected in upcoming releases of ESLint and TS-ESLint.
@@ -283,33 +289,24 @@ describe('when calling getTokenBefore', () => {
283289
});
284290

285291
it('should retrieve the previous node if the comment at the end of source code is specified.', () => {
286-
resetSourceAndAst();
287292
sourceText = 'a + b /*comment*/';
288293
// TODO: this verbatim range should be replaced with `ast.comments[0]`
289294
const token = getTokenBefore({ range: [6, 17] } as Node);
290-
291295
assert.strictEqual(token!.value, 'b');
292-
resetSourceAndAst();
293296
});
294297

295298
it('should retrieve the previous comment if the first token is specified.', () => {
296-
resetSourceAndAst();
297299
sourceText = '/*comment*/ a + b';
298300
// TODO: this verbatim range should be replaced with `ast.tokens[0]`
299301
const token = getTokenBefore({ range: [12, 13] } as Node, { includeComments: true });
300-
301302
assert.strictEqual(token!.value, 'comment');
302-
resetSourceAndAst();
303303
});
304304

305305
it('should retrieve null if the first comment is specified.', () => {
306-
resetSourceAndAst();
307306
sourceText = '/*comment*/ a + b';
308307
// TODO: this verbatim range should be replaced with `ast.comments[0]`
309308
const token = getTokenBefore({ range: [0, 11] } as Node, { includeComments: true });
310-
311309
assert.strictEqual(token, null);
312-
resetSourceAndAst();
313310
});
314311
});
315312

@@ -380,37 +377,28 @@ describe('when calling getTokenAfter', () => {
380377
});
381378

382379
it('should retrieve the next node if the comment at the first of source code is specified.', () => {
383-
resetSourceAndAst();
384380
sourceText = '/*comment*/ a + b';
385381
// TODO: replace this verbatim range with `ast.comments[0]`
386382
const token = getTokenAfter({ range: [0, 12] } as Node)!;
387-
388383
assert.strictEqual(token.value, 'a');
389-
resetSourceAndAst();
390384
});
391385

392386
it('should retrieve the next comment if the last token is specified.', () => {
393-
resetSourceAndAst();
394387
sourceText = 'a + b /*comment*/';
395388
// TODO: replace this verbatim range with `ast.tokens[2]`
396389
const token = getTokenAfter({ range: [4, 5] } as Node, {
397390
includeComments: true,
398391
});
399-
400392
assert.strictEqual(token!.value, 'comment');
401-
resetSourceAndAst();
402393
});
403394

404395
it('should retrieve null if the last comment is specified.', () => {
405-
resetSourceAndAst();
406396
sourceText = 'a + b /*comment*/';
407397
// TODO: replace this verbatim range with `ast.comments[0]`
408398
const token = getTokenAfter({ range: [6, 17] } as Node, {
409399
includeComments: true,
410400
});
411-
412401
assert.strictEqual(token, null);
413-
resetSourceAndAst();
414402
});
415403
});
416404

@@ -654,7 +642,6 @@ describe('when calling getFirstToken', () => {
654642
});
655643

656644
it('should retrieve the first comment if the comment is at the last of nodes', () => {
657-
resetSourceAndAst();
658645
sourceText = 'a + b\n/*comment*/ c + d';
659646
/*
660647
* A node must not start with a token: it can start with a comment or be empty.
@@ -668,11 +655,9 @@ describe('when calling getFirstToken', () => {
668655
)!.value,
669656
'comment',
670657
);
671-
resetSourceAndAst();
672658
});
673659

674660
it('should retrieve the first token (without includeComments option) if the comment is at the last of nodes', () => {
675-
resetSourceAndAst();
676661
sourceText = 'a + b\n/*comment*/ c + d';
677662
/*
678663
* A node must not start with a token: it can start with a comment or be empty.
@@ -685,19 +670,15 @@ describe('when calling getFirstToken', () => {
685670
} as Node)!.value,
686671
'c',
687672
);
688-
resetSourceAndAst();
689673
});
690674

691675
it('should retrieve the first token if the root node contains a trailing comment', () => {
692-
resetSourceAndAst();
693676
sourceText = 'foo // comment';
694677
// TODO: this verbatim range should be replaced with `ast`
695678
assert.strictEqual(getFirstToken({ range: [0, 14] } as Node)!.value, 'foo');
696-
resetSourceAndAst();
697679
});
698680

699681
it('should return null if the source contains only comments', () => {
700-
resetSourceAndAst();
701682
sourceText = '// comment';
702683
// TODO: this verbatim range should be replaced with `ast`
703684
assert.strictEqual(
@@ -708,15 +689,12 @@ describe('when calling getFirstToken', () => {
708689
}),
709690
null,
710691
);
711-
resetSourceAndAst();
712692
});
713693

714694
it('should return null if the source is empty', () => {
715-
resetSourceAndAst();
716695
sourceText = '';
717696
// TODO: this verbatim range should be replaced with `ast`
718697
assert.strictEqual(getFirstToken({ range: [0, 0] } as Node), null);
719-
resetSourceAndAst();
720698
});
721699
});
722700

0 commit comments

Comments
 (0)