如何使用 istanbul API 从 grunt 加载配置

How to use the istanbul API to load config from grunt

我试图在不借助 .istanbul.yml 文件的情况下从 g运行t 引导伊斯坦布尔。想法是 运行 grunt-jasmine-nodejs 进行单元测试并将伊斯坦布尔集成为自定义报告程序:

module.exports = function(grunt) {
  grunt.initConfig({
    jasmine_nodejs: {
      options: {
        specNameSuffix: 'spec.js',
        useHelpers: false,
        reporters: {
          console: {}
        },
        customReporters: [
          require('./tests/lib/istanbul-reporter.js')({
            coverageVar: '__coverage__',
            dir: './tests/coverage'
            reports: ['text','json','html']
          })
        ]
      },
      default: {
        specs: [ 'tests/unit/**' ]
      }
    }
  });

  grunt.loadNpmTasks('grunt-jasmine-nodejs');
};

茉莉花记者还通知 sandboxed-module that it should instrument the tested files. The istanbul API doc 给出了它加载配置的想法 .loadFile():

module.exports = function (opt) {
    var istanbul = require('istanbul');
    istanbul.config.loadFile(false, {
        instrumentation: { variable: opt.coverageVar },
        reporting: { dir: opt.dir }
    });        

    var SandboxedModule = require('sandboxed-module');
    SandboxedModule.registerBuiltInSourceTransformer('istanbul');
    global[opt.coverageVar] = {};

    var collector, reporter;

    return {
        jasmineStarted: function () {
            collector = new istanbul.Collector();
            reporter = new istanbul.Reporter();
            reporter.addAll(opt.reports);
        },
        suiteStarted: function () {},
        suiteDone: function () {},
        specStarted: function () {},
        specDone: function () {},
        jasmineDone: function () {
            console.log('\n\n');
            collector.add(global[opt.coverageVar]);
            reporter.write(collector, true, function () {
                return;
            });
        }
    };
};

没用。我尝试了几种变体,包括 config.loadObject(config.defaultConfig(), {...}),但未应用覆盖。

除了从 g运行t 配置数据写入 .istanbul.yml 文件外,还有编程方式吗?

istanbul.config.loadFile 不初始化任何东西,它返回一个对象供进一步使用。

此外,沙盒模块目前不接受它使用的仪器的选项。有一个开放的pull request来处理这个。

所以暂时需要一个自定义源变压器。我重写的自定义茉莉花记者现在看起来像这样:

var istanbul = require('istanbul');
var instrumentMethod;

exports.init = function (opt) {
    var collector, reporter;

    global[opt.instrumenting.coverageVariable] = {};

    return {
        jasmineStarted: function () {
            var configObj = istanbul.config.loadFile(false, opt);        
            var instrumenter = new istanbul.Instrumenter(opt.instrumenting);
            instrumentMethod = instrumenter.instrumentSync.bind(instrumenter);
            collector = new istanbul.Collector();
            reporter = new istanbul.Reporter(configObj);
            reporter.addAll(opt.reporting.reports);
        },
        suiteStarted: function () {},
        suiteDone: function () {},
        specStarted: function () {},
        specDone: function () {},
        jasmineDone: function () {
            console.log('\n\n');
            collector.add(global[opt.instrumenting.coverageVariable]);
            reporter.write(collector, true, function () {
                return;
            });
        }
    };
};

exports.transformer =  function (source) {
    source = instrumentMethod(source, this.filename);
    return source;
};

opt 参数与 YAML 文件不兼容。有两个原因:

  1. 大部分处理多个文件,而沙盒模块的设置处理单个文件:您获取文件,然后对其进行转换。
  2. hookschecks 在定义仪器、收集器和报告器之外处理。

为避免混淆,我将第一部分命名为 instrumenting,而不是 instrumentation。交给了new Instrumenter(opt.instrumenting)。请注意 documentation 已过时 (v0.3.0)。第二部分 reporting 与 YAML 中的对应部分完全兼容。

在 Gruntfile 中,注意默认值:

require('./tests/lib/istanbul-reporter.js').init({
    instrumenting: {
        debug: false,                       // not in YAML
        walkDebug: false,                   // not in YAML
        codeGenerationOptions: undefined,   // not in YAML, see escodegen
        noAutoWrap: false,                  // not in YAML
        coverageVariable: '__coverage__',   // YAML name is variable
        noCompact: false,                   // YAML states compact: true
        embedSource: false,
        preserveComments: false,
        esModules: false
    },
    reporting: {
                                            // same as YAML
    }
}

最后,在 jasmine 规范中:

var SandboxedModule = require('sandboxed-module');
var isr = require('../lib/istanbul-reporter.js');

var testedModule = SandboxedModule.require('../../lib/tested-module.js', {
    // requires: { },
    // globals: { }, ...
    sourceTransformers: {
        istanbul: isr.transformer
    }
});