用coffeescript jsx开玩笑?

时间:2014-11-25 09:34:03

标签: node.js coffeescript reactjs react-jsx jestjs

如何使用Jest测试用CoffeeScript + React jsx编写的React组件?

Jest提供的唯一CoffeeScript示例使用普通的CoffeeScript,但不适用于CoffeeScript + React JSX(语法错误到达<时)。

我尝试了什么

第一次尝试:execSync

// preprocessor.js
var execSync = require('exec-sync');

module.exports = {
  process: function (src, path) {
    return execSync('browserify -t coffee-reactify ' + path);
  }
};

这可行,但需要花费太多时间(假测试需要12秒)。

然后我尝试了:

第二次尝试:咖啡反应变换

// 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;
  }
};

这引发了一个奇怪的错误,例如:

TypeError:function(){...}没有方法'getPooled'

“没有方法'getPooled'”的唯一Google结果是this gist,它显示了我得到的错误,但没有提供任何其他见解。

第三次可能的尝试

我想我可以使用coffee-reactify,但它会返回一个异步的流,而同步使用process中的preprocess.js函数,并且找不到任何方法,到目前为止,同步读取流。

我该怎么办?

3 个答案:

答案 0 :(得分:8)

我认为你的第二种方法是正确的,除非你没有(我在这里猜测)添加反应&#34; unmockedModulePathPatterns&#34;在package.json的jest属性中。这通常是我的经验中出现getPooled错误的结果。

以下适用于我:

<强>的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;
  }
};

整个过程很难排除故障,因为错误可能发生在jsx -> coffee -> js -> jest管道中的任何地方,并且会被静默吞下。我发现通过在单独的文件中运行转换以确保jsx -> coffeecoffee -> js正确发生,然后运行jest预处理器来解决此问题最有帮助。

答案 1 :(得分:4)

我刚刚发布了一个适用于Jest的锅炉板单元测试,它与React&amp; amp; CoffeeScript的。

https://github.com/Cotidia/jest-react-coffeescript

预处理器需要如下:

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;
  }
};

答案 2 :(得分:1)

基于user2534631的模板项目,我增强了使用coffee-react-transform来编译CJSX文件。

https://github.com/redice/jest-react-coffeescript

var coffee = require('coffee-script');
var transform = require('coffee-react-transform');

module.exports = {
  process: function(src, path) {
    if (coffee.helpers.isCoffee(path)) {
      compiled_cjx = transform(src);
      compiled_to_react = coffee.compile(compiled_cjx, {bare: true});

      return compiled_to_react;
    }

    return src;
  }
};

因此,使用CJSX语法编写React组件。

render: ->
  <label>
    <input
      type="checkbox"
      checked={this.state.isChecked}
      onChange={this.onChange} />
    {if this.state.isChecked then this.props.labelOn else this.props.labelOff}
  </label>