How can I use Jest to test React components written in CoffeeScript + React jsx?
The only CoffeeScript example provided with Jest uses plain CoffeeScript, and doesn't work with CoffeeScript + React JSX (syntax error when it reaches a <
).
// preprocessor.js
var execSync = require('exec-sync');
module.exports = {
process: function (src, path) {
return execSync('browserify -t coffee-reactify ' + path);
}
};
This works, but takes too much time (a good 12 seconds for a dummy test).
Then I tried:
// preprocessor.js
var coffee = require('coffee-script');
var transform = require('coffee-react-transform');
module.exports = {
process: function(src, path) {
if (path.match(/\.coffee$/)) {
return coffee.compile(transform(src), {'bare': true});
}
return src;
}
};
This throws a strange error, like:
TypeError: function() {...} has no method 'getPooled'
The only Google result for "has no method 'getPooled'" is this gist, that shows exactly the error I get, but offers no other insights.
I think I could use coffee-reactify, but it returns a stream, which is asynchronous, while the process
function in preprocess.js
is used synchronously, and have found no way, so far, to read a stream synchronously.
What can I do?
You simple need to add a <script type="text/coffeescript" src="app. coffee"></script> to execute coffee script code in an HTML file. In other cases, I've seen people use the attributes of type="coffeescript" and type="coffee" , so they might work for you as well. Save this answer.
Load a remote script from the current domain via XHR. Activate CoffeeScript in the browser by having it compile and evaluate all script tags with a content-type of text/coffeescript . This happens on page load. Listen for window load, both in decent browsers and in IE.
I think your second approach was correct, except you did not (I'm guessing here) add react to "unmockedModulePathPatterns" in the jest
property of package.json. That is typically the result of the getPooled
error in my experience.
The following works for me:
package.json
// ...
"jest": {
"unmockedModulePathPatterns": ["<rootDir>/node_modules/react"],
"testFileExtensions": [
"js",
"coffee"
],
"scriptPreprocessor": "<rootDir>/preprocessor.js"
}
preprocessor.js
// I found it simpler to use coffee-react,
// since it does the jsx transform and coffeescript compilation
var coffee = require('coffee-react');
module.exports = {
process: function(src, path) {
if (path.match(/\.coffee$/)) {
return coffee.compile(src, {bare: true});
}
return src;
}
};
This whole process is difficult troubleshoot because errors can happen anywhere during the jsx -> coffee -> js -> jest
pipeline and get silently swallowed. I found it most helpful to troubleshoot this by running the transform in a separate file to make sure the jsx -> coffee
and coffee -> js
happened properly, and then run the jest preprocessor.
I have just published a boiler plate unit test for Jest that works with React & CoffeeScript.
https://github.com/Cotidia/jest-react-coffeescript
The preprocessor needs to be as follows:
var coffee = require('coffee-script');
var ReactTools = require('react-tools');
module.exports = {
process: function(src, path) {
// console.log('src', src);
if (path.match(/\.coffee$/)) {
// First we compile the coffeescript files to JSX
compiled_to_js = coffee.compile(src, {bare: true});
// Then we compile the JSX to React
compiled_to_react = ReactTools.transform(compiled_to_js)
return compiled_to_react;
}
return src;
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With