Extract isTestCall (#18757)

This commit is contained in:
fisker Cheung authored and GitHub committed 2026-01-27 10:46:43 +08:00
1 parent 48a6e73d5b
commit f0ad38b3c9
5 files changed
+137 -118

No files matched your search

+1 -1
View File
@@ -8,9 +8,9 @@ import {
isNodeMatches,
isStringLiteral,
isTemplateOnItsOwnLine,
isTestCall,
iterateCallArgumentsPath,
} from "../utilities/index.js";
import { isTestCall } from "../utilities/test-libraries.js";
import printCallArguments from "./call-arguments.js";
import printMemberChain from "./member-chain.js";
import { printOptionalToken } from "./miscellaneous.js";
+1 -1
View File
@@ -20,11 +20,11 @@ import {
isObjectExpression,
isObjectType,
isSimpleType,
isTestCall,
isTypeAnnotationAFunction,
iterateFunctionParametersPath,
shouldPrintComma,
} from "../utilities/index.js";
import { isTestCall } from "../utilities/test-libraries.js";
import { printDanglingCommentsInList } from "./miscellaneous.js";
/** @import AstPath from "../../common/ast-path.js" */
+1 -1
View File
@@ -17,9 +17,9 @@ import {
getFunctionParameters,
hasComment,
isObjectType,
isTestCall,
shouldPrintComma,
} from "../utilities/index.js";
import { isTestCall } from "../utilities/test-libraries.js";
import { isArrowFunctionVariableDeclarator } from "./assignment.js";
import {
printTypeAnnotationProperty,
-115
View File
@@ -18,7 +18,6 @@ import getRaw from "./get-raw.js";
import isBlockComment from "./is-block-comment.js";
import isFlowKeywordType from "./is-flow-keyword-type.js";
import isLineComment from "./is-line-comment.js";
import isNodeMatches from "./is-node-matches.js";
import isTsKeywordType from "./is-ts-keyword-type.js";
import {
isArrayExpression,
@@ -213,36 +212,6 @@ const isSingleWordType = createTypeCheckFunction([
"PrivateIdentifier",
]);
/**
* @param {Node} node
* @returns {boolean}
*/
function isFunctionOrArrowExpressionWithBody(node) {
return (
node.type === "FunctionExpression" ||
(node.type === "ArrowFunctionExpression" &&
node.body.type === "BlockStatement")
);
}
/**
* Note: `inject` is used in AngularJS 1.x, `async` and `fakeAsync` in
* Angular 2+, although `async` is deprecated and replaced by `waitForAsync`
* since Angular 12.
*
* example: https://docs.angularjs.org/guide/unit-testing#using-beforeall-
*
* @param {NodeMap["CallExpression"]} node
* @returns {boolean}
*/
function isAngularTestWrapper(node) {
return (
isCallExpression(node) &&
node.callee.type === "Identifier" &&
["async", "inject", "fakeAsync", "waitForAsync"].includes(node.callee.name)
);
}
function isMethod(node) {
return (
(node.method && node.kind === "init") ||
@@ -317,89 +286,6 @@ function isSimpleType(node) {
);
}
/**
* @param {*} node
* @returns {boolean}
*/
function isUnitTestSetupIdentifier(node) {
return (
node.type === "Identifier" &&
(node.name === "beforeEach" ||
node.name === "beforeAll" ||
node.name === "afterEach" ||
node.name === "afterAll")
);
}
const testCallCalleePatterns = [
"it",
"it.only",
"it.skip",
"describe",
"describe.only",
"describe.skip",
"test",
"test.only",
"test.skip",
"test.fixme",
"test.step",
"test.describe",
"test.describe.only",
"test.describe.skip",
"test.describe.fixme",
"test.describe.parallel",
"test.describe.parallel.only",
"test.describe.serial",
"test.describe.serial.only",
"skip",
"xit",
"xdescribe",
"xtest",
"fit",
"fdescribe",
"ftest",
];
function isTestCallCallee(node) {
return isNodeMatches(node, testCallCalleePatterns);
}
// eg; `describe("some string", (done) => {})`
function isTestCall(node, parent) {
if (node?.type !== "CallExpression" || node.optional) {
return false;
}
const args = getCallArguments(node);
if (args.length === 1) {
if (isAngularTestWrapper(node) && isTestCall(parent)) {
return isFunctionOrArrowExpression(args[0]);
}
if (isUnitTestSetupIdentifier(node.callee)) {
return isAngularTestWrapper(args[0]);
}
} else if (
(args.length === 2 || args.length === 3) &&
(args[0].type === "TemplateLiteral" || isStringLiteral(args[0])) &&
isTestCallCallee(node.callee)
) {
// it("name", () => { ... }, 2500)
if (args[2] && !isNumericLiteral(args[2])) {
return false;
}
return (
(args.length === 2
? isFunctionOrArrowExpression(args[1])
: isFunctionOrArrowExpressionWithBody(args[1]) &&
getFunctionParameters(args[1]).length <= 1) ||
isAngularTestWrapper(args[1])
);
}
return false;
}
/**
* Attempts to gauge the rough complexity of a node, for example
* to detect deeply-nested booleans, call expressions with lots of arguments, etc.
@@ -1189,7 +1075,6 @@ export {
isSimpleType,
isStringLiteral,
isTemplateOnItsOwnLine,
isTestCall,
isTsAsConstExpression,
isTupleType,
isTypeAlias,
+134
View File
@@ -0,0 +1,134 @@
import {
getCallArguments,
getFunctionParameters,
isNumericLiteral,
isStringLiteral,
} from "./index.js";
import isNodeMatches from "./is-node-matches.js";
import { isCallExpression, isFunctionOrArrowExpression } from "./node-types.js";
/**
@import {
Node,
NodeMap,
} from "../types/estree.js";
*/
const testCallCalleePatterns = [
"it",
"it.only",
"it.skip",
"describe",
"describe.only",
"describe.skip",
"test",
"test.only",
"test.skip",
"test.fixme",
"test.step",
"test.describe",
"test.describe.only",
"test.describe.skip",
"test.describe.fixme",
"test.describe.parallel",
"test.describe.parallel.only",
"test.describe.serial",
"test.describe.serial.only",
"skip",
"xit",
"xdescribe",
"xtest",
"fit",
"fdescribe",
"ftest",
];
/**
* @param {Node} node
* @returns {boolean}
*/
function isTestCallCallee(node) {
return isNodeMatches(node, testCallCalleePatterns);
}
/**
* @param {Node} node
* @returns {boolean}
*/
function isUnitTestSetupIdentifier(node) {
return (
node.type === "Identifier" &&
(node.name === "beforeEach" ||
node.name === "beforeAll" ||
node.name === "afterEach" ||
node.name === "afterAll")
);
}
/**
* Note: `inject` is used in AngularJS 1.x, `async` and `fakeAsync` in
* Angular 2+, although `async` is deprecated and replaced by `waitForAsync`
* since Angular 12.
*
* example: https://docs.angularjs.org/guide/unit-testing#using-beforeall-
*
* @param {NodeMap["CallExpression"]} node
* @returns {boolean}
*/
function isAngularTestWrapper(node) {
return (
isCallExpression(node) &&
node.callee.type === "Identifier" &&
["async", "inject", "fakeAsync", "waitForAsync"].includes(node.callee.name)
);
}
/**
* @param {Node} node
* @returns {boolean}
*/
function isFunctionOrArrowExpressionWithBody(node) {
return (
node.type === "FunctionExpression" ||
(node.type === "ArrowFunctionExpression" &&
node.body.type === "BlockStatement")
);
}
// eg; `describe("some string", (done) => {})`
function isTestCall(node, parent) {
if (node?.type !== "CallExpression" || node.optional) {
return false;
}
const args = getCallArguments(node);
if (args.length === 1) {
if (isAngularTestWrapper(node) && isTestCall(parent)) {
return isFunctionOrArrowExpression(args[0]);
}
if (isUnitTestSetupIdentifier(node.callee)) {
return isAngularTestWrapper(args[0]);
}
} else if (
(args.length === 2 || args.length === 3) &&
(args[0].type === "TemplateLiteral" || isStringLiteral(args[0])) &&
isTestCallCallee(node.callee)
) {
// it("name", () => { ... }, 2500)
if (args[2] && !isNumericLiteral(args[2])) {
return false;
}
return (
(args.length === 2
? isFunctionOrArrowExpression(args[1])
: isFunctionOrArrowExpressionWithBody(args[1]) &&
getFunctionParameters(args[1]).length <= 1) ||
isAngularTestWrapper(args[1])
);
}
return false;
}
export { isTestCall };