diff --git a/src/transformers/jasmine-globals.test.ts b/src/transformers/jasmine-globals.test.ts index e757b7bb..ec91b35d 100644 --- a/src/transformers/jasmine-globals.test.ts +++ b/src/transformers/jasmine-globals.test.ts @@ -1,4 +1,5 @@ /* eslint-env jest */ +import { describe } from '@jest/globals' import chalk from 'chalk' import { wrapPlugin } from '../utils/test-helpers' @@ -226,19 +227,87 @@ test('jasmine.(*)', () => { ) }) -test('createSpyObj', () => { - expectTransformation( - ` +describe('createSpyObj', () => { + test('with methodNames array and no properties', () => { + expectTransformation( + ` const spyObj = jasmine.createSpyObj('label', ['a', 'b', 'hyphen-ated']); `, - ` + ` const spyObj = { 'a': jest.fn(), 'b': jest.fn(), 'hyphen-ated': jest.fn() }; ` - ) + ) + }) + + test('with methodNames array and properties object', () => { + expectTransformation( + ` + const spyObj = jasmine.createSpyObj('', ['a', 'b'], { c: 5 }); + `, + ` + const spyObj = { + 'a': jest.fn(), + 'b': jest.fn(), + 'c': 5 + }; + ` + ) + }) + + test('with methods object and no properties', () => { + expectTransformation( + ` + const spyObj = jasmine.createSpyObj('label', { + a: 42, + b: true, + c: of(undefined) + }); + `, + ` + const spyObj = { + 'a': jest.fn(() => { + return 42; + }), + + 'b': jest.fn(() => { + return true; + }), + + 'c': jest.fn(() => { + return of(undefined); + }) + }; + ` + ) + }) + + test('with methods object and properties array', () => { + expectTransformation( + ` + const spyObj = jasmine.createSpyObj('label', { + a: 42, + b: true + }, ['c']); + `, + ` + const spyObj = { + 'a': jest.fn(() => { + return 42; + }), + + 'b': jest.fn(() => { + return true; + }), + + 'c': null + }; + ` + ) + }) }) test('return value', () => { diff --git a/src/transformers/jasmine-globals.ts b/src/transformers/jasmine-globals.ts index 528f29e0..d3e49365 100644 --- a/src/transformers/jasmine-globals.ts +++ b/src/transformers/jasmine-globals.ts @@ -1,6 +1,8 @@ /** * Codemod for transforming Jasmine globals into Jest. */ +import { ObjectProperty } from 'jscodeshift' + import finale from '../utils/finale' import logger from '../utils/logger' @@ -532,21 +534,57 @@ export default function jasmineGlobals(fileInfo, api, options) { }, }, }) - .filter( - (path) => - path.node.arguments.length === 2 && - path.node.arguments[1].type === 'ArrayExpression' - ) + .filter((path) => { + const args = path.node.arguments + + return ( + (args.length === 2 || args.length === 3) && + (args[1].type === 'ArrayExpression' || args[1].type === 'ObjectExpression') && + (args[2] === undefined || + args[2].type === 'ArrayExpression' || + args[2].type === 'ObjectExpression') + ) + }) .forEach((path) => { - const properties = path.node.arguments[1].elements.map((arg) => - j.objectProperty( - j.literal(arg.value), - j.callExpression( - j.memberExpression(j.identifier('jest'), j.identifier('fn')), - [] - ) + const [, spyObjMethods, spyObjProperties] = path.node.arguments + + const properties: ObjectProperty[] = + spyObjMethods.type === 'ArrayExpression' + ? spyObjMethods.elements.map((arg) => + j.objectProperty( + j.literal(arg.value), + j.callExpression( + j.memberExpression(j.identifier('jest'), j.identifier('fn')), + [] + ) + ) + ) + : spyObjMethods.properties.map((arg) => + j.objectProperty( + j.literal(arg.key.name), + j.callExpression( + j.memberExpression(j.identifier('jest'), j.identifier('fn')), + [ + j.arrowFunctionExpression( + [], + j.blockStatement([j.returnStatement(arg.value)]) + ), + ] + ) + ) + ) + + if (spyObjProperties !== undefined) { + properties.push( + ...(spyObjProperties.type === 'ArrayExpression' + ? spyObjProperties.elements.map((arg) => + j.objectProperty(j.literal(arg.value), j.literal(null)) + ) + : spyObjProperties.properties.map((arg) => + j.objectProperty(j.literal(arg.key.name), arg.value) + )) ) - ) + } j(path).replaceWith(j.objectExpression(properties)) })