facebook / jscodeshift

A JavaScript codemod toolkit.
https://jscodeshift.com
MIT License
9.32k stars 481 forks source link

defineInlineTest doesn't support async transforms #454

Open robatwilliams opened 3 years ago

robatwilliams commented 3 years ago

Since #237, transformers can be async.

However testing such transformers using defineInlineTest doesn't appear to be supported, and from the code also looks like it won't be suppored by any type of unit test.

Error: TypeError: (output || "").trim is not a function

MonicaOlejniczak commented 3 years ago

I have the same problem :(

danieldelcore commented 2 years ago

Hey all, in case anyone finds it useful here's an alternate testing util that supports async transforms. Feel free to either copy-paste or pull the library as a dep.

The API is different to defineInlineTest because it allows for you to still have access to jest library features like it.skip, it.only etc.

applyTransform

Example:

import * as transformer from '../transform';
import { applyTransform } from '@codeshift/test-utils';

it('should wrap avatar in a tooltip if name is defined', async () => {
  const result = await applyTransform(transformer, `const foo = 'foo';`);

  expect(result).toMatchInlineSnapshot(`"const oof = 'oof';"`);
});

here's the implementation in case you would rather copy-paste:

import jscodeshift from 'jscodeshift';

type Parser = 'babel' | 'babylon' | 'flow' | 'ts' | 'tsx';

interface Options {
  parser?: Parser;
}

export default async function applyTransform(
  transform: any,
  input: string,
  options: Options = {
    parser: 'babel',
  },
) {
  // Handle ES6 modules using default export for the transform
  const transformer = transform.default ? transform.default : transform;
  const output = await transformer(
    { source: input },
    {
      jscodeshift: jscodeshift.withParser(options.parser as string),
      stats: () => {},
    },
    options || {},
  );

  return (output || '').trim();
}