Skip to content

Commit

Permalink
chore: avoid using anonymous default exports (#12313)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB committed Feb 6, 2022
1 parent dd29978 commit e0f3d16
Show file tree
Hide file tree
Showing 33 changed files with 208 additions and 163 deletions.
12 changes: 12 additions & 0 deletions .eslintrc.js
Expand Up @@ -180,6 +180,18 @@ module.exports = {
files: 'packages/**/*.ts',
rules: {
'@typescript-eslint/explicit-module-boundary-types': 'error',
'import/no-anonymous-default-export': [
'error',
{
allowAnonymousClass: false,
allowAnonymousFunction: false,
allowArray: false,
allowArrowFunction: false,
allowCallExpression: false,
allowLiteral: false,
allowObject: true,
},
],
},
},
{
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -10,6 +10,8 @@

### Chore & Maintenance

- `[*]` Avoid anonymous default exports ([#12313](https://github.com/facebook/jest/pull/12313))

### Performance

## 27.5.0
Expand Down
172 changes: 88 additions & 84 deletions packages/babel-plugin-jest-hoist/src/index.ts
Expand Up @@ -268,102 +268,106 @@ const extractJestObjExprIfHoistable = <T extends Node>(
};

/* eslint-disable sort-keys */
export default (): PluginObj<{
export default function jestHoist(): PluginObj<{
declareJestObjGetterIdentifier: () => Identifier;
jestObjGetterIdentifier?: Identifier;
}> => ({
pre({path: program}) {
this.declareJestObjGetterIdentifier = () => {
if (this.jestObjGetterIdentifier) {
return this.jestObjGetterIdentifier;
}
}> {
return {
pre({path: program}) {
this.declareJestObjGetterIdentifier = () => {
if (this.jestObjGetterIdentifier) {
return this.jestObjGetterIdentifier;
}

this.jestObjGetterIdentifier =
program.scope.generateUidIdentifier('getJestObj');
this.jestObjGetterIdentifier =
program.scope.generateUidIdentifier('getJestObj');

program.unshiftContainer('body', [
createJestObjectGetter({
GETTER_NAME: this.jestObjGetterIdentifier.name,
JEST_GLOBALS_MODULE_JEST_EXPORT_NAME,
JEST_GLOBALS_MODULE_NAME,
}),
]);
program.unshiftContainer('body', [
createJestObjectGetter({
GETTER_NAME: this.jestObjGetterIdentifier.name,
JEST_GLOBALS_MODULE_JEST_EXPORT_NAME,
JEST_GLOBALS_MODULE_NAME,
}),
]);

return this.jestObjGetterIdentifier;
};
},
visitor: {
ExpressionStatement(exprStmt) {
const jestObjExpr = extractJestObjExprIfHoistable(
exprStmt.get('expression'),
);
if (jestObjExpr) {
jestObjExpr.replaceWith(
callExpression(this.declareJestObjGetterIdentifier(), []),
return this.jestObjGetterIdentifier;
};
},
visitor: {
ExpressionStatement(exprStmt) {
const jestObjExpr = extractJestObjExprIfHoistable(
exprStmt.get('expression'),
);
}
if (jestObjExpr) {
jestObjExpr.replaceWith(
callExpression(this.declareJestObjGetterIdentifier(), []),
);
}
},
},
},
// in `post` to make sure we come after an import transform and can unshift above the `require`s
post({path: program}) {
const self = this;

visitBlock(program);
program.traverse({BlockStatement: visitBlock});

function visitBlock(block: NodePath<BlockStatement> | NodePath<Program>) {
// use a temporary empty statement instead of the real first statement, which may itself be hoisted
const [varsHoistPoint, callsHoistPoint] = block.unshiftContainer('body', [
emptyStatement(),
emptyStatement(),
]);
block.traverse({
CallExpression: visitCallExpr,
VariableDeclarator: visitVariableDeclarator,
// do not traverse into nested blocks, or we'll hoist calls in there out to this block
blacklist: ['BlockStatement'],
});
callsHoistPoint.remove();
varsHoistPoint.remove();

function visitCallExpr(callExpr: NodePath<CallExpression>) {
const {
node: {callee},
} = callExpr;
if (
isIdentifier(callee) &&
callee.name === self.jestObjGetterIdentifier?.name
) {
const mockStmt = callExpr.getStatementParent();

if (mockStmt) {
const mockStmtParent = mockStmt.parentPath;
if (mockStmtParent.isBlock()) {
const mockStmtNode = mockStmt.node;
mockStmt.remove();
callsHoistPoint.insertBefore(mockStmtNode);
// in `post` to make sure we come after an import transform and can unshift above the `require`s
post({path: program}) {
const self = this;

visitBlock(program);
program.traverse({BlockStatement: visitBlock});

function visitBlock(block: NodePath<BlockStatement> | NodePath<Program>) {
// use a temporary empty statement instead of the real first statement, which may itself be hoisted
const [varsHoistPoint, callsHoistPoint] = block.unshiftContainer(
'body',
[emptyStatement(), emptyStatement()],
);
block.traverse({
CallExpression: visitCallExpr,
VariableDeclarator: visitVariableDeclarator,
// do not traverse into nested blocks, or we'll hoist calls in there out to this block
blacklist: ['BlockStatement'],
});
callsHoistPoint.remove();
varsHoistPoint.remove();

function visitCallExpr(callExpr: NodePath<CallExpression>) {
const {
node: {callee},
} = callExpr;
if (
isIdentifier(callee) &&
callee.name === self.jestObjGetterIdentifier?.name
) {
const mockStmt = callExpr.getStatementParent();

if (mockStmt) {
const mockStmtParent = mockStmt.parentPath;
if (mockStmtParent.isBlock()) {
const mockStmtNode = mockStmt.node;
mockStmt.remove();
callsHoistPoint.insertBefore(mockStmtNode);
}
}
}
}
}

function visitVariableDeclarator(varDecl: NodePath<VariableDeclarator>) {
if (hoistedVariables.has(varDecl.node)) {
// should be assert function, but it's not. So let's cast below
varDecl.parentPath.assertVariableDeclaration();

const {kind, declarations} = varDecl.parent as VariableDeclaration;
if (declarations.length === 1) {
varDecl.parentPath.remove();
} else {
varDecl.remove();
function visitVariableDeclarator(
varDecl: NodePath<VariableDeclarator>,
) {
if (hoistedVariables.has(varDecl.node)) {
// should be assert function, but it's not. So let's cast below
varDecl.parentPath.assertVariableDeclaration();

const {kind, declarations} = varDecl.parent as VariableDeclaration;
if (declarations.length === 1) {
varDecl.parentPath.remove();
} else {
varDecl.remove();
}
varsHoistPoint.insertBefore(
variableDeclaration(kind, [varDecl.node]),
);
}
varsHoistPoint.insertBefore(
variableDeclaration(kind, [varDecl.node]),
);
}
}
}
},
});
},
};
}
/* eslint-enable */
6 changes: 3 additions & 3 deletions packages/diff-sequences/src/index.ts
Expand Up @@ -779,12 +779,12 @@ const validateCallback = (name: string, arg: unknown) => {
// Given lengths of sequences and input function to compare items at indexes,
// return by output function the number of adjacent items and starting indexes
// of each common subsequence.
export default (
export default function diffSequence(
aLength: number,
bLength: number,
isCommon: IsCommon,
foundSubsequence: FoundSubsequence,
): void => {
): void {
validateLength('aLength', aLength);
validateLength('bLength', bLength);
validateCallback('isCommon', isCommon);
Expand Down Expand Up @@ -869,4 +869,4 @@ export default (
foundSubsequence(nCommonR, aEnd, bEnd);
}
}
};
}
Expand Up @@ -17,7 +17,9 @@ import {

export type Expect = typeof expect;

export default (config: Pick<Config.GlobalConfig, 'expand'>): Expect => {
export default function jestExpect(
config: Pick<Config.GlobalConfig, 'expand'>,
): Expect {
expect.setState({expand: config.expand});
expect.extend({
toMatchInlineSnapshot,
Expand All @@ -29,4 +31,4 @@ export default (config: Pick<Config.GlobalConfig, 'expand'>): Expect => {
expect.addSnapshotSerializer = addSerializer;

return expect;
};
}
6 changes: 3 additions & 3 deletions packages/jest-cli/src/init/index.ts
Expand Up @@ -37,9 +37,9 @@ type PromptsResults = {

const getConfigFilename = (ext: string) => JEST_CONFIG_BASE_NAME + ext;

export default async (
export default async function init(
rootDir: string = tryRealpath(process.cwd()),
): Promise<void> => {
): Promise<void> {
// prerequisite checks
const projectPackageJsonPath: string = path.join(rootDir, PACKAGE_JSON);

Expand Down Expand Up @@ -152,4 +152,4 @@ export default async (
console.log(
`📝 Configuration file created at ${chalk.cyan(jestConfigPath)}`,
);
};
}
6 changes: 3 additions & 3 deletions packages/jest-config/src/resolveConfigPath.ts
Expand Up @@ -21,11 +21,11 @@ const isFile = (filePath: Config.Path) =>

const getConfigFilename = (ext: string) => JEST_CONFIG_BASE_NAME + ext;

export default (
export default function resolveConfigPath(
pathToResolve: Config.Path,
cwd: Config.Path,
skipMultipleConfigWarning = false,
): Config.Path => {
): Config.Path {
if (!path.isAbsolute(cwd)) {
throw new Error(`"cwd" must be an absolute path. cwd: ${cwd}`);
}
Expand Down Expand Up @@ -61,7 +61,7 @@ export default (
cwd,
skipMultipleConfigWarning,
);
};
}

const resolveConfigPathByTraversing = (
pathToResolve: Config.Path,
Expand Down
6 changes: 3 additions & 3 deletions packages/jest-console/src/getConsoleOutput.ts
Expand Up @@ -14,11 +14,11 @@ import {
} from 'jest-message-util';
import type {ConsoleBuffer} from './types';

export default (
export default function getConsoleOutput(
buffer: ConsoleBuffer,
config: StackTraceConfig,
globalConfig: Config.GlobalConfig,
): string => {
): string {
const TITLE_INDENT = globalConfig.verbose ? ' ' : ' ';
const CONSOLE_INDENT = TITLE_INDENT + ' ';

Expand Down Expand Up @@ -64,4 +64,4 @@ export default (
}, '');

return logEntries.trimRight() + '\n';
};
}
6 changes: 3 additions & 3 deletions packages/jest-core/src/getChangedFilesPromise.ts
Expand Up @@ -10,10 +10,10 @@ import type {Config} from '@jest/types';
import {ChangedFilesPromise, getChangedFilesForRoots} from 'jest-changed-files';
import {formatExecError} from 'jest-message-util';

export default (
export default function getChangedFilesPromise(
globalConfig: Config.GlobalConfig,
configs: Array<Config.ProjectConfig>,
): ChangedFilesPromise | undefined => {
): ChangedFilesPromise | undefined {
if (globalConfig.onlyChanged) {
const allRootsForAllProjects = configs.reduce<Array<Config.Path>>(
(roots, config) => {
Expand Down Expand Up @@ -41,4 +41,4 @@ export default (
}

return undefined;
};
}
16 changes: 9 additions & 7 deletions packages/jest-core/src/lib/createContext.ts
Expand Up @@ -9,12 +9,14 @@ import type {Config} from '@jest/types';
import type {HasteMapObject} from 'jest-haste-map';
import Runtime, {Context} from 'jest-runtime';

export default (
export default function createContext(
config: Config.ProjectConfig,
{hasteFS, moduleMap}: HasteMapObject,
): Context => ({
config,
hasteFS,
moduleMap,
resolver: Runtime.createResolver(config, moduleMap),
});
): Context {
return {
config,
hasteFS,
moduleMap,
resolver: Runtime.createResolver(config, moduleMap),
};
}
7 changes: 4 additions & 3 deletions packages/jest-core/src/lib/handleDeprecationWarnings.ts
Expand Up @@ -8,11 +8,11 @@
import chalk = require('chalk');
import {KEYS} from 'jest-watcher';

export default (
export default function handleDeprecationWarnings(
pipe: NodeJS.WriteStream,
stdin: NodeJS.ReadStream = process.stdin,
): Promise<void> =>
new Promise((resolve, reject) => {
): Promise<void> {
return new Promise((resolve, reject) => {
if (typeof stdin.setRawMode === 'function') {
const messages = [
chalk.red('There are deprecation warnings.\n'),
Expand All @@ -39,3 +39,4 @@ export default (
resolve();
}
});
}
6 changes: 3 additions & 3 deletions packages/jest-core/src/lib/updateGlobalConfig.ts
Expand Up @@ -13,10 +13,10 @@ type ExtraConfigOptions = Partial<
Pick<Config.GlobalConfig, 'noSCM' | 'passWithNoTests'>
>;

export default (
export default function updateGlobalConfig(
globalConfig: Config.GlobalConfig,
options: AllowedConfigOptions & ExtraConfigOptions = {},
): Config.GlobalConfig => {
): Config.GlobalConfig {
const newConfig: Config.GlobalConfig = {...globalConfig};

if (options.mode === 'watch') {
Expand Down Expand Up @@ -112,4 +112,4 @@ export default (
}

return Object.freeze(newConfig);
};
}

0 comments on commit e0f3d16

Please sign in to comment.