vendredi 26 avril 2019

Creating a custom transform in Jest

I'm trying to create a custom transform for Jest, but running into a documentation roadblock which has me asking myself if I'm even on the right track.

Problem

I have a Rails project which is serving a Vue JS app. I want to write Jest tests for the JS app. In order to pass config variables from Rails to the app, I'm using ERB to template a small number of .js files. For example:

// in server-routes.js.erb
export default {
  reports: '<%= Rails.application.config.relative_url_root %><%= Rails.application.routes.url_helpers.reports_path %>',
  ...

In my Webpack build for the Vue app, I use rails-erb-loader to preprocess the *.erb files before they get passed to the rest of the build process.

However, when I run my JS tests, Jest doesn't know anything about ERB loaders (reasonably enough). So my goal is to add a custom transform for Jest to convert the ERB files when running npm test.

Approach

I thought I might be able to use rails-erb-loader as a Jest transform:

// package.json
"jest": {
  "moduleFileExtensions": [
    "js",
    "json",
    "vue"
  ],
  "moduleDirectories": [
    "<rootDir>/node_modules"
  ],
  "transform": {
    ".*\\.(vue)$": "vue-jest",
    "^.+\\.js$": "babel-jest",
    "^.+\\.js\\.erb$": "rails-erb-loader"
  },

This doesn't work, however, because Jest transforms and Webpack loaders seemingly have different signatures. In particular, Jest expects a process function:

$ npm test
 FAIL  app/javascript/components/__tests__/dummy.test.js
 ● Test suite failed to run
TypeError: Jest: a transform must export a `process` function.

> 101 | import ServerRoutes from '../server-routes.js.erb';
      | ^

  at ScriptTransformer._getTransformer (node_modules/@jest/transform/build/ScriptTransformer.js:291:15)
  at ScriptTransformer.transformSource (node_modules/@jest/transform/build/ScriptTransformer.js:353:28)
  at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:457:40)
  at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:513:25)
  at app/javascript/components/related-media.vue:101:1
  at Object.<anonymous> (app/javascript/components/related-media.vue:232:3)

And this is where I get stuck, because I can't see where it's documented what the API and behaviour of a process function should be. In the documentation for the transform config option there's a single not very helpful example, and that's it as far as docs go, unless I've missed something.

I also note that babel-jest has a createTransformer function which sounds like it might be helpful, or at least illuminating, but again I can't find any docs on what it does.

If anyone has pointers on the details of creating custom Jest transforms, or at least some better docs, that would be great! Or, if I'm going about this the wrong way, what should I be doing?

Aucun commentaire:

Enregistrer un commentaire