Repository: skovhus/jest-codemods (ts)

Issue:
spyOn.returnValues transformation uses incorrect jest mock function
Calls to `returnValues` are currently transformed into a series of `mockReturnValue` which causes an issue in Jest since only the last call of mockReturnValue gets applied. Using [`mockReturnValueOnce`](https://jestjs.io/docs/mock-function-api#mockfnmockreturnvalueoncevalue) seems to be more appropriate.

`spyOn(stuff).and.returnValues(1,2,3);`

transformed into:

`jest.spyOn(stuff).mockReturnValue(1).mockReturnValue(2).mockReturnValue(3);
// calling stuff always returns 3
`

proposal:

`jest.spyOn(stuff).mockReturnValueOnce(1).mockReturnValueOnce(2).mockReturnValueOnce(3);`




Pull request description:
fix(jasmine): returnValues() should be transformed to a chain of mockReturnValueOnce()
fixes #627

Patch:
diff --git a/src/transformers/jasmine-globals.ts b/src/transformers/jasmine-globals.ts
index 65a25b7..f087ed7 100644
--- a/src/transformers/jasmine-globals.ts
+++ b/src/transformers/jasmine-globals.ts
@@ -315,14 +315,14 @@ export default function jasmineGlobals(fileInfo, api, options) {
         }
 
         case 'returnValues': {
-          let mockReturnValuesCall = j.callExpression(
-            j.memberExpression(j.identifier('jest'), j.identifier('spyOn')),
-            path.node.callee.object.object.arguments ?? []
-          )
+          let mockReturnValuesCall = path.node.callee.object.object
 
           for (const argument of path.node.arguments) {
             mockReturnValuesCall = j.callExpression(
-              j.memberExpression(mockReturnValuesCall, j.identifier('mockReturnValue')),
+              j.memberExpression(
+                mockReturnValuesCall,
+                j.identifier('mockReturnValueOnce')
+              ),
               [argument]
             )
           }


Test patch:
diff --git a/src/transformers/jasmine-globals.test.ts b/src/transformers/jasmine-globals.test.ts
index 6e1b215..6039350 100644
--- a/src/transformers/jasmine-globals.test.ts
+++ b/src/transformers/jasmine-globals.test.ts
@@ -143,6 +143,7 @@ test('spyOn', () => {
     existingSpy.and.callThrough();
     spyOn(something, 'foo').and.stub().and.returnValue(42);
     mySpy.and.stub();
+    anotherSpy.and.returnValues('a', 'b');
     `,
     `
     jest.spyOn().mockReturnValue();
@@ -150,7 +151,7 @@ test('spyOn', () => {
     jest.spyOn(stuff).mockImplementation(() => 'lol');
     existingSpy.mockImplementation(() => 'lol');
     jest.spyOn(stuff).mockReturnValue('lmao');
-    jest.spyOn(stuff).mockReturnValue(1).mockReturnValue(2).mockReturnValue(3);
+    jest.spyOn(stuff).mockReturnValueOnce(1).mockReturnValueOnce(2).mockReturnValueOnce(3);
     existingSpy.mockReturnValue('lmao');
     jest.spyOn();
     jest.spyOn(stuff).mockImplementation(() => {});
@@ -161,6 +162,7 @@ test('spyOn', () => {
     existingSpy.mockRestore();
     jest.spyOn(something, 'foo').mockReturnValue(42);
     mySpy.mockImplementation(() => {});
+    anotherSpy.mockReturnValueOnce('a').mockReturnValueOnce('b');
     `
   )
 })