Skip to content
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

chore: avoid using anonymous default exports #12313

Merged
merged 2 commits into from Feb 6, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions .eslintrc.js
Expand Up @@ -185,6 +185,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);
};
}