Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert enzyme imports to RTL #10

Merged
merged 3 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Find and convert all Enzyme import declarations to RTL imports
* Example:
* import { shallow } from 'enzyme'; --> import { render, screen } from '@testing-library/react';
*/

import type { Collection, JSCodeshift, ImportDeclaration } from 'jscodeshift';
import { astLogger } from '../utils/ast-logger';

/**
* Transforms the provided AST by converting all Enzyme imports to RTL imports.
* @param j - JSCodeshift library
* @param root - The root AST node
* @returns {void} - The function does not return a value but mutates the AST directly.
*/
export const convertImports = (j: JSCodeshift, root: Collection): void => {
// Find all import declarations matching `import { shallow } from 'enzyme';`
astLogger.verbose('Query for enzyme import declarations');
const enzymeImportDeclaration = root.find(j.ImportDeclaration, {
source: {
value: 'enzyme',
},
});

let newImportDeclaration: ImportDeclaration;

// Replace shallow and mount imports with import screen and render from rtl
astLogger.verbose(
'Convert shallow and mount imports with import screen and render from rtl',
);
if (enzymeImportDeclaration.length > 0) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition is relevant only for Slack specific code, sicne we know that if there is no imports from enzyme, we probably used some helper methods that underneath called enzyme mount or shallow. So we can remove this condition

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We depend on Enzyme imports in other files and I added this config value if there are no Enzyme imports https://github.com/slackhq/enzyme-to-rtl-codemod/pull/9/files#diff-68ac65091b40f07c929387caa54f12a720b3039ea29aaaee2defbc9205e79e30R19-R25

Could you reuse it? Maybe pass that value to this method when we call it in main-ast-transform.ts?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or if you don't want to do that, this might be the easiest way:

if (enzymeImportDeclaration.length > 0) {
        // create new import declaration for `import { render, screen } from '@testing-library/react';`
        newImportDeclaration = j.importDeclaration(
            [
                j.importSpecifier(j.identifier('render')),
                j.importSpecifier(j.identifier('screen')),
            ],
            j.literal('@testing-library/react'),
        );

        // remove enzyme imports
        enzymeImportDeclaration.remove();
    }

and remove the else condition, since in theory it should not be applicable. Or add a logger.warn('No enzyme imports found') in the else condition

Copy link
Contributor Author

@cresczul cresczul Jul 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah okay! Yeah not so much that I dont want to but more so do i know how to 😅 . Let me use the latter approach

// create new import declaration for `import { render, screen } from '@testing-library/react';`
newImportDeclaration = j.importDeclaration(
[
j.importSpecifier(j.identifier('render')),
j.importSpecifier(j.identifier('screen')),
],
j.literal('@testing-library/react'),
);

// remove enzyme imports
enzymeImportDeclaration.remove();
} else {
astLogger.verbose('No enzyme imports found');
}

// Get the top file node
const fileTopNode = root.find(j.Program);

// Add the new import
astLogger.verbose('Add RTL import');
fileTopNode.replaceWith((path) => {
path.node.body.unshift(newImportDeclaration);
return path.node;
});
};
5 changes: 4 additions & 1 deletion src/utils/ast-transformations/main-ast-transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import jscodeshift from 'jscodeshift';
import { convertFind } from './individual-transformations/convert-find';
import { convertHostNodes } from './individual-transformations/remove-enzyme-hostNodes-method';
import { convertImports } from './individual-transformations/convert-enzyme-imports';
import { convertMountShallowMethods } from './individual-transformations/convert-mount-shallow-methods';
import { convertMountShallowVars } from './individual-transformations/convert-mount-shallow-vars';
import { convertSimulate } from './individual-transformations/convert-simulate';
Expand All @@ -28,7 +29,8 @@
j.withParser('tsx');

// Convert enzyme imports
// convertImports(j, root);
astLogger.verbose('Convert imports');
convertImports(j, root);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add astLogger.verbose('Convert imports'); either now or in a following PR, so that we have verbose logs for each transformation method in src/utils/ast-transformations/main-ast-transform.ts

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets add this now. I may not remember later


/**
* Convert mount and shallow to render
Expand All @@ -43,7 +45,7 @@
* Step 2: Collect variable names that reference shallow and mount calls
*/
astLogger.verbose('Convert mount/shallow vars');
const renderFunctionVarNames = convertMountShallowVars(

Check warning on line 48 in src/utils/ast-transformations/main-ast-transform.ts

View workflow job for this annotation

GitHub Actions / build

'renderFunctionVarNames' is assigned a value but never used

Check warning on line 48 in src/utils/ast-transformations/main-ast-transform.ts

View workflow job for this annotation

GitHub Actions / build

'renderFunctionVarNames' is assigned a value but never used
j,
root,
abstractedFunctionName,
Expand All @@ -54,6 +56,7 @@
convertFind(j, root);

// Convert text()
astLogger.verbose('Convert text()');
convertText(j, root);

// Convert simulate()
Expand Down
30 changes: 30 additions & 0 deletions test/convert-enzyme-imports.jest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { convertImports } from '../src/utils/ast-transformations/individual-transformations/convert-enzyme-imports';
import jscodeshift from 'jscodeshift';

describe('convertText', () => {
let j: jscodeshift.JSCodeshift;

beforeEach(() => {
j = jscodeshift.withParser('tsx');
});

it('Should convert Enzyme imports to RTL imports', () => {
const source = `
import { mount } from 'enzyme';
`;

// Transform the source code
const root = j(source);
convertImports(j, root);

// Generate the transformed source code
const transformedSource = root.toSource();

const expectedSource = `
import { render, screen } from "@testing-library/react";
`;

// Check if the transformed source matches the expected source
expect(transformedSource).toBe(expectedSource);
});
});
2 changes: 1 addition & 1 deletion test/data/ast-conversion-test-file-verify.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import userEvent from "@testing-library/user-event";
import { render, screen } from "@testing-library/react";
import React from 'react';
import { mount } from 'enzyme';
import Component from '../components/..';


Expand Down
2 changes: 1 addition & 1 deletion test/data/ast-conversion-test-file-verify.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import userEvent from "@testing-library/user-event";
import { render, screen } from "@testing-library/react";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This made me think about other type of imports:
const { mount } = require('enzyme'); Going to add it some time later

import React from 'react';
import { mount } from 'enzyme';
import Component from '../components/..';


Expand Down
Loading