Repository: skovhus/jest-codemods
Pull request #500 (2023-03-22 09:23:54)

Sinon: add support for transforming callsFake
Hello!

When running the codemods on a quite large test suite, I noticed that `sinon.stub(obj, 'prop').callsFake(fn)` does not seem to be transformed. Docs: https://sinonjs.org/releases/latest/stubs/#properties

I changed it so, that 
```js
sinon.stub(I18n, 'extend').callsFake(fn => fn);
``` 
will be turned into 
```js
jest.spyOn(I18n, 'extend').mockClear().mockImplementation(fn => fn);
``` 
which should be the expected result.

I also added a couple of additional test cases to verify that `sinon.stub()` without arguments is transformed correctly (no changes in the code were needed). 

ping @skovhus 

codecov[bot]: ## [Codecov](https://codecov.io/gh/skovhus/jest-codemods/pull/500?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Kenneth+Skovhus) Report
Patch coverage: **`100.00`**% and project coverage change: **`+0.02`** :tada:
> Comparison is base [(`87daaa6`)](https://codecov.io/gh/skovhus/jest-codemods/commit/87daaa67390d55e38258c9143f0929b346d0cf43?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Kenneth+Skovhus) 92.39% compared to head [(`bf3c0e1`)](https://codecov.io/gh/skovhus/jest-codemods/pull/500?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Kenneth+Skovhus) 92.42%.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main     #500      +/-   ##
==========================================
+ Coverage   92.39%   92.42%   +0.02%     
==========================================
  Files          26       26              
  Lines        1934     1940       +6     
  Branches      404      405       +1     
==========================================
+ Hits         1787     1793       +6     
  Misses        101      101              
  Partials       46       46              
```


| [Impacted Files](https://codecov.io/gh/skovhus/jest-codemods/pull/500?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Kenneth+Skovhus) | Coverage Δ | |
|---|---|---|
| [src/transformers/sinon.ts](https://codecov.io/gh/skovhus/jest-codemods/pull/500?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Kenneth+Skovhus#diff-c3JjL3RyYW5zZm9ybWVycy9zaW5vbi50cw==) | `90.74% <100.00%> (+0.20%)` | :arrow_up: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Kenneth+Skovhus). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Kenneth+Skovhus)

</details>

[:umbrella: View full report in Codecov by Sentry](https://codecov.io/gh/skovhus/jest-codemods/pull/500?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Kenneth+Skovhus).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Kenneth+Skovhus).


Patch:
diff --git a/src/transformers/sinon.ts b/src/transformers/sinon.ts
index a1822a9..c93a749 100644
--- a/src/transformers/sinon.ts
+++ b/src/transformers/sinon.ts
@@ -344,6 +344,21 @@ function transformStub(j, ast, sinonExpression, logWarning) {
             findParentOfType(np, j.VariableDeclaration.name) ||
             findParentOfType(np, j.ExpressionStatement.name)
 
+          const callsFake = j(parent).find(j.CallExpression, {
+            callee: {
+              type: 'MemberExpression',
+              property: { type: 'Identifier', name: 'callsFake' },
+            },
+          })
+          const hasCallsFake = callsFake.size() > 0
+
+          if (hasCallsFake) {
+            callsFake.forEach((np) => {
+              np.node.callee.property.name = 'mockImplementation'
+            })
+            return spyOn
+          }
+
           const hasReturn =
             j(parent)
               .find(j.CallExpression, {


Test patch:
diff --git a/src/transformers/sinon.test.ts b/src/transformers/sinon.test.ts
index eb0c110..50e5611 100644
--- a/src/transformers/sinon.test.ts
+++ b/src/transformers/sinon.test.ts
@@ -56,8 +56,11 @@ describe('spies and stubs', () => {
 
         const stub = sinon.stub(Api, 'get');
         const putOk = sinon.stub(Api, 'put').returns(200)
+        sinon.stub();
+        sinon.stub().returns(Promise.resolve());
         sinon.stub(I18n); // unsupported
         sinon.stub(I18n, 'extend');
+        sinon.stub(I18n, 'extend').callsFake(fn => fn);
         sinon.stub(AirbnbUser, 'current').returnsArg(1);
         sinon.stub(a, b, () => c, d) // too many args
 
@@ -69,8 +72,11 @@ describe('spies and stubs', () => {
       `
         const stub = jest.spyOn(Api, 'get').mockClear().mockImplementation();
         const putOk = jest.spyOn(Api, 'put').mockClear().mockReturnValue(200)
+        jest.fn();
+        jest.fn().mockReturnValue(Promise.resolve());
         sinon.stub(I18n); // unsupported
         jest.spyOn(I18n, 'extend').mockClear().mockImplementation();
+        jest.spyOn(I18n, 'extend').mockClear().mockImplementation(fn => fn);
         jest.spyOn(AirbnbUser, 'current').mockClear().mockImplementation((...args) => args[1]);
         jest.spyOn(a, b).mockClear().mockImplementation(() => c) // too many args
 
@@ -81,9 +87,9 @@ describe('spies and stubs', () => {
 `,
       {
         warnings: [
-          'jest-codemods warning: (test.js line 6) stubbing all methods in an object is not supported; stub each one you care about individually',
-          'jest-codemods warning: (test.js line 9) 4+ arguments found in sinon.stub call; did you mean to use this many?',
-          'jest-codemods warning: (test.js line 14) 4+ arguments found in sinon.spy call; did you mean to use this many?',
+          'jest-codemods warning: (test.js line 8) stubbing all methods in an object is not supported; stub each one you care about individually',
+          'jest-codemods warning: (test.js line 12) 4+ arguments found in sinon.stub call; did you mean to use this many?',
+          'jest-codemods warning: (test.js line 17) 4+ arguments found in sinon.spy call; did you mean to use this many?',
         ],
       }
     )