Skip to content

Commit

Permalink
chore: TextField codemods (#2386)
Browse files Browse the repository at this point in the history
Co-authored-by: Rivka Ungar <[email protected]>
  • Loading branch information
talkor and rivka-ungar authored Aug 29, 2024
1 parent a7b0a22 commit a1409c9
Show file tree
Hide file tree
Showing 3 changed files with 357 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,319 @@
import transform from "../text-field-component-migration";
import { defineInlineTest } from "jscodeshift/src/testUtils";

function prependImport(source: string): string {
return `
import { TextField } from "monday-ui-react-core";
${source}
`;
}

describe("TextField component migration", () => {
describe("dataTestId to data-testId", () => {
defineInlineTest(
transform,
{},
prependImport(`<TextField dataTestId="unique-id" />`),
prependImport(`<TextField data-testid="unique-id" />`),
"should update 'dataTestId' to 'data-testid'"
);

defineInlineTest(
transform,
{},
prependImport(`<div><TextField dataTestId="unique-id" /></div>`),
prependImport(`<div><TextField data-testid="unique-id" /></div>`),
"should update 'dataTestId' to 'data-testid' in a nested structure"
);

defineInlineTest(
transform,
{},
prependImport(`<TextField dataTestId="unique-id" name="Test TextField" />`),
prependImport(`<TextField data-testid="unique-id" name="Test TextField" />`),
"should update 'dataTestId' to 'data-testid' while maintaining other props"
);

defineInlineTest(
transform,
{},
prependImport(
`
<>
<TextField dataTestId="first-unique-id" />
<TextField dataTestId="second-unique-id" />
</>`
),
prependImport(`
<>
<TextField data-testid="first-unique-id" />
<TextField data-testid="second-unique-id" />
</>`),
"should handle multiple instances of TextField each with 'dataTestId'"
);

defineInlineTest(
transform,
{},
prependImport(`<TextField dataTestId="test-id" data-testid="other-test-id" />`),
prependImport(`<TextField dataTestId="test-id" data-testid="other-test-id" />`),
"should not change when when both 'dataTestId' and 'data-testid' props exist with different literal values"
);

defineInlineTest(
transform,
{},
prependImport(`<TextField dataTestId="test-id" data-testid="test-id" />`),
prependImport(`<TextField data-testid="test-id" />`),
"should remove 'dataTestId' when both 'dataTestId' and 'data-testid' props exist and have same values"
);

defineInlineTest(
transform,
{},
prependImport(`<TextField dataTestId="testId" data-testid={testId} />`),
prependImport(`<TextField dataTestId="testId" data-testid={testId} />`),
"should not change when when both 'dataTestId' and 'data-testid' props exist and have different complex values"
);

defineInlineTest(
transform,
{},
prependImport(`<TextField dataTestId={"testId"} data-testid="testId" />`),
prependImport(`<TextField data-testid="testId" />`),
"should remove 'dataTestId' when when both 'dataTestId' and 'data-testid' props exist with same literal values while one is inside an expression"
);

defineInlineTest(
transform,
{},
`<TextField dataTestId="unique-id" />`,
`<TextField dataTestId="unique-id" />`,
"should not change when no import even if 'dataTestId' prop exists"
);

defineInlineTest(
transform,
{},
prependImport(`<OtherComponent dataTestId="unique-id" />`),
prependImport(`<OtherComponent dataTestId="unique-id" />`),
"should not affect other components with 'dataTestId'"
);

defineInlineTest(
transform,
{},
`
import { TextField } from "other-library";
<TextField dataTestId="unique-id" />
`,
`
import { TextField } from "other-library";
<TextField dataTestId="unique-id" />
`,
"should not change when 'TextField' is not imported from vibe"
);

defineInlineTest(
transform,
{},
`
import { OtherComponent as TextField } from "other-library";
<TextField dataTestId="unique-id" />
`,
`
import { OtherComponent as TextField } from "other-library";
<TextField dataTestId="unique-id" />
`,
"should not change when 'TextField' is an alias for another component that is not from vibe"
);

defineInlineTest(
transform,
{},
`
import { OtherComponent as TextField } from "monday-ui-react-core";
<TextField dataTestId="unique-id" />
`,
`
import { OtherComponent as TextField } from "monday-ui-react-core";
<TextField dataTestId="unique-id" />
`,
"should not change when 'TextField' is an alias for another component from vibe"
);

defineInlineTest(
transform,
{},
`
import { TextField as VibeComponent } from "monday-ui-react-core";
<VibeComponent dataTestId="unique-id" />
`,
`
import { TextField as VibeComponent } from "monday-ui-react-core";
<VibeComponent data-testid="unique-id" />
`,
"should change when 'TextField' is imported with alias from vibe"
);
});

describe('remove "withReadOnlyStyle" prop', () => {
defineInlineTest(
transform,
{},
prependImport(`<TextField withReadOnlyStyle />`),
prependImport(`<TextField />`),
"should remove 'withReadOnlyStyle' prop"
);

defineInlineTest(
transform,
{},
prependImport(`<TextField withReadOnlyStyle={true} />`),
prependImport(`<TextField />`),
"should remove 'withReadOnlyStyle' prop if given with a value"
);

defineInlineTest(
transform,
{},
prependImport(
`
<>
<TextField withReadOnlyStyle data-testid="t1" />
<TextField withReadOnlyStyle data-testid="t2" />
</>`
),
prependImport(`
<>
<TextField data-testid="t1" />
<TextField data-testid="t2" />
</>`),
"should handle multiple instances of TextField each with 'withReadOnlyStyle'"
);

defineInlineTest(
transform,
{},
`<TextField withReadOnlyStyle />`,
`<TextField withReadOnlyStyle />`,
"should not change when no import even if 'withReadOnlyStyle' prop exists"
);

defineInlineTest(
transform,
{},
prependImport(`<OtherComponent withReadOnlyStyle />`),
prependImport(`<OtherComponent withReadOnlyStyle />`),
"should not affect other components with 'withReadOnlyStyle'"
);

defineInlineTest(
transform,
{},
`
import { TextField } from "other-library";
<TextField withReadOnlyStyle />
`,
`
import { TextField } from "other-library";
<TextField withReadOnlyStyle />
`,
"should not change when 'TextField' is not imported from vibe"
);

defineInlineTest(
transform,
{},
`
import { OtherComponent as TextField } from "other-library";
<TextField withReadOnlyStyle />
`,
`
import { OtherComponent as TextField } from "other-library";
<TextField withReadOnlyStyle />
`,
"should not change when 'TextField' is an alias for another component that is not from vibe"
);

defineInlineTest(
transform,
{},
`
import { OtherComponent as TextField } from "monday-ui-react-core";
<TextField withReadOnlyStyle />
`,
`
import { OtherComponent as TextField } from "monday-ui-react-core";
<TextField withReadOnlyStyle />
`,
"should not change when 'TextField' is an alias for another component from vibe"
);

defineInlineTest(
transform,
{},
`
import { TextField as VibeComponent } from "monday-ui-react-core";
<VibeComponent withReadOnlyStyle />
`,
`
import { TextField as VibeComponent } from "monday-ui-react-core";
<VibeComponent />
`,
"should change when 'TextField' is imported with alias from vibe"
);
});

describe('remove "requiredAsterisk" if "required" prop is given', () => {
defineInlineTest(
transform,
{},
prependImport(`<TextField required requiredAsterisk />`),
prependImport(`<TextField required />`),
"should remove 'requiredAsterisk' prop when 'required' prop exists"
);

defineInlineTest(
transform,
{},
prependImport(`<TextField requiredAsterisk />`),
prependImport(`<TextField requiredAsterisk />`),
"should not remove 'requiredAsterisk' when 'required' prop does not exist"
);

defineInlineTest(
transform,
{},
prependImport(`
<>
<TextField required />
<TextField requiredAsterisk />
</>
`),
prependImport(`
<>
<TextField required />
<TextField requiredAsterisk />
</>
`),
"should not remove 'requiredAsterisk' when 'required' prop is not present in the same component"
);

defineInlineTest(
transform,
{},
prependImport(`<TextField required requiredAsterisk label="Name" />`),
prependImport(`<TextField required label="Name" />`),
"should remove 'requiredAsterisk' when 'required' exists with multiple other props"
);

defineInlineTest(
transform,
{},
`<TextField requiredAsterisk />`,
`<TextField requiredAsterisk />`,
"should not remove 'requiredAsterisk' when no import even if 'required' prop exists"
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {
wrap,
getCoreImportsForFile,
getComponentNameOrAliasFromImports,
findComponentElements,
migratePropsNames,
removeProp,
isPropExists
} from "../../../src/utils";
import { TransformationContext } from "../../../types";

/**
* 1. Change the 'dataTestId' prop to 'data-testid'
* 2. Remove 'withReadOnlyStyle' prop
* 3. Remove 'requiredAsterisk' prop if 'required' prop exists
*/
function transform({ j, root, filePath }: TransformationContext) {
const imports = getCoreImportsForFile(root);
const componentName = getComponentNameOrAliasFromImports(j, imports, "TextField");
if (!componentName) return;

const elements = findComponentElements(root, componentName);
if (!elements.length) return;

elements.forEach(elementPath => {
migratePropsNames(j, elementPath, filePath, componentName, { dataTestId: "data-testid" });
removeProp(j, elementPath, "withReadOnlyStyle");
if (isPropExists(j, elementPath, "required")) {
removeProp(j, elementPath, "requiredAsterisk");
}
});
}

export default wrap(transform);
9 changes: 4 additions & 5 deletions packages/core/docs/vibe-3-changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,13 +282,12 @@ codemod: `tab-panels-import-migration`

### TextField

- `dataTestId` -> `data-testid` [codemod]
- `iconsNames` prop removed `layout` [codemod]
- `dataTestId` -> `data-testid` [codemod]
- `iconsNames` prop removed `layout`
- Behavior of asterisk is now controlled by `required` prop, which means a field with asterisk will have to be required.
- Removed `requiredAsterisk` [codemod] (codemod should replace only if `requiredAsterisk` is used with `required`)
- Remove `withReadOnlyStyle` prop, new read only style will apply when using `readOnly` prop [codemod - remove withReadOnlyStyle]
- Removed `requiredAsterisk` [codemod]
- Remove `withReadOnlyStyle` prop, new read only style will apply when using `readOnly` prop [codemod ]
- Removed `sm`, `md`, `lg` sizes, use `small`, `medium`, `large` respectively
-

### ThemeProvider

Expand Down

0 comments on commit a1409c9

Please sign in to comment.