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

时间:2016-07-19 14:17:57

标签: node.js gruntjs jasmine istanbul

我试图在不诉诸.istanbul.yml文件的情况下从grunt引导伊斯坦布尔。我们的想法是运行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它应该检测测试文件。 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(), {...}),但未应用覆盖。

除了从grunt配置数据中编写.istanbul.yml文件外,是否有编程方式?

1 个答案:

答案 0 :(得分:0)

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. 大型部件处理多个文件,而使用sandboxed-module的设置处理单个文件:您获取文件,然后对其进行转换。
  2. hookschecks在定义指导员,收藏家和记者之外处理。
  3. 为避免混淆,我将第一部分instrumenting命名为instrumentation,而不是new Instrumenter(opt.instrumenting)。它交给reporting。请注意documentation已过时(v0.3.0)。第二部分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 } } 与YAML中的对应部分完全兼容。

    在Gruntfile中,注意默认值:

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

    最后,在茉莉花规格中:

    >>> l1=[1,2,3]
    >>> l2=[4,5,6]
    >>> l3=[7,8,9]
    >>> zip(l1, l2, l3)
    [(1, 4, 7), (2, 5, 8), (3, 6, 9)]