diff --git a/package.json b/package.json
index 20b013dab04d..a51cd0073937 100644
--- a/package.json
+++ b/package.json
@@ -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": "*",
@@ -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",
diff --git a/packages/parser/package.json b/packages/parser/package.json
index 6fb66eac1ae8..ca32c3eb4d7e 100644
--- a/packages/parser/package.json
+++ b/packages/parser/package.json
@@ -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",
diff --git a/packages/parser/tests/lib/parser.test.ts b/packages/parser/tests/lib/parser.test.ts
index 39c072a8d42e..a36d76c11edd 100644
--- a/packages/parser/tests/lib/parser.test.ts
+++ b/packages/parser/tests/lib/parser.test.ts
@@ -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', () => {
@@ -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, {
@@ -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);
@@ -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(
@@ -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);
diff --git a/packages/parser/tests/lib/services.test.ts b/packages/parser/tests/lib/services.test.ts
index 3719c7127e82..5db0a81f44fb 100644
--- a/packages/parser/tests/lib/services.test.ts
+++ b/packages/parser/tests/lib/services.test.ts
@@ -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);
});
});
diff --git a/packages/parser/tests/lib/tsx.test.ts b/packages/parser/tests/lib/tsx.test.ts
index f58a859f41f7..ad7d5c8fd7f3 100644
--- a/packages/parser/tests/lib/tsx.test.ts
+++ b/packages/parser/tests/lib/tsx.test.ts
@@ -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
@@ -12,7 +12,9 @@ describe('TSX', () => {
it('filePath was not provided', () => {
const code = 'const element = ';
- expect(() => parseForESLint(code)).toThrowErrorMatchingInlineSnapshot(`
+ expect(() => {
+ parseForESLint(code);
+ }).toThrowErrorMatchingInlineSnapshot(`
TSError {
"column": 18,
"index": 18,
@@ -24,22 +26,22 @@ describe('TSX', () => {
it("filePath was not provided and 'jsx:true' option", () => {
const code = 'const element = ';
- expect(() =>
+ expect(() => {
parseForESLint(code, {
ecmaFeatures: {
jsx: true,
},
- }),
- ).not.toThrow();
+ });
+ }).not.toThrow();
});
it('test.ts', () => {
const code = 'const element = ';
- expect(() =>
+ expect(() => {
parseForESLint(code, {
filePath: 'test.ts',
- }),
- ).toThrowErrorMatchingInlineSnapshot(`
+ });
+ }).toThrowErrorMatchingInlineSnapshot(`
TSError {
"column": 18,
"index": 18,
@@ -52,14 +54,14 @@ describe('TSX', () => {
it("test.ts with 'jsx:true' option", () => {
const code = 'const element = ';
- expect(() =>
+ expect(() => {
parseForESLint(code, {
ecmaFeatures: {
jsx: true,
},
filePath: 'test.ts',
- }),
- ).toThrowErrorMatchingInlineSnapshot(`
+ });
+ }).toThrowErrorMatchingInlineSnapshot(`
TSError {
"column": 18,
"index": 18,
@@ -71,23 +73,23 @@ describe('TSX', () => {
it('test.tsx', () => {
const code = 'const element = ';
- expect(() =>
+ expect(() => {
parseForESLint(code, {
filePath: 'test.tsx',
- }),
- ).not.toThrow();
+ });
+ }).not.toThrow();
});
it("test.tsx with 'jsx:false' option", () => {
const code = 'const element = ';
- expect(() =>
+ expect(() => {
parseForESLint(code, {
ecmaFeatures: {
jsx: false,
},
filePath: 'test.tsx',
- }),
- ).not.toThrow();
+ });
+ }).not.toThrow();
});
});
});
diff --git a/packages/parser/tests/test-utils/test-utils.ts b/packages/parser/tests/test-utils/test-utils.ts
index a286f9df4a86..1177c5923236 100644
--- a/packages/parser/tests/test-utils/test-utils.ts
+++ b/packages/parser/tests/test-utils/test-utils.ts
@@ -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') {
@@ -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, '')}`;
-}
diff --git a/packages/parser/tests/test-utils/ts-error-serializer.ts b/packages/parser/tests/test-utils/ts-error-serializer.ts
index 9c9acca97eee..98eb146ce27d 100644
--- a/packages/parser/tests/test-utils/ts-error-serializer.ts
+++ b/packages/parser/tests/test-utils/ts-error-serializer.ts
@@ -1,8 +1,8 @@
-import type { Plugin } from 'pretty-format';
+import type { SnapshotSerializer } from 'vitest';
import { TSError } from '@typescript-eslint/typescript-estree';
-export const serializer: Plugin = {
+export const serializer: SnapshotSerializer = {
serialize(val: TSError, config, indentation, depth, refs, printer) {
const format = (value: unknown): string =>
printer(value, config, indentation, depth + 1, refs);
diff --git a/yarn.lock b/yarn.lock
index c51e1648780d..89d54984e2db 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5739,7 +5739,6 @@ __metadata:
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: "*"
@@ -16047,7 +16046,7 @@ __metadata:
languageName: node
linkType: hard
-"pretty-format@npm:^29":
+"pretty-format@npm:^29.7.0":
version: 29.7.0
resolution: "pretty-format@npm:29.7.0"
dependencies: