「mocha-phantomjs+jscoverageでコードカバレッジ出力」な流れをgruntに移植する

2013-03-17T12:00:00+09:00 grunt JavaScript

今までは

jscoverage lib
mocha-phantomjs -R json-cov test/runner.html | json2htmlcov > coverage.html

な感じなのを普通に実行してカバレッジを出力していた。こういうのもどうかと思うので、最近というかちょっと前だと思うけどGruntっていうNode.jsベースなビルドタスクツールな感じなので移植してみた

前提

以下が出来るタスクを定義する

  • jscoverageタスクでjscoverageを実行
  • testタスクでmocha-phantomjsを実行 (但しカバレッジは出力されない)
  • coverageタスクでmocha-phantomjs -R json-covをしつつのjson2htmlcovでカバレッジを出力
  • yuidocタスクでyuidocを生成

な感じ。でその前に問題があってjson2htmlcovが何やらおかしい。mocha-phantomjsのissueによるとjson2htmlcovが/dev/stdin使ってるのはよくないっていう話なんだと思いますが、まさに合致していてそれが原因で正常に出力が出来なかった。なのでこのhtml-cov.jsをマージしておく

あとはディレクトリにpackage.jsonとGruntfile.jsを書く

package.json

{
  "name": "twitter4chrome",
  "version": "0.0.1",
  "devDependencies": {
    "grunt": "0.4.0",
    "grunt-contrib-yuidoc": "0.4.0"
  }
}

yuidocタスクはgrunt-contrib-yuidocを使う事で可能らしいのでそれを使う。それ以外は自前で書く。そういうのがあるみたいだけど(ry

Gruntfile.js

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON("package.json"),
    yuidoc: {
      compile: {
        options: {
          paths: "lib", // libディレクトリにあるファイルのyuidocする
          outdir: "doc" // docディレクトリに出力
        }
      }
    }
  });

  // yuidocのタスクをロード?
  grunt.loadNpmTasks("grunt-contrib-yuidoc");

  var mochaRun = function(args, cb) {
    var mocha = grunt.util.spawn(
      {
        cmd: "mocha-phantomjs",
        args: args
      },
      cb
    );
    //mocha.stdout.pipe(process.stdout);
    mocha.stderr.pipe(process.stderr);

    return mocha;
  };

  // testタスクで使う
  grunt.registerTask(
    "test-mocha-phantomjs",
    "Run mocha-phantomjs",
    function() {
      var done = this.async();

      mochaRun(
        ["test/runner.html"],
        function(err, result, code) {
          console.log(result.stdout);

          done();
        }
      );
    }
  );

  // coverageタスクで使う
  grunt.registerTask(
    "test-mocha-phantomjs-coverage",
    "Run mocha-phantomjs -R json-cov",
    function() {
      var done = this.async();

      /* child_processを使ってやる場合
      var spawn = require("child_process").spawn;

      var mocha = spawn("mocha-phantomjs", ["-R", "json-cov", "test/runner.html"]);
      var covdata =[];

      mocha.stdout.on("data", function(data) {
        covdata.push(data.toString());
      });

      mocha.stderr.on("data", function(data) {
        console.log("ERR: " + data);
      });

      mocha.on("exit", function() {
        var cov = spawn("json2htmlcov");
        cov.stdin.write(covdata.join(""));
        cov.stdin.end();
        cov.stdout.on("data", function(data) {
          console.log(data.toString());
        });
      });
      */

      // json-covなカバレッジレポートを生成
      var mocha = mochaRun(
        ["-R", "json-cov", "test/runner.html" ],
        function(err, result, code) {

          // 生成されたjson-covなカバレッジレポートにjson2htmlcovをかます

          var cov = grunt.util.spawn(
            { cmd: "json2htmlcov" },
            function(err, result, code) {
              if (code === 0) {
                grunt.file.write("coverage.html", result.stdout);
              }

              done();
            }
          );

          // json2htmlcovはstdinで受け取るのでぶち込んでおく
          cov.stdin.write(result.stdout);
          cov.stdin.end();
        }
      );

      mocha.stderr.pipe(process.stderr);
    }
  );

  // jscoverageタスク
  grunt.registerTask(
    "jscoverage",
    "Run jscoverage",
    function() {
      var done = this.async();
      var jsc = grunt.util.spawn(
        {
          cmd: "jscoverage",
          args: ["lib"]
        },
        function(err, result, code) {
          done();
        }
      );
      jsc.stdout.pipe(process.stdout);
      jsc.stdout.pipe(process.stderr);
    }
  );

  // testタスクを定義。jscoverage及びtest-mocha-phantomjsタスクを実行する
  grunt.registerTask("test", ["jscoverage", "test-mocha-phantomjs"]);

  // coverageタスクを定義。jscoverage及びtest-mocha-phantomjs-coverageタスクを実行
  grunt.registerTask("coverage", ["jscoverage", "test-mocha-phantomjs-coverage"]);

};

yuidocでアンダースコア(アンダーバー)を使うと消える件 mocha-phantomjs+jscoverageでコードカバレッジ出力