Skip to content

Commit

Permalink
test(typescript-estree): separate snapshots for ast tests (#2290)
Browse files Browse the repository at this point in the history
  • Loading branch information
bradzacher committed Jul 17, 2020
1 parent 9458130 commit 2eb3ca4
Show file tree
Hide file tree
Showing 859 changed files with 341,926 additions and 365,931 deletions.
6 changes: 2 additions & 4 deletions .eslintrc.js
Expand Up @@ -161,11 +161,9 @@ module.exports = {
// all test files
{
files: [
'packages/eslint-plugin-internal/tests/**/*.test.ts',
'packages/eslint-plugin-tslint/tests/**/*.ts',
'packages/eslint-plugin/tests/**/*.test.ts',
'packages/*/tests/**/*.test.ts',
'packages/*/tests/**/*.spec.ts',
'packages/parser/tests/**/*.ts',
'packages/typescript-estree/tests/**/*.ts',
],
env: {
'jest/globals': true,
Expand Down
5 changes: 5 additions & 0 deletions package.json
Expand Up @@ -69,6 +69,8 @@
"@commitlint/cli": "^8.3.5",
"@commitlint/config-conventional": "^8.3.4",
"@commitlint/config-lerna-scopes": "^8.3.4",
"@types/glob": "^7.1.1",
"@types/jest-specific-snapshot": "^0.5.4",
"@types/jest": "^25.2.1",
"@types/node": "^13.13.5",
"@types/prettier": "^2.0.0",
Expand All @@ -82,11 +84,14 @@
"eslint-plugin-eslint-plugin": "^2.2.1",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-jest": "^23.10.0",
"glob": "^7.1.6",
"husky": "^4.2.5",
"isomorphic-fetch": "^2.2.1",
"jest": "^25.5.4",
"jest-specific-snapshot": "^3.0.0",
"lerna": "^3.20.2",
"lint-staged": "^10.2.2",
"make-dir": "^3.1.0",
"markdownlint-cli": "^0.23.0",
"prettier": "^2.0.5",
"rimraf": "^3.0.2",
Expand Down
8 changes: 3 additions & 5 deletions packages/scope-manager/package.json
Expand Up @@ -42,12 +42,10 @@
"@typescript-eslint/visitor-keys": "3.6.1"
},
"devDependencies": {
"@types/jest-specific-snapshot": "^0.5.4",
"@types/mkdirp": "^1.0.0",
"@typescript-eslint/typescript-estree": "3.6.1",
"glob": "^7.1.6",
"jest-specific-snapshot": "^3.0.0",
"make-dir": "^3.1.0",
"glob": "*",
"jest-specific-snapshot": "*",
"make-dir": "*",
"prettier": "*",
"pretty-format": "^25.5.0",
"rimraf": "*",
Expand Down
2 changes: 1 addition & 1 deletion packages/scope-manager/tests/eslint-scope/label.test.ts
Expand Up @@ -47,7 +47,7 @@ describe('label', () => {
expectToBeGlobalScope(scope);
expect(scope.variables).toHaveLength(1);
expect(scope.variables[0].name).toBe('foo');
expect(scope.through.length).toBe(3);
expect(scope.through).toHaveLength(3);
expect(scope.through[2].identifier.name).toBe('foo');
expect(scope.through[2].isRead()).toBeTruthy();

Expand Down
21 changes: 21 additions & 0 deletions packages/scope-manager/tests/fixtures.test.ts
Expand Up @@ -145,6 +145,7 @@ function nestDescribe(
};

if ([...fixture.segments, fixture.name].join(path.sep) === ONLY) {
// eslint-disable-next-line jest/no-focused-tests
it.only(fixture.name, test);
} else {
it(fixture.name, test);
Expand All @@ -153,3 +154,23 @@ function nestDescribe(
}

fixtures.forEach(f => nestDescribe(f));

if (ONLY === '') {
// ensure that the snapshots are cleaned up, because jest-specific-snapshot won't do this check
const snapshots = glob.sync(`${FIXTURES_DIR}/**/*.shot`).map(absolute => {
const relative = path.relative(FIXTURES_DIR, absolute);
const { name, dir } = path.parse(relative);
return {
relative,
fixturePath: path.join(FIXTURES_DIR, dir, name),
};
});

describe('ast snapshots should have an associated test', () => {
for (const snap of snapshots) {
it(snap.relative, () => {
fs.existsSync(snap.fixturePath);
});
}
});
}
2 changes: 1 addition & 1 deletion packages/scope-manager/tests/lib.test.ts
Expand Up @@ -8,7 +8,7 @@ describe('implicit lib definitions', () => {
});

const variables = scopeManager.variables;
expect(variables.length).toBe(0);
expect(variables).toHaveLength(0);
});

it('should define implicit variables', () => {
Expand Down
8 changes: 6 additions & 2 deletions packages/typescript-estree/jest.config.js
Expand Up @@ -3,9 +3,13 @@
module.exports = {
testEnvironment: 'node',
transform: {
'^.+\\.tsx?$': 'ts-jest',
[/^.+\.tsx?$/.source]: 'ts-jest',
},
testRegex: './tests/(lib/.*\\.(jsx?|tsx?)|ast-alignment/spec\\.ts)$',
testRegex: [
/.\/tests\/lib\/.*\.ts$/.source,
/.\/tests\/ast-alignment\/spec\.ts$/.source,
/.\/tests\/[^\/]+\.test\.ts$/.source,
],
collectCoverage: false,
collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
Expand Down
4 changes: 3 additions & 1 deletion packages/typescript-estree/package.json
Expand Up @@ -55,12 +55,14 @@
"@babel/types": "^7.8.3",
"@types/babel__code-frame": "^7.0.1",
"@types/debug": "^4.1.5",
"@types/glob": "^7.1.1",
"@types/is-glob": "^4.0.1",
"@types/lodash": "^4.14.149",
"@types/semver": "^7.1.0",
"@types/tmp": "^0.2.0",
"@typescript-eslint/shared-fixtures": "3.6.1",
"glob": "*",
"jest-specific-snapshot": "*",
"make-dir": "*",
"tmp": "^0.2.1",
"typescript": "*"
},
Expand Down
110 changes: 110 additions & 0 deletions packages/typescript-estree/tests/ast-fixtures.test.ts
@@ -0,0 +1,110 @@
import fs from 'fs';
import glob from 'glob';
import 'jest-specific-snapshot';
import makeDir from 'make-dir';
import path from 'path';
import { parseAndGenerateServices } from '../src/parser';

// Assign a segment set to this variable to limit the test to only this segment
// This is super helpful if you need to debug why a specific fixture isn't producing the correct output
// eg. ['type-declaration', 'signatures', 'method-generic'] will only test /type-declaration/signatures/method-generic.ts
// prettier-ignore
const ONLY = [].join(path.sep);

const FIXTURES_DIR = path.resolve(
__dirname,
'..',
'..',
'..',
'node_modules',
'@typescript-eslint',
'shared-fixtures',
'fixtures',
);
const SNAPSHOTS_DIR = path.resolve(__dirname, 'snapshots');

const JSX_REGEX = /\.[jt]sx$/;
const fixtures = glob
.sync(`${FIXTURES_DIR}/**/*.src.{js,ts,jsx,tsx}`)
.map(absolute => {
const relative = path.relative(FIXTURES_DIR, absolute);
const { name, dir, ext } = path.parse(relative);
const segments = dir.split(path.sep);
const snapshotPath = path.join(SNAPSHOTS_DIR, dir);
return {
absolute,
isJsx: JSX_REGEX.test(name),
name,
segments,
snapshotPath,
snapshotFile: path.join(snapshotPath, `${name}${ext}.shot`),
};
});

function nestDescribe(
fixture: typeof fixtures[number],
segments = fixture.segments,
): void {
if (segments.length > 0) {
describe(segments[0], () => {
nestDescribe(fixture, segments.slice(1));
});
} else {
const test = (): void => {
const contents = fs.readFileSync(fixture.absolute, 'utf8');

try {
makeDir.sync(fixture.snapshotPath);
} catch (e) {
if ('code' in e && e.code === 'EEXIST') {
// already exists - ignored
} else {
throw e;
}
}

try {
const { ast } = parseAndGenerateServices(contents, {
comment: true,
errorOnUnknownASTType: true,
jsx: fixture.isJsx,
loc: true,
range: true,
tokens: true,
});
expect(ast).toMatchSpecificSnapshot(fixture.snapshotFile);
} catch (e) {
expect(e).toMatchSpecificSnapshot(fixture.snapshotFile);
}
};

if ([...fixture.segments, fixture.name].join(path.sep) === ONLY) {
// eslint-disable-next-line jest/no-focused-tests
it.only(fixture.name, test);
} else {
it(fixture.name, test);
}
}
}

fixtures.forEach(f => nestDescribe(f));

if (ONLY === '') {
// ensure that the snapshots are cleaned up, because jest-specific-snapshot won't do this check
const snapshots = glob.sync(`${SNAPSHOTS_DIR}/**/*.shot`).map(absolute => {
const relative = path.relative(SNAPSHOTS_DIR, absolute);
const { name, dir } = path.parse(relative);
return {
relative,
fixturePath: path.join(FIXTURES_DIR, dir, name),
};
});

describe('ast snapshots should have an associated test', () => {
for (const snap of snapshots) {
it(snap.relative, () => {
fs.existsSync(snap.fixturePath);
});
}
});
}

0 comments on commit 2eb3ca4

Please sign in to comment.