Skip to content

Commit

Permalink
Add migrate-to-test-package codemod
Browse files Browse the repository at this point in the history
  • Loading branch information
kasperpeulen committed Feb 8, 2024
1 parent 2e7405f commit 4cd82bb
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { expect, test } from 'vitest';
import transform from '../migrate-to-test-package';
import dedent from 'ts-dedent';

expect.addSnapshotSerializer({
serialize: (val: any) => (typeof val === 'string' ? val : val.toString()),
test: () => true,
});

const tsTransform = (source: string) => transform({ source, path: 'Component.stories.tsx' }).trim();

test('replace jest and testing-library with the test package', () => {
const input = dedent`
import { expect } from '@storybook/jest';
import { within, userEvent } from '@storybook/testing-library';
`;

expect(tsTransform(input)).toMatchInlineSnapshot(`
import { expect } from "@storybook/test";
import { within, userEvent } from "@storybook/test";
`);
});

test('Make jest imports namespace imports', () => {
const input = dedent`
import { expect, jest } from '@storybook/jest';
import { within, userEvent } from '@storybook/testing-library';
const onFocusMock = jest.fn();
const onSearchMock = jest.fn();
jest.spyOn(window, 'Something');
`;

expect(tsTransform(input)).toMatchInlineSnapshot(`
import * as test, { expect } from "@storybook/test";
import { within, userEvent } from "@storybook/test";
const onFocusMock = test.fn();
const onSearchMock = test.fn();
test.spyOn(window, 'Something');
`);
});
49 changes: 49 additions & 0 deletions code/lib/codemod/src/transforms/migrate-to-test-package.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* eslint-disable no-underscore-dangle */
import type { FileInfo } from 'jscodeshift';
import { loadCsf, printCsf } from '@storybook/csf-tools';
import type { BabelFile } from '@babel/core';
import * as babel from '@babel/core';
import * as t from '@babel/types';

export default function transform(info: FileInfo): string {
const csf = loadCsf(info.source, { makeTitle: (title) => title });
const fileNode = csf._ast;
// @ts-expect-error File is not yet exposed, see https://github.com/babel/babel/issues/11350#issuecomment-644118606
const file: BabelFile = new babel.File(
{ filename: info.path },
{ code: info.source, ast: fileNode }
);

file.path.traverse({
ImportDeclaration: (path) => {
if (
path.node.source.value === '@storybook/jest' ||
path.node.source.value === '@storybook/testing-library'
) {
if (path.node.source.value === '@storybook/jest') {
path.get('specifiers').forEach((specifier) => {
if (specifier.isImportSpecifier()) {
const imported = specifier.get('imported');
if (!imported.isIdentifier()) return;
if (imported.node.name === 'jest') {
specifier.remove();
path.node.specifiers.push(t.importNamespaceSpecifier(t.identifier('jest')));
}
}
});
}
path.get('source').replaceWith(t.stringLiteral('@storybook/test'));
}
},
Identifier: (path) => {
console.log(path.node.name);
if (path.node.name === 'jest') {
path.replaceWith(t.identifier('test'));
}
},
});

return printCsf(csf).code;
}

export const parser = 'tsx';

0 comments on commit 4cd82bb

Please sign in to comment.