【问题标题】:Typescript code coverage of multiple __extends declarations多个 __extends 声明的打字稿代码覆盖率
【发布时间】:2014-03-03 19:06:03
【问题描述】:

当它编译我的代码时,TypeScript 在每个文件的顶部包含一个 __extends 声明:

var __extends = this.__extends || function (d, b) {
    /* istanbul ignore next */
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};

这在幕后工作得很好,但在使用 karma-coverage 之类的东西来生成报告时会产生不一致。该声明包含两个函数调用和代码中的一个分支(|| 用法),它们只会在第一个声明中执行,留下数十个(如果不是数百个)后续声明没有覆盖。这使得具有 100% 代码覆盖率的文件在覆盖率报告中看起来非常难以发现。

有人解决了这个问题吗?

【问题讨论】:

    标签: typescript code-coverage karma-runner istanbul


    【解决方案1】:

    我在 typescript codeplex 找到了一个工作项。我希望打字稿人尽快解决这个问题。你可以在这里找到更多信息:typescript workitem 2002

    【讨论】:

    • 谢谢,我们实际上提交了类似的票证,并注明为重复。与此同时,我们分叉了编译器并自己实现了 _noExtends 选项,它就像一个魅力;)
    • CodePlex 问题现已关闭。试试看:github.com/Microsoft/TypeScript/issues/1350
    【解决方案2】:

    我刚刚在我的脚本任务中创建了一个函数,该函数将一个标题附加到任何使用继承的文件的顶部。这大大提高了代码覆盖率。我使用的是伊斯坦布尔,所以我的函数如下所示:

    function istanbulIgnoreTypeScriptExtend() {
        var tsExtends = /^var __extends =/;
        return through.obj(function(file, enc, done) {
            if (file.isBuffer() && tsExtends.test(file.contents)) {
                file.contents = Buffer.concat([
                    new Buffer('/* istanbul ignore next: TypeScript extend */' + os.EOL),
                    file.contents
                ]);
            }
            this.push(file);
            done();
        });
    }
    

    我实际上可以将它作为一个 gulp 插件发布,但我希望很快有新的方法来解决这个问题。

    【讨论】:

      【解决方案3】:

      从 2.1 开始,typescript 支持外部帮助程序库,所有发出的函数都转到 tslib

      npm install --save tslib
      

      更改您的 tsconfig:

      {
          "compilerOptions": {
              //all the other stuff
              "importHelpers": true
          }
      }
      

      然后TypeScript会在必要时自动导入tslib包 像下面的例子

      var tslib_1 = require("tslib");
      
      var MyClass = (function (_super) {
          tslib_1.__extends(MyClass, _super);
          function MyClass() {
              return _super !== null && _super.apply(this, arguments) || this;
          }
          return MyClass;
      }(controller_1.Controller));
      

      【讨论】:

      • 这似乎是当前正确的解决方案,谢谢
      【解决方案4】:

      这里是使用their answer 中提供的函数@jedmao 和gulp 任务的示例。 我稍微修改了它以处理 var __extends= 不是文件中的第一件事(例如,如果您有 'use strict'/// <references 标签)。您可能还应该像 jedmao 那样使用 os.EOL,而不是像我在这里所做的那样使用 \n

      var gulp     = require('gulp');
      var through2 = require('through2');
      
      gulp.task('my-gulp-task', function() {
          gulp.src('*.ts')
              .pipe(myTypeScriptCompiler())
              .pipe(istanbulIgnoreTypeScriptExtend())
              .pipe(gulp.dest('myDestFolder'));
      });
      
      function istanbulIgnoreTypeScriptExtend() {
          var tsExtends = /var __extends =/;
          return through2.obj(function(file, enc, done) {
              if (file.isBuffer() && tsExtends.test(file.contents)) {
                  var rows = file.contents.toString().split('\n');
                  for (var i = 0; i < rows.length; i++) {
                      if (rows[i].indexOf('var __extends =') === 0) {
                          rows.splice(i, 0, '/* istanbul ignore next: TypeScript extend */');
                          break;
                      }
                  }
                  file.contents = new Buffer(rows.join('\n'));
              }
              this.push(file);
              done();
          });
      }
      

      【讨论】:

        【解决方案5】:

        打字稿编译器将在每个具有 extends 关键字的文件之上生成此文件。使其成为单一用途的唯一方法是使用 --out 编译器标志编译成单个 js 文件。

        【讨论】:

        • 感谢您的回答,但这只是问题的重述。显然,编译到单个文件会生成几乎无用的覆盖率报告。似乎 TSC 应该有一个选项,或者应该有一种方法可以通过 karma-coverage 选项忽略这些多个实例......甚至是创造性的 shell 脚本解决方案?好奇其他人可能做了什么。
        猜你喜欢
        • 1970-01-01
        • 2018-03-10
        • 2018-09-30
        • 1970-01-01
        • 2013-11-21
        • 2012-06-30
        • 1970-01-01
        • 2014-10-03
        • 2018-04-10
        相关资源
        最近更新 更多