1

我在尝试使用 Karma 运行 Angular2 + TypeScript 测试时遇到了一些问题。

这是我的场景:

假设我有一个简单的管道:

    import {PipeTransform, Pipe, Injectable} from 'angular2/core';

    @Injectable()
    @Pipe({name: 'ucfirst'})
    export class UcFirstPipe implements PipeTransform {

      transform(text:string):string {
        return text.slice(0, 1).toUpperCase() + text.slice(1);
      }
    }

和以下规格:

import {it, describe, expect, beforeEach, inject} from 'angular2/testing';
import {UcFirstPipe} from "./ucfirst";

describe('UcFirstPipe Tests', () => {
  let pipe:UcFirstPipe;

  beforeEach(() => {
    pipe = new UcFirstPipe();
  });

  it('Should capitalize first word in a string', () => {
    var result = pipe.transform('foo bar baz');

    expect(result).toEqual('Foo bar baz');
  });
});

这是我的目录结构:

src/
   pipes/ 
     - ucfirst.ts
     - ucfirst.spec.ts

使用 Karma 编译和运行测试时,使用此目录结构一切正常。但是,当我将 ucfirst*.ts 移动到管道下的子目录时,例如:

src/
   pipes/ 
     string/ 
       - ucfirst.ts
       - ucfirst.spec.ts

我收到以下错误:

Error: XHR error (404 Not Found) loading .../compiled/pipes/string/ucfirst
        Error loading .../compiled/pipes/string/ucfirst as "./ucfirst" from ../compiled/pipes/string/ucfirst.spec.js

这些是我的配置文件:

tsconfig.json

{
  "files": [
    "./typings/**/*.d.ts"
  ],
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "sourceMap": true,
    "removeComments": true,
    "declaration": true,
    "noImplicitAny": false,
    "preserveConstEnums": true
  },
  "exclude": [
    "node_modules"
  ]
}

业力.conf.js:

module.exports = function(config) {
    config.set({

        basePath: '.',

        frameworks: ['jasmine'],

        files: [
            // paths loaded by Karma
            {pattern: 'node_modules/angular2/bundles/angular2-polyfills.js', included: true, watched: true},
            {pattern: 'node_modules/systemjs/dist/system.src.js', included: true, watched: true},
            {pattern: 'node_modules/rxjs/bundles/Rx.js', included: true, watched: true},
            {pattern: 'node_modules/angular2/bundles/angular2.dev.js', included: true, watched: true},
            {pattern: 'node_modules/angular2/bundles/testing.dev.js', included: true, watched: true},
            {pattern: 'karma-test-shim.js', included: true, watched: true},

            // paths loaded via module imports
            {pattern: 'compiled/**/*.js', included: false, watched: true},

            // paths to support debugging with source maps in dev tools
            {pattern: 'src/**/*.ts', included: false, watched: false},
            {pattern: 'compiled/**/*.js.map', included: false, watched: false}
        ],

        // proxied base paths
        proxies: {
            // required for component assests fetched by Angular's compiler
            '/src/': '/base/src/'
        },

        port: 9876,

        logLevel: config.LOG_INFO,

        colors: true,

        autoWatch: true,

        browsers: ['Chrome'],

        // Karma plugins loaded
        plugins: [
            'karma-jasmine',
            'karma-coverage',
            'karma-chrome-launcher'
        ],

        // Coverage reporter generates the coverage
        reporters: ['progress', 'dots', 'coverage'],

        // Source files that you wanna generate coverage for.
        // Do not include tests or libraries (these files will be instrumented by Istanbul)
        preprocessors: {
            'compiled/**/!(*spec).js': ['coverage']
        },

        coverageReporter: {
            reporters:[
                {type: 'json', subdir: '.', file: 'coverage-final.json'}
            ]
        },

        singleRun: true
    })
};

业力测试垫片:

// Tun on full stack traces in errors to help debugging
Error.stackTraceLimit = Infinity;

jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;

// // Cancel Karma's synchronous start,
// // we will call `__karma__.start()` later, once all the specs are loaded.
__karma__.loaded = function() {};

System.config({
    packages: {
        'base/compiled': {
            defaultExtension: false,
            format: 'cjs',
            map: Object.keys(window.__karma__.files).filter(onlyAppFiles).reduce(createPathRecords, {})
        }
    }
});

System.import('angular2/src/platform/browser/browser_adapter')
    .then(function(browser_adapter) { browser_adapter.BrowserDomAdapter.makeCurrent(); })
    .then(function() { return Promise.all(resolveTestFiles()); })
    .then(function() { __karma__.start(); }, function(error) { __karma__.error(error.stack || error); });

function createPathRecords(pathsMapping, appPath) {
    // creates local module name mapping to global path with karma's fingerprint in path, e.g.:
    // './vg-player/vg-player':
    // '/base/compiled/vg-player/vg-player.js?f4523daf879cfb7310ef6242682ccf10b2041b3e'
    var pathParts = appPath.split('/');
    var moduleName = './' + pathParts.slice(Math.max(pathParts.length - 2, 1)).join('/');
    moduleName = moduleName.replace(/\.js$/, '');
    pathsMapping[moduleName] = appPath + '?' + window.__karma__.files[appPath];
    return pathsMapping;
}

function onlyAppFiles(filePath) {
    return /\/base\/compiled\/(?!.*\.spec\.js$).*\.js$/.test(filePath);
}

function onlySpecFiles(path) {
    return /\.spec\.js$/.test(path);
}

function resolveTestFiles() {
    return Object.keys(window.__karma__.files)  // All files served by Karma.
        .filter(onlySpecFiles)
        .map(function(moduleName) {
            // loads all spec files via their global module names (e.g.
            // 'base/compiled/vg-player/vg-player.spec')
            return System.import(moduleName);
        });
}
4

0 回答 0