Thanks to visit codestin.com
Credit goes to github.com

Skip to content

chore(parser): finish migrating to vitest #11191

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@
"markdownlint-cli": "^0.44.0",
"nx": "20.7.2",
"prettier": "3.5.0",
"pretty-format": "^29.7.0",
"rimraf": "^5.0.5",
"semver": "7.7.0",
"tsx": "*",
Expand All @@ -116,7 +115,6 @@
"@types/react": "^18.2.14",
"eslint-plugin-eslint-plugin@^5.5.0": "patch:eslint-plugin-eslint-plugin@npm%3A5.5.1#./.yarn/patches/eslint-plugin-eslint-plugin-npm-5.5.1-4206c2506d.patch",
"prettier": "3.5.0",
"pretty-format": "^29",
"react-split-pane@^0.1.92": "patch:react-split-pane@npm%3A0.1.92#./.yarn/patches/react-split-pane-npm-0.1.92-93dbf51dff.patch",
"tmp": "0.2.1",
"tsx": "^4.7.2",
Expand Down
3 changes: 1 addition & 2 deletions packages/parser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@
],
"scripts": {
"build": "tsc -b tsconfig.build.json",
"clean": "tsc -b tsconfig.build.json --clean",
"postclean": "rimraf dist/ coverage/",
"clean": "rimraf dist/ coverage/",
"format": "prettier --write \"./**/*.{ts,mts,cts,tsx,js,mjs,cjs,jsx,json,md,css}\" --ignore-path ../../.prettierignore",
"lint": "npx nx lint",
"test": "vitest --run --config=$INIT_CWD/vitest.config.mts",
Expand Down
24 changes: 15 additions & 9 deletions packages/parser/tests/lib/parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,30 @@ import type { ParserOptions } from '@typescript-eslint/types';

import * as scopeManager from '@typescript-eslint/scope-manager';
import * as typescriptESTree from '@typescript-eslint/typescript-estree';
import path from 'node:path';
import { ScriptTarget } from 'typescript';

import { parse, parseForESLint } from '../../src/parser';
import { parse, parseForESLint } from '../../src/parser.js';
import { FIXTURES_DIR } from '../test-utils/test-utils.js';

describe('parser', () => {
beforeEach(() => {
afterEach(() => {
vi.clearAllMocks();
});

afterAll(() => {
vi.restoreAllMocks();
});

it('parse() should return just the AST from parseForESLint()', () => {
const code = 'const valid = true;';
expect(parse(code)).toEqual(parseForESLint(code).ast);
expect(parse(code)).toStrictEqual(parseForESLint(code).ast);
});

it('parseForESLint() should work if options are `null`', () => {
const code = 'const valid = true;';
expect(() => parseForESLint(code, null)).not.toThrow();
expect(() => {
parseForESLint(code, null);
}).not.toThrow();
});

it('parseAndGenerateServices() should be called with options', () => {
Expand All @@ -36,7 +42,7 @@ describe('parser', () => {
extraFileExtensions: ['.foo'],
filePath: './isolated-file.src.ts',
project: 'tsconfig.json',
tsconfigRootDir: path.join(__dirname, '..', 'fixtures', 'services'),
tsconfigRootDir: FIXTURES_DIR,
};
parseForESLint(code, config);
expect(spy).toHaveBeenCalledExactlyOnceWith(code, {
Expand Down Expand Up @@ -107,7 +113,7 @@ describe('parser', () => {
errorOnTypeScriptSyntacticAndSemanticIssues: false,
filePath: 'isolated-file.src.ts',
project: 'tsconfig.json',
tsconfigRootDir: path.join(__dirname, '..', 'fixtures', 'services'),
tsconfigRootDir: FIXTURES_DIR,
};

parseForESLint(code, config);
Expand Down Expand Up @@ -141,7 +147,7 @@ describe('parser', () => {
const config: ParserOptions = {
filePath: 'isolated-file.src.ts',
project: 'tsconfig.json',
tsconfigRootDir: path.join(__dirname, '..', 'fixtures', 'services'),
tsconfigRootDir: FIXTURES_DIR,
};

vi.spyOn(
Expand Down Expand Up @@ -185,7 +191,7 @@ describe('parser', () => {
extraFileExtensions: ['.foo'],
filePath: 'isolated-file.src.ts',
project: 'tsconfig.json',
tsconfigRootDir: path.join(__dirname, '..', 'fixtures', 'services'),
tsconfigRootDir: FIXTURES_DIR,
};

parseForESLint(code, config);
Expand Down
65 changes: 33 additions & 32 deletions packages/parser/tests/lib/services.test.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,58 @@
import { createProgram } from '@typescript-eslint/typescript-estree';
import * as glob from 'glob';
import fs from 'node:fs/promises';
import path from 'node:path';

import type { ParserOptions } from '../../src/parser';
import * as fs from 'node:fs/promises';
import * as path from 'node:path';

import { parseForESLint } from '../../src/index.js';
import {
createSnapshotTestBlock,
formatSnapshotName,
testServices,
} from '../test-utils/test-utils';
createConfig,
FIXTURES_DIR,
getRaw,
} from '../test-utils/test-utils.js';

//------------------------------------------------------------------------------
// Setup
//------------------------------------------------------------------------------

const FIXTURES_DIR = path.join(
__dirname,
'..',
'..',
'tests',
'fixtures',
'services',
);
const testFiles = glob.sync(`**/*.src.ts`, {
const testFiles = glob.sync('**/*.src.ts', {
absolute: true,
cwd: FIXTURES_DIR,
});

function createConfig(filename: string): ParserOptions {
return {
filePath: filename,
project: './tsconfig.json',
tsconfigRootDir: path.resolve(FIXTURES_DIR),
};
}

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

const program = createProgram(path.resolve(FIXTURES_DIR, 'tsconfig.json'));
const program = createProgram(path.join(FIXTURES_DIR, 'tsconfig.json'));

describe.for(testFiles)('services', async filename => {
const code = await fs.readFile(path.join(FIXTURES_DIR, filename), {
const code = await fs.readFile(filename, {
encoding: 'utf-8',
});
const config = createConfig(filename);
const snapshotName = formatSnapshotName(filename, FIXTURES_DIR, '.ts');
it(snapshotName, createSnapshotTestBlock(code, config));

const { base, name } = path.parse(filename);

const config = createConfig(base);

const snapshotName = path.posix.join('fixtures', name);

it(snapshotName, () => {
const { ast } = parseForESLint(code, config);

const result = getRaw(ast);

expect(result).toMatchSnapshot();
});

it(`${snapshotName} services`, () => {
testServices(code, config);
const { services } = parseForESLint(code, config);

assert.isNotNull(services.program);
});

it(`${snapshotName} services with provided program`, () => {
testServices(code, { ...config, program });
const { services } = parseForESLint(code, { ...config, program });

assert.isNotNull(services.program);
});
});
38 changes: 20 additions & 18 deletions packages/parser/tests/lib/tsx.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { parseForESLint } from '../../src/parser';
import { serializer } from '../test-utils/ts-error-serializer';
import { parseForESLint } from '../../src/index.js';
import { serializer } from '../test-utils/ts-error-serializer.js';

//------------------------------------------------------------------------------
// Tests
Expand All @@ -12,7 +12,9 @@ describe('TSX', () => {
it('filePath was not provided', () => {
const code = 'const element = <T/>';

expect(() => parseForESLint(code)).toThrowErrorMatchingInlineSnapshot(`
expect(() => {
parseForESLint(code);
}).toThrowErrorMatchingInlineSnapshot(`
TSError {
"column": 18,
"index": 18,
Expand All @@ -24,22 +26,22 @@ describe('TSX', () => {

it("filePath was not provided and 'jsx:true' option", () => {
const code = 'const element = <T/>';
expect(() =>
expect(() => {
parseForESLint(code, {
ecmaFeatures: {
jsx: true,
},
}),
).not.toThrow();
});
}).not.toThrow();
});

it('test.ts', () => {
const code = 'const element = <T/>';
expect(() =>
expect(() => {
parseForESLint(code, {
filePath: 'test.ts',
}),
).toThrowErrorMatchingInlineSnapshot(`
});
}).toThrowErrorMatchingInlineSnapshot(`
TSError {
"column": 18,
"index": 18,
Expand All @@ -52,14 +54,14 @@ describe('TSX', () => {
it("test.ts with 'jsx:true' option", () => {
const code = 'const element = <T/>';

expect(() =>
expect(() => {
parseForESLint(code, {
ecmaFeatures: {
jsx: true,
},
filePath: 'test.ts',
}),
).toThrowErrorMatchingInlineSnapshot(`
});
}).toThrowErrorMatchingInlineSnapshot(`
TSError {
"column": 18,
"index": 18,
Expand All @@ -71,23 +73,23 @@ describe('TSX', () => {

it('test.tsx', () => {
const code = 'const element = <T/>';
expect(() =>
expect(() => {
parseForESLint(code, {
filePath: 'test.tsx',
}),
).not.toThrow();
});
}).not.toThrow();
});

it("test.tsx with 'jsx:false' option", () => {
const code = 'const element = <T/>';
expect(() =>
expect(() => {
parseForESLint(code, {
ecmaFeatures: {
jsx: false,
},
filePath: 'test.tsx',
}),
).not.toThrow();
});
}).not.toThrow();
});
});
});
84 changes: 16 additions & 68 deletions packages/parser/tests/test-utils/test-utils.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,35 @@
import type { ParserOptions } from '@typescript-eslint/types';
import type { TSESTree } from '@typescript-eslint/typescript-estree';

import type { ParserOptions } from '../../src/parser';
import * as path from 'node:path';

import * as parser from '../../src/parser';
export const FIXTURES_DIR = path.join(__dirname, '..', 'fixtures', 'services');

const defaultConfig = {
const DEFAULT_PARSER_OPTIONS = {
comment: true,
errorOnUnknownASTType: true,
loc: true,
range: true,
raw: true,
sourceType: 'module' as const,
sourceType: 'module',
tokens: true,
};
} as const satisfies ParserOptions;

export function createConfig(filename: string): ParserOptions {
return {
...DEFAULT_PARSER_OPTIONS,
filePath: filename,
project: './tsconfig.json',
tsconfigRootDir: FIXTURES_DIR,
};
}

/**
* Returns a raw copy of the given AST
* @param ast the AST object
* @returns copy of the AST object
*/
function getRaw(ast: TSESTree.Program): TSESTree.Program {
export function getRaw(ast: TSESTree.Program): TSESTree.Program {
return JSON.parse(
JSON.stringify(ast, (key, value) => {
if ((key === 'start' || key === 'end') && typeof value === 'number') {
Expand All @@ -29,65 +39,3 @@ function getRaw(ast: TSESTree.Program): TSESTree.Program {
}),
);
}

/**
* Returns a function which can be used as the callback of a Jest test() block,
* and which performs an assertion on the snapshot for the given code and config.
* @param code The source code to parse
* @param config the parser configuration
* @returns callback for Jest test() block
*/
export function createSnapshotTestBlock(
code: string,
config: ParserOptions = {},
): () => void {
config = { ...defaultConfig, ...config };

/**
* @returns the AST object
*/
function parse(): TSESTree.Program {
const ast = parser.parseForESLint(code, config).ast;
return getRaw(ast);
}

return (): void => {
try {
const result = parse();
expect(result).toMatchSnapshot();
} catch (error) {
/**
* If we are deliberately throwing because of encountering an unknown
* AST_NODE_TYPE, we rethrow to cause the test to fail
*/
if ((error as Error).message.includes('Unknown AST_NODE_TYPE')) {
throw error;
}
expect(parse).toThrowErrorMatchingSnapshot();
}
};
}

/**
* @param code The code being parsed
* @param config The configuration object for the parser
*/
export function testServices(code: string, config: ParserOptions = {}): void {
config = { ...defaultConfig, ...config };

const services = parser.parseForESLint(code, config).services;
expect(services).toBeDefined();
expect(services.program).toBeDefined();
expect(services.esTreeNodeToTSNodeMap).toBeDefined();
expect(services.tsNodeToESTreeNodeMap).toBeDefined();
}

export function formatSnapshotName(
filename: string,
fixturesDir: string,
fileExtension = '.js',
): string {
return `fixtures/${filename
.replace(`${fixturesDir}/`, '')
.replace(fileExtension, '')}`;
}
Loading