Repository: skovhus/jest-codemods
Pull request #613 (2024-09-03 13:18:52)

feat(jasmine): also replace jasmine.Spy/SpyObj on nested types

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/skovhus/jest-codemods/pull/613?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Kenneth+Skovhus) Report
Attention: Patch coverage is `81.25000%` with `3 lines` in your changes missing coverage. Please review.
> Project coverage is 92.62%. Comparing base [(`a94e2b5`)](https://app.codecov.io/gh/skovhus/jest-codemods/commit/a94e2b561fed619cbebf0b9c28e0a919c44aa4e3?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Kenneth+Skovhus) to head [(`f78bbe0`)](https://app.codecov.io/gh/skovhus/jest-codemods/commit/f78bbe038fa8d4742971584bb8edf276f6425567?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Kenneth+Skovhus).
> Report is 69 commits behind head on main.

| [Files with missing lines](https://app.codecov.io/gh/skovhus/jest-codemods/pull/613?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Kenneth+Skovhus) | Patch % | Lines |
|---|---|---|
| [src/transformers/jasmine-globals.ts](https://app.codecov.io/gh/skovhus/jest-codemods/pull/613?src=pr&el=tree&filepath=src%2Ftransformers%2Fjasmine-globals.ts&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Kenneth+Skovhus#diff-c3JjL3RyYW5zZm9ybWVycy9qYXNtaW5lLWdsb2JhbHMudHM=) | 81.25% | [2 Missing and 1 partial :warning: ](https://app.codecov.io/gh/skovhus/jest-codemods/pull/613?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Kenneth+Skovhus) |

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


```diff
@@            Coverage Diff             @@
##             main     #613      +/-   ##
==========================================
+ Coverage   92.38%   92.62%   +0.23%     
==========================================
  Files          26       27       +1     
  Lines        1944     2074     +130     
  Branches      405      427      +22     
==========================================
+ Hits         1796     1921     +125     
- Misses        102      104       +2     
- Partials       46       49       +3     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/skovhus/jest-codemods/pull/613?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Kenneth+Skovhus).   
:loudspeaker: Have feedback on the report? [Share it here](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/jasmine-globals.ts b/src/transformers/jasmine-globals.ts
index 6592d07..db78300 100644
--- a/src/transformers/jasmine-globals.ts
+++ b/src/transformers/jasmine-globals.ts
@@ -685,47 +685,30 @@ export default function jasmineGlobals(fileInfo, api, options) {
       j(path).replaceWith(j.objectExpression(properties))
     })
 
-  root
-    .find(j.VariableDeclarator)
-    .filter((path) => {
-      const { typeAnnotation } = path.value.id
-      if (!typeAnnotation) return false
-
-      const { typeName } = typeAnnotation.typeAnnotation
+  const isJasmineSpyType = (typeAnnotation) =>
+    typeAnnotation &&
+    typeAnnotation.type === 'TSTypeReference' &&
+    typeAnnotation.typeName.type === 'TSQualifiedName' &&
+    typeAnnotation.typeName.left.name === 'jasmine' &&
+    (typeAnnotation.typeName.right.name === 'Spy' ||
+      typeAnnotation.typeName.right.name === 'SpyObj')
+
+  const transformJasmineTypeToJest = (type) => {
+    if (!type) return type
+
+    const typeArgument = type.typeParameters?.params[0]
+    const jestType = type.typeName.right.name === 'Spy' ? 'Mock' : 'Mocked'
+
+    return j.tsTypeReference(
+      j.tsQualifiedName(j.identifier('jest'), j.identifier(jestType)),
+      typeArgument ? j.tsTypeParameterInstantiation([typeArgument]) : null
+    )
+  }
 
-      return (
-        typeName &&
-        typeName.type === 'TSQualifiedName' &&
-        typeName.left.name === 'jasmine' &&
-        (typeName.right.name === 'Spy' || typeName.right.name === 'SpyObj')
-      )
-    })
-    .forEach((path) => {
-      const { typeAnnotation } = path.value.id
-      const { typeName } = typeAnnotation.typeAnnotation
-      const typeArgument = typeAnnotation.typeAnnotation.typeParameters?.params[0]
-
-      switch (typeName.right.name) {
-        case 'Spy': {
-          path.value.id.typeAnnotation = j.tsTypeAnnotation(
-            j.tsTypeReference(
-              j.tsQualifiedName(j.identifier('jest'), j.identifier('Mock')),
-              typeArgument ? j.tsTypeParameterInstantiation([typeArgument]) : null
-            )
-          )
-          break
-        }
-        case 'SpyObj': {
-          path.value.id.typeAnnotation = j.tsTypeAnnotation(
-            j.tsTypeReference(
-              j.tsQualifiedName(j.identifier('jest'), j.identifier('Mocked')),
-              j.tsTypeParameterInstantiation([typeArgument])
-            )
-          )
-          break
-        }
-      }
-    })
+  root
+    .find(j.TSTypeReference)
+    .filter((path) => isJasmineSpyType(path.value))
+    .forEach((path) => path.replace(transformJasmineTypeToJest(path.value)))
 
   root
     .find(j.CallExpression, {


Test patch:
diff --git a/src/transformers/jasmine-globals.test.ts b/src/transformers/jasmine-globals.test.ts
index 6570cef..9b6c6b4 100644
--- a/src/transformers/jasmine-globals.test.ts
+++ b/src/transformers/jasmine-globals.test.ts
@@ -444,11 +444,17 @@ describe('types', () => {
         let setLanguageSpy: jasmine.Spy;
         let logSpy: jasmine.Spy<(message: string) => void>;
         const handleErrorSpy: jasmine.Spy<ErrorHandler['handleError']> = jasmine.createSpy();
+        let translateMock: { translate: jasmine.Spy };
+        class Foo { something: jasmine.Spy<(value: string) => void>; }
+        type MySpy = jasmine.Spy<(value: string) => void>;
         `,
       `
         let setLanguageSpy: jest.Mock;
         let logSpy: jest.Mock<(message: string) => void>;
         const handleErrorSpy: jest.Mock<ErrorHandler['handleError']> = jest.fn();
+        let translateMock: { translate: jest.Mock };
+        class Foo { something: jest.Mock<(value: string) => void>; }
+        type MySpy = jest.Mock<(value: string) => void>;
         `,
       { parser: 'ts' }
     ))