6

My team has been using both coffeescript and ES6/ES2015 (via Babel) in our project. Since the files are ultimately compatible due to Babel, it's been working great. But I can't figure out how we can write a jest test that allows both.

I've found examples of how to use jest with coffee, or ES6 features, but not both:

These all work. But again, I can't figure out how to combine them

What I've tried

  • I tried my own solution:

    In package.json I have:

    "jest": {
      "scriptPreprocessor": "<rootDir>/jest-script-preprocessor",
      "unmockedModulePathPatterns": [
        "<rootDir>/node_modules/react",
        "<rootDir>/node_modules/react-dom",
        "<rootDir>/node_modules/react-addons-test-utils",
        "<rootDir>/node_modules/fbjs"
      ],
      "testFileExtensions": ["coffee", "cjsx", "js", "jsx"],
      "moduleFileExtensions": ["coffee", "cjsx", "js", "jsx"]
    }
    

    In jest-script-preprocessor.js, I have:

    var coffee = require('coffee-react');
    var transform = require('coffee-react-transform');
    var babelJest = require("babel-jest");
    
    module.exports = {
        process: function(src, path) {
            if (coffee.helpers.isCoffee(path)) {
                console.log(path);
                return coffee.compile(transform(src), {
                    'bare': true
                });
            } else {
                console.log(path);
                return babelJest.process(src, {
                    filename: path,
                    stage: 0
                });
            }
        }
    };
    

    If I run a test like npm test __tests__/sometest.jsx, it loads the ES6 test file fine. That test file will import the module under test, which is also ES6, and THAT'S where it blows up. It simply says Unexpected reserved word as soon as it hits an ES6-only syntax, like import, export, etc. There is no additional line information, but I know it's ES6 that causes the problem because if I change the module under test to be ONLY export default 'mystring', it blows up, and if I change it to non-ES6 syntax like var q = 5 + 5; module.exports = q;, it imports the module fine. (Of course, that's not really a testable module, but it doesn't need to be for this proof-of-concept.)

    Note the console.log() lines in there. I never see them. So one reason this has been so tricky to track down is I can't put any of my own debug logic in. I'm sure these lines run, because if I throw in some random syntax on those lines, it'll choke. But no console output.

  • I've tried jest-webpack-alias, which is officially recommended by jest, and it sounds great in theory: you use jest with webpack, which then allows you to use whatever preprocessors you've already set up. It gives me the same error of Unexpected reserved word. I wrote up an issue on their github repo.

Notes

  • I found jestpack, but I don't want to use it as it requires Node >= 5, and I want to use Node 4.2.3. It also doesn't work with Jest >= 0.8, and I want to use Jest 0.8, as it's currently the latest and I assume has the best chance of being in sync with the live docs and react version (0.14.6).
Community
  • 1
  • 1
Tyler Collier
  • 11,489
  • 9
  • 73
  • 80

1 Answers1

0

Here's what I'm doing that's working for me.

npm install --save-dev babel-jest
npm install --save-dev coffee-react

In package.json:

"jest": {
    "scriptPreprocessor": "<rootDir>/jest-script-preprocessor",
    "unmockedModulePathPatterns": [
        "<rootDir>/node_modules/."
    ],
    "testFileExtensions": ["coffee", "cjsx", "js", "jsx"],
    "moduleFileExtensions": ["coffee", "cjsx", "js", "jsx"]
}

Take note of the unmockedModulePathPatterns. I set it to match everything in node_modules. You might not want that, but if you start getting errors like Error: Failed to get mock metadata:..., consider it, as recommended here.

In jest-script-preprocessor.js:

var babelJest = require('babel-jest');
var coffee = require('coffee-react');

module.exports = {
    process: function(src, filename) {
        if (filename.indexOf('node_modules') === -1) {
            if (filename.match(/\.coffee|\.cjsx/)) {
                src = coffee.compile(src, {bare: true});
            } else {
                src = babelJest.process(src, filename);
            }
        }
        return src;
    }
};
Community
  • 1
  • 1
Tyler Collier
  • 11,489
  • 9
  • 73
  • 80