Skip to content

Commit

Permalink
Add ts codemod tests. Use vitest for test.
Browse files Browse the repository at this point in the history
  • Loading branch information
origami-z committed Feb 1, 2024
1 parent fd1a267 commit 1c2b432
Show file tree
Hide file tree
Showing 5 changed files with 776 additions and 1,876 deletions.
179 changes: 178 additions & 1 deletion __tests__/migration/utils.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
import { getCssRenameCheckRegex } from "../../migration/utils.js";
import { describe, expect, test } from "vitest";
import * as tsm from "ts-morph";
import {
getCssRenameCheckRegex,
moveNamedImports,
renameReactElementName,
replaceReactAttribute,
} from "../../migration/utils.js";

/**
*
* @param {string} sourceFileString
* @returns
*/
function createFileWithContent(sourceFileString) {
const project = new tsm.Project({ useInMemoryFileSystem: true });
const file = project.createSourceFile("test.tsx", sourceFileString);
return file;
}

describe("getCssRenameCheckRegex", () => {
test("regex match var intended", () => {
Expand All @@ -15,3 +33,162 @@ describe("getCssRenameCheckRegex", () => {
expect(actual.test("--my-var: var(--salt-a-extra);")).toBe(false);
});
});

describe("moveNamedImports", () => {
test("move import to another existing import declaration", () => {
const file =
createFileWithContent(`import { ComponentOne, ComponentThree } from "package-a";
import { ComponentTwo } from "package-b";
export const App = () => {
return (
<ComponentOne />
);
};`);
moveNamedImports(file, {
namedImportText: "ComponentOne",
from: "package-a",
to: "package-b",
});
const actualResultText = file.getText();
expect(actualResultText).toContain(
`import { ComponentTwo, ComponentOne } from "package-b";`
);
expect(actualResultText).toContain(
`import { ComponentThree } from "package-a";`
);
});

test("move to a newly created import declaration", () => {
const file = createFileWithContent(
`import { ComponentOne, ComponentThree } from "package-a";
export const App = () => {
return (
<ComponentOne />
);
};`
);
moveNamedImports(file, {
namedImportText: "ComponentOne",
from: "package-a",
to: "package-b",
});
const actualResultText = file.getText();
expect(actualResultText).toContain(
`import { ComponentOne } from "package-b";`
);
expect(actualResultText).toContain(
`import { ComponentThree } from "package-a";`
);
});

test("removes empty import declaration after move", () => {
const file = createFileWithContent(
`import { ComponentOne } from "package-a";
export const App = () => {
return (
<ComponentOne />
);
};`
);
moveNamedImports(file, {
namedImportText: "ComponentOne",
from: "package-a",
to: "package-b",
});
const actualResultText = file.getText();
expect(actualResultText).toContain(
`import { ComponentOne } from "package-b";`
);
expect(actualResultText).not.toContain(`package-a`);
});

test("move and rename at the same time", () => {
const file = createFileWithContent(
`import { ComponentNext } from "package-one";
export const App = () => {
return (
<ComponentNext />
);
};`
);
moveNamedImports(file, {
namedImportText: "ComponentNext",
newName: "NewComponent",
from: "package-one",
to: "package-two",
});
const actualResultText = file.getText();
expect(actualResultText).toContain(
`import { NewComponent } from "package-two";`
);
expect(actualResultText).toContain(`<NewComponent />`);
});
});

describe("renameReactElementName", () => {
test("renames both opening and closing tag", () => {
const file =
createFileWithContent(`import { ComponentOne } from "package-a";
export const App = () => {
return (
<ComponentOne>
Some text
</ComponentOne>
);
};`);
renameReactElementName(file, {
from: "ComponentOne",
to: "AnotherComponent",
});
const actualResultText = file.getText();

expect(actualResultText).toContain(`<AnotherComponent>`);
expect(actualResultText).toContain(`</AnotherComponent>`);
expect(actualResultText).not.toContain(`<ComponentOne>`);
expect(actualResultText).not.toContain(`</ComponentOne>`);
});
test("renames self closing tag", () => {
const file =
createFileWithContent(`import { ComponentOne } from "package-a";
export const App = () => {
return (
<ComponentOne />
);
};`);
renameReactElementName(file, {
from: "ComponentOne",
to: "AnotherComponent",
});
const actualResultText = file.getText();

expect(actualResultText).toContain(`<AnotherComponent />`);
expect(actualResultText).not.toContain(`<ComponentOne />`);
});
});

describe("replaceReactAttribute", () => {
test("Renames prop name and value for a component with children", () => {
const file =
createFileWithContent(`import { ComponentOne } from "package-a";
export const App = () => {
return (
<ComponentOne prop1="a">
Some text
</ComponentOne>
);
};`);
replaceReactAttribute(file, {
elementName: "ComponentOne",
attributeFrom: "prop1",
valueFrom: `"a"`,
attributeTo: "prop2",
valueTo: `"b"`,
});
const actualResultText = file.getText();
expect(actualResultText).toContain(`<ComponentOne prop2="b">`);
});
});
6 changes: 0 additions & 6 deletions migration/core100.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,6 @@ export function react100(file) {
);

// Component props
if (saltProviderRenamed) {
renameReactElementName(file, {
from: "ToolkitProvider",
to: "SaltProvider",
});
}

// <Panel emphasis="medium"> => <Panel variant="primary">
// <Panel emphasis="high"> => <Panel variant="secondary">
Expand Down
8 changes: 4 additions & 4 deletions migration/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export function renameImportModuleSpecifier(
}

/**
* Used when a component is renamed from A -> B.
* Used when a component is renamed from A -> B. All usage of the import will also be renamed.
*
* @param {import("ts-morph").ImportDeclaration} declaration
*/
Expand Down Expand Up @@ -131,6 +131,8 @@ export function moveNamedImports(file, { namedImportText, from, to, newName }) {
}

/**
* Rename a React element name, but not import statement.
* This is rarely needed, and should consider use `moveNamedImports` with `newName` option instead.
*
* @param {import("ts-morph").SourceFile} file
*/
Expand All @@ -148,9 +150,7 @@ export function renameReactElementName(file, { from, to }) {
SyntaxKind.JsxSelfClosingElement,
]) {
for (const descendant of file.getDescendantsOfKind(syntaxKind)) {
const identifierNode = descendant.getFirstDescendantByKind(
SyntaxKind.Identifier
);
const identifierNode = descendant.getTagNameNode();
if (identifierNode) {
if (identifierNode.getText() === from) {
verboseOnlyLog(
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"salt-codemod": "./index.js"
},
"scripts": {
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
"test": "vitest"
},
"author": "Zhihao CUi",
"license": "ISC",
Expand All @@ -20,10 +20,11 @@
"fast-glob": "^3.2.12",
"resolve-package-path": "^4.0.3",
"semver": "^7.3.8",
"ts-morph": "^17.0.1",
"ts-morph": "^21.0.1",
"yargs": "^17.6.2"
},
"devDependencies": {
"jest": "^29.5.0"
"vite": "^5.0.12",
"vitest": "^1.2.2"
}
}
Loading

0 comments on commit 1c2b432

Please sign in to comment.