jest-codemods
Version:
Codemods for migrating test files to Jest
749 lines (748 loc) • 34.4 kB
JavaScript
"use strict";
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.assertPrefixes = void 0;
exports.default = transformer;
var chai_chain_utils_1 = require("../utils/chai-chain-utils");
var finale_1 = __importDefault(require("../utils/finale"));
var imports_1 = require("../utils/imports");
var logger_1 = __importDefault(require("../utils/logger"));
var recast_helpers_1 = require("../utils/recast-helpers");
function addCommentHelper(node, comment) {
var comments = node.comments || (node.comments = []);
comments.push(comment);
}
function addLeadingComment(node, comment) {
comment.leading = true;
comment.trailing = false;
addCommentHelper(node, comment);
}
var fns = [
'Uint16Array',
'Uint32Array',
'Uint8Array',
'Uint8ClampedArray',
'a',
'above',
'an',
'array',
'below',
'callCount', // sinon-chai
'calledWith', // sinon-chai
'calledWithMatch', // sinon-chai
'calledWithExactly', // sinon-chai
'descendants', // chai-enzyme
'contain',
'containing',
'containingAllOf',
'contains',
'eq',
'eql',
'eqls',
'equal',
'equalTo',
'equals',
'exactly', // sinon-chai
'greaterthan',
'gt',
'gte',
'include',
'includes',
'instanceof',
'key',
'keys',
'least',
'length',
'lengthof',
'lessthan',
'lt',
'lte',
'match',
'members',
'most',
'ofSize',
'ownproperty',
'ownpropertydescriptor',
'present', // chai-enzyme
'prop', // chai-enzyme
'property',
'props', // chai-enzyme
'state', // chai-enzyme
'string',
'throw',
'type', // chai-enzyme
'within',
// https://www.chaijs.com/plugins/chai-arrays/ plugin:
// TODO: containingAnyOf
].map(function (name) { return name.toLowerCase(); });
var members = [
'called', // sinon-chai
'calledOnce', // sinon-chai
'calledThrice', // sinon-chai
'calledTwice', // sinon-chai
'defined',
'empty',
'exist',
'extensible',
'false',
'finite',
'frozen',
'function',
'nan',
'null',
'ok',
'sealed',
'true',
'undefined',
].map(function (name) { return name.toLowerCase(); });
var unsupportedProperties = new Set([
'arguments',
'respondTo',
'satisfy',
'closeTo',
'oneOf',
'change',
'increase',
'decrease',
]);
var mapValueNameToObjectMethod = {
extensible: 'isExtensible',
frozen: 'isFrozen',
sealed: 'isSealed',
};
var typeEqualityToConstructor = {
regexp: 'RegExp',
promise: 'Promise',
date: 'Date',
set: 'Set',
map: 'Map',
weakset: 'WeakSet',
weakmap: 'WeakMap',
dataview: 'DataView',
object: 'Object',
float64array: 'Float64Array',
float32array: 'Float32Array',
uint32array: 'Uint32Array',
uint16array: 'Uint16Array',
uint8array: 'Uint8Array',
int32array: 'Int32Array',
int16array: 'Int16Array',
int8array: 'Int8Array',
uint8clampedarray: 'Uint8ClampedArray',
};
var chaiToJestGlobalMethods = {
before: 'beforeAll',
after: 'afterAll',
context: 'describe',
};
exports.assertPrefixes = new Set(['to', 'with', 'that']);
function transformer(fileInfo, api, options) {
var j = api.jscodeshift;
var root = j(fileInfo.source);
var mutations = 0;
var createCall = (0, chai_chain_utils_1.createCallUtil)(j);
var chainContains = (0, chai_chain_utils_1.chainContainsUtil)(j);
var getAllBefore = (0, chai_chain_utils_1.getNodeBeforeMemberExpressionUtil)(j);
var getExpectNode = (0, chai_chain_utils_1.getExpectNodeUtil)(j);
var updateExpect = (0, chai_chain_utils_1.updateExpectUtil)(j);
var createCallChain = (0, chai_chain_utils_1.createCallChainUtil)(j);
var isShouldMemberExpression = (0, recast_helpers_1.traverseMemberExpressionUtil)(j, function (node) { return node.type === 'Identifier' && node.name === 'should'; });
var isExpectMemberExpression = (0, recast_helpers_1.traverseMemberExpressionUtil)(j, function (node) { return node.type === j.CallExpression.name && node.callee.name === 'expect'; });
var logWarning = function (msg, node) { return (0, logger_1.default)(fileInfo, msg, node); };
var chai = (0, imports_1.getRequireOrImportName)(j, root, 'chai');
var chaiExtensionUsage = root.find(j.CallExpression, {
callee: {
object: function (node) { return node.type === 'Identifier' && node.name === chai; },
property: function (node) { return node.type === 'Identifier' && node.name === 'use'; },
},
});
if (chaiExtensionUsage.length > 0) {
chaiExtensionUsage.forEach(function (node) {
logWarning('Unsupported Chai Extension "chai.use()"', node);
});
return;
}
var chaiExpectRemoved = (0, imports_1.removeRequireAndImport)(j, root, 'chai', 'expect');
var chaiShouldRemoved = (0, imports_1.removeRequireAndImport)(j, root, 'chai', 'should');
if (chaiExpectRemoved || chaiShouldRemoved) {
mutations += 1;
}
var isExpectCall = function (node) { return (0, chai_chain_utils_1.isExpectCallUtil)(j, node); };
var isInsideExpectCall = function (path) {
var _a;
return ((_a = (0, recast_helpers_1.findParentOfType)(path.parentPath.parentPath, 'CallExpression')) === null || _a === void 0 ? void 0 : _a.value.callee.name) ===
'expect';
};
var typeOf = function (path, value, args, containsNot) {
switch (args[0].value) {
case 'null':
return createCall('toBeNull', [], updateExpect(value, function (node) { return node; }), containsNot);
case 'undefined':
return createCall('toBeUndefined', [], updateExpect(value, function (node) { return node; }), containsNot);
case 'array': {
var parentExpressionStatement = (0, recast_helpers_1.findParentOfType)(path, 'ExpressionStatement');
if (parentExpressionStatement &&
parentExpressionStatement.value &&
parentExpressionStatement.value.expression &&
parentExpressionStatement.value.expression.property &&
parentExpressionStatement.value.expression.property.name === 'empty') {
var topExpression = parentExpressionStatement.value.expression;
var newCallExpression = j.callExpression(j.identifier('toEqual'), [
j.arrayExpression([]),
]);
topExpression.property = containsNot
? j.memberExpression(j.identifier('not'), newCallExpression)
: newCallExpression;
topExpression.object = updateExpect(value, function (node) { return node; });
return null;
}
return createCall('toBe', [j.booleanLiteral(containsNot ? false : true)], updateExpect(value, function (node) {
return j.callExpression(j.memberExpression(j.identifier('Array'), j.identifier('isArray')), [node]);
}));
}
case 'string':
return createCall('toBe', args, updateExpect(value, function (node) { return j.unaryExpression('typeof', node); }), containsNot);
default: {
var chaiValue = args[0].value;
// Chai type strings are case insensitive. :/ Let us try to guess a constructor.
var constructor = typeEqualityToConstructor[chaiValue.toLowerCase()] ||
"".concat(chaiValue[0].toUpperCase()).concat(chaiValue.slice(1));
return createCall('toBeInstanceOf', [j.identifier(constructor)], updateExpect(value, function (node) { return node; }), containsNot);
}
}
};
// TODO: not sure if this is even required for chai...
// E.g. is should(x).true valid?
var isPrefix = function (name) { return exports.assertPrefixes.has(name); };
function parseArgs(args) {
if (args.length === 1 && args[0].type === j.ObjectExpression.name) {
return [createCallChain(['Object', 'keys'], args)];
}
else if (args.length > 1) {
return [j.arrayExpression(args)];
}
return args;
}
function containing(node) {
switch (node.type) {
case j.ArrayExpression.name:
return createCallChain(['expect', 'arrayContaining'], [node]);
case j.ObjectExpression.name:
return createCallChain(['expect', 'objectContaining'], [node]);
default:
return node;
}
}
var createLeadingComments = function (rest) { return function (comment) {
if (comment.type === 'Literal') {
addLeadingComment(rest, j.commentLine(" ".concat(comment.value)));
return;
}
if (comment.type === 'TemplateLiteral') {
addLeadingComment(rest, j.commentLine(" ".concat(j(comment).toSource().replace(/`/g, ''))));
return;
}
addLeadingComment(rest, j.commentLine(" ".concat(j(comment).toSource())));
}; };
function getRestWithLengthHandled(p, rest) {
var containsLength = chainContains('length', p.value.callee, isPrefix);
var newRest = containsLength
? updateExpect(rest, function (node) { return j.memberExpression(node, j.identifier('length')); })
: rest;
if (newRest.arguments) {
// Add expect's second argument as a comment (if one exists)
var comments = newRest.arguments.slice(1, 2);
comments.forEach(createLeadingComments(newRest));
// Jest's expect only allows one argument
newRest.arguments = newRest.arguments.slice(0, 1);
}
return newRest;
}
function withIn(p, rest, args, containsNot) {
if (args.length < 2) {
logWarning(".within needs at least two arguments", p);
return p.value;
}
j(p)
.closest(j.ExpressionStatement)
.insertBefore(j.expressionStatement(createCall('toBeGreaterThanOrEqual', [args[0]], rest, containsNot)));
return createCall('toBeLessThanOrEqual', [args[1]], rest, containsNot);
}
var shouldChainedToExpect = function () {
return root
.find(j.MemberExpression, {
property: {
type: j.Identifier.name,
name: 'should',
},
})
.filter(function (p) { return p.node.object; })
.replaceWith(function (p) { return j.callExpression(j.identifier('expect'), [p.node.object]); })
.size();
};
var shouldIdentifierToExpect = function () {
return root
.find(j.CallExpression)
.filter(function (p) { return isShouldMemberExpression(p.value.callee); })
.replaceWith(function (p) {
var callee = p.value.callee;
var _a = __read(p.node.arguments, 2), args0 = _a[0], args1 = _a[1];
var assertionNode = j.identifier(callee.property.name);
var assertionPrefixNode = callee.object.property;
var firstChainElement = assertionPrefixNode || assertionNode;
var memberExpression = j.memberExpression(j.callExpression(j.identifier('expect'), [args0]), firstChainElement);
if (assertionPrefixNode) {
// if there is a .not wrap it in another memberExpression
memberExpression = j.memberExpression(memberExpression, assertionNode);
}
if (typeof args1 === 'undefined') {
return memberExpression;
}
return j.callExpression(memberExpression, [args1]);
})
.size();
};
var updateMemberExpressions = function () {
var getMembers = function () {
return root
.find(j.MemberExpression, {
property: {
name: function (name) { return members.indexOf(name.toLowerCase()) !== -1; },
},
})
.filter(function (p) { return (0, recast_helpers_1.findParentOfType)(p, 'ExpressionStatement'); })
.filter(function (p) { return !isInsideExpectCall(p); })
.filter(function (p) {
var value = p.value;
var propertyName = value.property.name.toLowerCase();
// Reject "ok" when it isn't proceeded by "to"
return !(propertyName === 'ok' && !chainContains('to', value, 'to'));
});
};
getMembers().forEach(function (p) {
if (p.parentPath.value.type === j.CallExpression.name) {
p.parentPath.replace(p.value);
}
});
return getMembers()
.replaceWith(function (p) {
var value = p.value;
var rest = getAllBefore(isPrefix, value, 'should');
if (rest.arguments !== undefined) {
// Add expect's second argument as a comment (if one exists)
var comments = rest.arguments.slice(1, 2);
comments.forEach(createLeadingComments(rest));
// Jest's expect only allows one argument
rest.arguments = rest.arguments.slice(0, 1);
}
var containsNot = chainContains('not', value, 'to');
var propertyName = value.property.name.toLowerCase();
switch (propertyName) {
case 'ok':
return containsNot
? createCall('toBeFalsy', [], rest)
: createCall('toBeTruthy', [], rest);
case 'true':
return createCall('toBe', [j.booleanLiteral(true)], rest, containsNot);
case 'false':
return createCall('toBe', [j.booleanLiteral(false)], rest, containsNot);
case 'finite':
return createCall('toBe', [j.booleanLiteral(!containsNot)], updateExpect(value, function (node) {
return createCallChain(['isFinite'], [node]);
}));
case 'extensible':
case 'frozen':
case 'sealed':
return createCall('toBe', [j.booleanLiteral(!containsNot)], updateExpect(value, function (node) {
return createCallChain(['Object', mapValueNameToObjectMethod[propertyName]], [node]);
}));
case 'null':
return createCall('toBeNull', [], rest, containsNot);
case 'nan':
return createCall('toBeNaN', [], rest, containsNot);
case 'undefined':
return containsNot
? createCall('toBeDefined', [], rest)
: createCall('toBeUndefined', [], rest);
case 'empty':
if (p.parentPath.parentPath.value.type === 'CallExpression' ||
!chainContains('be', value, 'to')) {
return value;
}
else {
return createCall('toHaveLength', [j.literal(0)], updateExpect(value, function (node) {
if (node.type === j.ObjectExpression.name ||
node.type === j.Identifier.name) {
return createCallChain(['Object', 'keys'], [node]);
}
if (node.type === j.MemberExpression.name &&
node.property.type === 'Identifier' &&
node.property.name === 'length') {
return node.object;
}
return node;
}), containsNot);
}
case 'exist':
case 'defined': {
if (propertyName === 'defined' && containsNot) {
return createCall('toBeDefined', [], rest, true);
}
return containsNot
? createCall('toBeFalsy', [], rest)
: createCall('toBeDefined', [], rest);
}
case 'function':
return typeOf(p, value, [j.literal('function')], containsNot);
case 'called':
return createCall('toHaveBeenCalled', [], rest, containsNot);
case 'calledonce':
return createCall('toHaveBeenCalledTimes', [j.literal(1)], rest, containsNot);
case 'calledtwice':
return createCall('toHaveBeenCalledTimes', [j.literal(2)], rest, containsNot);
case 'calledthrice':
return createCall('toHaveBeenCalledTimes', [j.literal(3)], rest, containsNot);
default:
return value;
}
})
.size();
};
/*
reverses `expect().not.to` -> `expect().to.not` to be
handled correctly by subsequent expression updates
*/
var reverseNotToExpressions = function () {
root
.find(j.MemberExpression, {
object: {
object: {
callee: { name: 'expect' },
},
property: { name: 'not' },
},
property: { name: 'to' },
})
.forEach(function (np) {
np.node.property.name = 'not';
np.node.object.property.name = 'to';
});
};
var updateCallExpressions = function () {
return root
.find(j.CallExpression, {
callee: {
type: j.MemberExpression.name,
property: {
name: function (name) { return fns.indexOf(name.toLowerCase()) !== -1; },
},
object: isExpectCall,
},
})
.replaceWith(function (p) {
var _a, _b, _c, _d, _e, _f;
var value = p.value;
var restRaw = getAllBefore(isPrefix, value.callee, 'should');
var rest = getRestWithLengthHandled(p, restRaw);
var containsNot = chainContains('not', value.callee, isPrefix);
var containsAny = chainContains('any', value.callee, isPrefix);
var args = value.arguments;
var numberOfArgs = args.length;
var _g = __read(args, 1), firstArg = _g[0];
var propertyName = value.callee.property.name.toLowerCase();
switch (propertyName) {
case 'type':
case 'descendants': {
/*
if `.not`: expect(wrapper.find(Foo)).toHaveLength(0)
else if `.exactly`: expect(wrapper.find(Foo)).toHaveLength(exactly.arg[0])
else: expect(wrapper.find(Foo).length).toBeGreaterThan(0)
*/
var lengthArg = void 0;
if (containsNot) {
// for .not, it should always be 0
lengthArg = 0;
}
else {
// if its an `.exactly`, use as length
var path = value.callee;
// find next call expression
while (!path.callee) {
path = path.object;
}
if (((_b = (_a = path.callee) === null || _a === void 0 ? void 0 : _a.property) === null || _b === void 0 ? void 0 : _b.name) === 'exactly') {
lengthArg = (_d = (_c = path.arguments) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.value;
}
}
var wrapNodeWithFind_1 = function (node) {
return j.callExpression(j.memberExpression(node, j.identifier('find')), args);
};
if (lengthArg != null) {
return createCall('toHaveLength', [j.literal(lengthArg)], updateExpect(value, wrapNodeWithFind_1));
}
return createCall('toBeGreaterThan', [j.literal(0)], updateExpect(value, function (node) {
return j.memberExpression(wrapNodeWithFind_1(node), j.identifier('length'));
}));
}
case 'callcount':
return createCall('toHaveBeenCalledTimes', args, rest, containsNot);
case 'calledwith':
return createCall('toHaveBeenCalledWith', args, rest, containsNot);
case 'calledwithmatch':
return createCall('toHaveBeenCalledWith', args.map(containing), rest, containsNot);
case 'calledwithexactly':
return createCall('toHaveBeenCalledWith', args, rest, containsNot);
case 'exactly':
// handle `expect(sinonSpy).to.have.called.exactly(3)`
if (chainContains('called', value.callee, isPrefix)) {
return createCall('toHaveBeenCalledTimes', [firstArg], rest, containsNot);
}
return value;
case 'equalto':
case 'eqls':
case 'eql':
case 'eq':
case 'equal':
case 'equals': {
if (numberOfArgs === 1) {
var type = firstArg.type;
if (type === 'Literal' && firstArg.value === null) {
return createCall('toBeNull', [], rest, containsNot);
}
if (type === 'Identifier' && firstArg.name === 'undefined') {
if (containsNot) {
return createCall('toBeDefined', [], rest, false);
}
else {
return createCall('toBeUndefined', [], rest, false);
}
}
}
var containsDeep = chainContains('deep', value.callee, isPrefix);
var isStrict = ['equal', 'equals', 'eq'].includes(propertyName);
return createCall(isStrict && !containsDeep ? 'toBe' : 'toEqual', args, rest, containsNot);
}
case 'throw':
return createCall('toThrow', args, rest, containsNot);
case 'string':
return createCall('toContain', args, rest, containsNot);
case 'state':
return createCall('toHaveProperty', args, updateExpect(value, function (node) {
return j.callExpression(j.memberExpression(node, j.identifier('state')), []);
}), containsNot);
case 'include':
case 'includes':
case 'contain':
case 'contains': {
var argType = (_e = args[0]) === null || _e === void 0 ? void 0 : _e.type;
if (args.length === 1 && argType === j.ObjectExpression.name) {
return createCall('toMatchObject', args, rest, containsNot);
}
// handle `expect(wrapper.text()).to.contain('string')`
var expectArg = rest.arguments[0];
var isExpectArgCallExpression = expectArg.type === j.CallExpression.name;
// handle `expect(a).to.contain(fn('bar'))`
var containsArg = args === null || args === void 0 ? void 0 : args[0];
var isContainsArgCallExpression = containsArg.type === j.CallExpression.name;
if (isExpectArgCallExpression || isContainsArgCallExpression) {
return createCall('toContain', args, rest, containsNot);
}
var expectNode = getExpectNode(value);
if (expectNode != null) {
// handle `expect([1, 2]).toContain(1)
if (expectNode.arguments[0].type === j.Literal.name) {
return createCall('toContain', args, rest, containsNot);
}
// handle `expect(someArr).toContain(1)`
if (args.length === 1 && argType === j.Literal.name) {
return createCall('toContain', args, updateExpect(value, function (node) { return node; }), containsNot);
}
}
// handle `expect(wrapper).to.contain(<div />)`
if (((_f = args === null || args === void 0 ? void 0 : args[0]) === null || _f === void 0 ? void 0 : _f.type) === j.JSXElement.name) {
return createCall('containsMatchingElement', args, rest, containsNot);
}
return createCall('toEqual', [
createCallChain(containsNot
? ['expect', 'not', 'arrayContaining']
: ['expect', 'arrayContaining'], [j.arrayExpression(args)]),
], updateExpect(value, function (node) { return node; }), false);
}
case 'containing':
return createCall('toContain', args, rest, containsNot);
case 'containingallof':
return createCall('toEqual', [
createCallChain(containsNot
? ['expect', 'not', 'arrayContaining']
: ['expect', 'arrayContaining'], [j.arrayExpression(args[0].elements)]),
], updateExpect(value, function (node) { return node; }), false);
case 'above':
case 'greaterthan':
case 'gt':
return createCall('toBeGreaterThan', args, rest, containsNot);
case 'least':
case 'gte':
return createCall('toBeGreaterThanOrEqual', args, rest, containsNot);
case 'below':
case 'lessthan':
case 'lt':
return createCall('toBeLessThan', args, rest, containsNot);
case 'most':
case 'lte':
return createCall('toBeLessThanOrEqual', args, rest, containsNot);
case 'within':
return withIn(p, rest, args, containsNot);
case 'match':
return createCall('toMatch', args, rest, containsNot);
case 'members':
if (chainContains('ordered', value.callee, isPrefix)) {
logWarning('Unsupported Chai Assertion "ordered"', p);
}
return createCall('toEqual', args.map(containing), rest, containsNot);
case 'key':
return createCall('toHaveProperty', args, rest, containsNot);
case 'keys': {
if (containsAny) {
logWarning('Unsupported Chai Assertion "any.keys"', p);
return value;
}
var updateExpectFn = updateExpect(value, function (node) {
if (node.type === j.ArrayExpression.name) {
return node;
}
return createCallChain(['Object', 'keys'], [node]);
});
// handle single arguments, eg: `expect(serverConfig).to.have.all.keys('middleware')`
if (args.length === 1 &&
[j.Literal.name, j.StringLiteral.name, j.Identifier.name].includes(args[0].type)) {
return createCall('toContain', args, updateExpectFn, containsNot);
}
return createCall('toEqual', [createCallChain(['expect', 'arrayContaining'], parseArgs(args))], updateExpectFn, containsNot);
}
case 'a':
case 'an': {
if (!args.length) {
return value;
}
var t = args[0].type;
if (t === 'Literal' || t === 'StringLiteral') {
return typeOf(p, value, args, containsNot);
}
return createCall('toBeInstanceOf', args, rest, containsNot);
}
case 'instanceof':
return createCall('toBeInstanceOf', args, rest, containsNot);
case 'length':
case 'lengthof':
case 'ofsize':
return createCall('toHaveLength', args, restRaw, containsNot);
case 'prop':
return createCall('toHaveProperty', args, updateExpect(value, function (node) {
return j.callExpression(j.memberExpression(node, j.identifier('props')), []);
}), containsNot);
case 'props':
if (args[0].type === 'ArrayExpression') {
return createCall('toEqual', [createCallChain(['expect', 'arrayContaining'], args)], updateExpect(value, function (node) {
return createCallChain(['Object', 'keys'], [
j.callExpression(j.memberExpression(node, j.identifier('props')), []),
]);
}));
}
else if (args[0].type === 'ObjectExpression') {
return createCall('toMatchObject', args, updateExpect(value, function (node) {
return j.callExpression(j.memberExpression(node, j.identifier('props')), []);
}));
}
break;
case 'present':
return createCall('toBeGreaterThan', [j.literal(0)], updateExpect(value, function (node) {
return j.memberExpression(node, j.identifier('length'));
}), containsNot);
case 'property':
return createCall('toHaveProperty', args, rest, containsNot);
case 'ownproperty':
return createCall('toBeTruthy', [], updateExpect(value, function (node) {
return j.callExpression(j.memberExpression(node, j.identifier('hasOwnProperty')), [args[0]]);
}));
case 'ownpropertydescriptor':
return args.length === 1
? createCall('toBeUndefined', [], updateExpect(value, function (node) {
return j.callExpression(j.memberExpression(j.identifier('Object'), j.identifier('getOwnPropertyDescriptor')), [node, args[0]]);
}), true)
: createCall('toEqual', [args[1]], updateExpect(value, function (node) {
return j.callExpression(j.memberExpression(j.identifier('Object'), j.identifier('getOwnPropertyDescriptor')), [node, args[0]]);
}));
case 'array':
case 'uint8array':
case 'uint16array':
case 'uint32array':
case 'uint8clampedarray':
return typeOf(p, value, [{ value: propertyName }], containsNot);
default:
return value;
}
})
.size();
};
var updateGlobalCallExpressions = function () {
return root
.find(j.CallExpression, {
callee: {
type: j.Identifier.name,
name: function (name) { return Object.keys(chaiToJestGlobalMethods).includes(name); },
},
})
.replaceWith(function (p) {
var _a, _b;
var value = p.value;
/*
if call expression is spread, don't transform, eg:
const foo = { params: ...context(searchParams) }
*/
if (((_b = (_a = p.parentPath) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.type) === j.SpreadElement.name) {
return value;
}
return j.callExpression(j.identifier(chaiToJestGlobalMethods[value.callee.name]), value.arguments);
})
.size();
};
reverseNotToExpressions();
mutations += shouldChainedToExpect();
mutations += shouldIdentifierToExpect();
mutations += updateCallExpressions();
mutations += updateMemberExpressions();
mutations += updateGlobalCallExpressions();
root
.find(j.MemberExpression, {
property: {
name: function (name) { return unsupportedProperties.has(name); },
},
})
.filter(function (p) { return isExpectMemberExpression(p.value); })
.forEach(function (p) {
var assertion = p.value.property.name;
logWarning("Unsupported Chai Assertion \"".concat(assertion, "\""), p);
});
if (!mutations) {
return null;
}
return (0, finale_1.default)(fileInfo, j, root, options);
}