简体   繁体   English

让 TypeScript、Karma、RequireJS 和 Chai 一起工作的问题

[英]Issue getting TypeScript, Karma, RequireJS and Chai to work together

I'm trying to rewrite one of my projects using TypeScript and because I'm quite new to TypeScript and RequireJS I'm not sure what I'm missing.我正在尝试使用 TypeScript 重写我的一个项目,因为我对 TypeScript 和 RequireJS 还很陌生,我不确定我错过了什么。

I've followed this guide Karma - RequireJS and double checked everything, yet I haven't managed to get it working at least not RequireJS.我已经按照这个指南Karma - RequireJS并仔细检查了所有内容,但我还没有设法让它工作,至少不是 RequireJS。

PS The error I'm getting is at the end of the post. PS 我得到的错误是在帖子的末尾。

The directory structure I'm using for this project is as follow:我用于这个项目的目录结构如下:

.
|-- WebEssentials-Settings.json
|-- build
|-- jake.sh
|-- jakefile.js
|-- node_modules
|   |-- chai
|   |   |-- CONTRIBUTING.md
|   |   |-- History.md
|   |   |-- README.md
|   |   |-- ReleaseNotes.md
|   |   |-- bower.json
|   |   |-- chai.js
|   |   |-- index.js
|   |   |-- karma.conf.js
|   |   |-- karma.sauce.js
|   |   |-- lib
|   |   |-- node_modules
|   |   |-- package.json
|   |   `-- sauce.browsers.js
|   |-- jake
|   |   |-- Jakefile
|   |   |-- Makefile
|   |   |-- README.md
|   |   |-- bin
|   |   |-- lib
|   |   |-- node_modules
|   |   |-- package.json
|   |   `-- test
|   |-- karma
|   |   |-- CHANGELOG.md
|   |   |-- LICENSE
|   |   |-- README.md
|   |   |-- bin
|   |   |-- config.tpl.coffee
|   |   |-- config.tpl.js
|   |   |-- config.tpl.ls
|   |   |-- karma-completion.sh
|   |   |-- lib
|   |   |-- node_modules
|   |   |-- package.json
|   |   |-- requirejs.config.tpl.coffee
|   |   |-- requirejs.config.tpl.js
|   |   `-- static
|   |-- karma-chai
|   |   |-- LICENSE
|   |   |-- README.md
|   |   |-- adapter.js
|   |   |-- index.js
|   |   `-- package.json
|   |-- karma-mocha
|   |   |-- LICENSE
|   |   |-- README.md
|   |   |-- lib
|   |   `-- package.json
|   |-- karma-requirejs
|   |   |-- LICENSE
|   |   |-- README.md
|   |   |-- lib
|   |   `-- package.json
|   |-- mocha
|   |   |-- Readme.md
|   |   |-- bin
|   |   |-- images
|   |   |-- index.js
|   |   |-- lib
|   |   |-- mocha.css
|   |   |-- mocha.js
|   |   |-- node_modules
|   |   `-- package.json
|   |-- requirejs
|   |   |-- README.md
|   |   |-- bin
|   |   |-- package.json
|   |   `-- require.js
|   `-- shelljs
|       |-- LICENSE
|       |-- README.md
|       |-- bin
|       |-- global.js
|       |-- make.js
|       |-- package.json
|       |-- scripts
|       |-- shell.js
|       `-- src
|-- scratchpad.txt
|-- src
|   |-- app.main.js
|   |-- app.main.js.map
|   |-- app.main.ts
|   |-- core
|   |   |-- exceptions.js
|   |   |-- exceptions.js.map
|   |   |-- exceptions.ts
|   |   |-- string.js
|   |   |-- string.js.map
|   |   |-- string.ts
|   |   |-- types.js
|   |   |-- types.js.map
|   |   `-- types.ts
|   |-- css
|   |-- index.html
|   |-- libs
|   |   |-- jquery-2.1.0.js
|   |   |-- require.js
|   |   `-- typings
|   |-- tests
|   |   |-- core
|   |   |-- test.main.js
|   |   |-- test.main.js.map
|   |   `-- test.main.ts
|   |-- tsToolkit.csproj
|   |-- tsToolkit.csproj.user
|   |-- web.Debug.config
|   |-- web.Release.config
|   |-- web.config
|   `-- widgets
|-- tools
|   |-- karma
|   |   `-- karma.conf.js
|   |-- lint
|   |   `-- lint_runner.js
|   `-- mocha
|       `-- mocha.ext.js
|-- tsToolkit.sln
|-- tsToolkit.sln.DotSettings.user
`-- tsToolkit.v12.suo

43 directories, 83 files

Here is the configuration file I'm using for Karma.这是我用于 Karma 的配置文件。 -- karma.conf.js -- karma.conf.js

// Karma configuration
// Generated on Wed Sep 25 2013 00:47:38 GMT+0300 (Jerusalem Daylight Time)

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

    // base path, that will be used to resolve files and exclude
    basePath: '../../',


    // frameworks to use
    frameworks: ['requirejs', 'mocha', 'chai'],


    // list of files / patterns to load in the browser
    files: [
        "tools/mocha/mocha.ext.js",
        "src/libs/*.js",
        "src/tests/*/*.js",
        "src/tests/test.main.js"
    ],


    // list of files to exclude
    exclude: [
        'src/main.js'
    ],


    // test results reporter to use
    // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
    reporters: ['progress'],


    // web server port
    port: 8380,


    // enable / disable colors in the output (reporters and logs)
    colors: true,


    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,


    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,


    // Start these browsers, currently available:
    // - Chrome
    // - ChromeCanary
    // - Firefox
    // - Opera
    // - Safari (only Mac)
    // - PhantomJS
    // - IE (only Windows)
    browsers: [],


    // If browser does not capture in given timeout [ms], kill it
    captureTimeout: 60000,


    // Continuous Integration mode
    // if true, it capture browsers, run tests and exit
    singleRun: false
  });
};

Here is the configuration I have for RequireJS - tests.main.js这是我对 RequireJS 的配置 - tests.main.js

interface Window {
// ReSharper disable InconsistentNaming
    __karma__: any;
// ReSharper restore InconsistentNaming
}

var tests = [];
for (var file in window.__karma__.files) {
    if (window.__karma__.files.hasOwnProperty(file)) {
        if (/\.tests\.js$/.test(file))
        {
            tests.push(file);
        }
    }
}

declare var requirejs: any;
requirejs.config({
    baseUrl: '/base/src',

    deps: tests,

    callback: window.__karma__.start
});

Here is the test file -- types.tests.ts这是测试文件——types.tests.ts

import Types = require("./../../core/types");

describe("isUndefined", () =>
{
    it("should return true when the object is undefined", () =>
    {
    });
});

and here is the thing I'm trying to test.这是我要测试的东西。

class Types {
    public static isNull(value: any) : boolean
    {
        return false;
    }

    public static isUndefined(value: any) : boolean
    {
        return false;
    }

    public static isString(value: any) : boolean
    {
        return false;
    }

    public static isElement(value: any) : boolean
    {
        return false;
    }

    public static isNumber(value: any) : boolean
    {
        return false;
    }
}

export = Types;

Finally, here is the error I'm getting.最后,这是我得到的错误。

INFO [IE 9.0.0 (Windows 7)]: Connected on socket H-LT4D3cwsrYq1V01VdY with id manual-4093
IE 9.0.0 (Windows 7) ERROR
  Mismatched anonymous define() module: function(require, exports) {
      describe("isUndefined", function () {
          it("should return true when the object is undefined", function () {
          });
      });
  }
  http://requirejs.org/docs/errors.html#mismatch
  at D:/Projects/Code/Development/Visual Studio/tsToolkit/node_modules/requirejs/require.js:141

NOTES:笔记:

I tried to edit the produced .js file of the test and use named modules just to make sure everything works and it does!我试图编辑生成的 .js 测试文件并使用命名模块来确保一切正常,并且确实如此! but I guess that it doesn't make a lot of sense to go through each test and add a name to the produced .js file, isn't?但我想通过每个测试并为生成的 .js 文件添加一个名称没有多大意义,不是吗?

define("core/types", ["require", "exports"], function(require, exports) {
    describe("isUndefined", function () {
        it("should return true when the object is undefined", function () {
        });
    });
});
//# sourceMappingURL=types.tests.js.map

I'm sure that after so many iterations on TypeScript they haven't missed it, I hope.我敢肯定,在对 TypeScript 进行了如此多的迭代之后,他们并没有错过它,我希望。 :p :p

I guess that I can write some code that automatically name these modules properly because I'm using a build file anyway but I really don't want to add extra work that can probably be saved, again, I hope.我想我可以编写一些代码来自动正确命名这些模块,因为无论如何我都在使用构建文件,但我真的不想添加可能可以保存的额外工作,我再次希望。

It tooks me few days to figure it out, the paths were incorrect all over the place both in my Karma configuration files and the requirejs 'tests.main.js' file.我花了几天时间才弄明白,我的 Karma 配置文件和 requirejs 'tests.main.js' 文件中的路径到处都是不正确的。

I also changed the project structure so here is everything that I changed to make it work.我还更改了项目结构,因此这里是我更改的所有内容以使其正常工作。

The solution is now available at GitHub .该解决方案现已在GitHub 上提供

The directory structure of the project.项目的目录结构。

.
|-- node_modules
|   |-- jake
|   |   |-- bin
|   |   |-- lib
|   |   |-- node_modules
|   |   |-- test
|   |   |-- Jakefile
|   |   |-- Makefile
|   |   |-- README.md
|   |   `-- package.json
|   |-- jasmine-node
|   |   |-- bin
|   |   |-- lib
|   |   |-- node_modules
|   |   |-- scripts
|   |   |-- spec
|   |   |-- src
|   |   |-- Gruntfile.coffee
|   |   |-- LICENSE
|   |   |-- README.md
|   |   |-- bower.json
|   |   |-- index.js
|   |   `-- package.json
|   |-- karma
|   |   |-- bin
|   |   |-- lib
|   |   |-- node_modules
|   |   |-- static
|   |   |-- CHANGELOG.md
|   |   |-- LICENSE
|   |   |-- README.md
|   |   |-- config.tpl.coffee
|   |   |-- config.tpl.js
|   |   |-- config.tpl.ls
|   |   |-- karma-completion.sh
|   |   |-- package.json
|   |   |-- requirejs.config.tpl.coffee
|   |   `-- requirejs.config.tpl.js
|   |-- karma-jasmine
|   |   |-- lib
|   |   |-- LICENSE
|   |   |-- README.md
|   |   `-- package.json
|   |-- karma-requirejs
|   |   |-- lib
|   |   |-- LICENSE
|   |   |-- README.md
|   |   `-- package.json
|   |-- karma-requirejs-preprocessor
|   |   `-- index.js
|   |-- requirejs
|   |   |-- bin
|   |   |-- README.md
|   |   |-- package.json
|   |   `-- require.js
|   `-- shelljs
|       |-- bin
|       |-- scripts
|       |-- src
|       |-- LICENSE
|       |-- README.md
|       |-- global.js
|       |-- make.js
|       |-- package.json
|       `-- shell.js
|-- src
|   |-- css
|   |-- framework
|   |   |-- core
|   |   `-- widgets
|   |-- libs
|   |   |-- typings
|   |   |-- jquery-2.1.0.js
|   |   `-- require.js
|   |-- tests
|   |   |-- core
|   |   `-- test.main.js
|   |-- app.main.js
|   |-- app.main.js.map
|   |-- app.main.ts
|   |-- index.html
|   |-- tsToolkit.csproj
|   |-- tsToolkit.csproj.user
|   |-- web.Debug.config
|   |-- web.Release.config
|   `-- web.config
|-- tools
|   `-- karma
|       `-- karma.conf.js
|-- WebEssentials-Settings.json
|-- jake.sh
|-- jakefile.js
|-- karma.sh
|-- scratchpad.txt
|-- tsToolkit.sln
|-- tsToolkit.sln.DotSettings.user
`-- tsToolkit.v12.suo

40 directories, 57 files

The Karma configuration file. Karma 配置文件。

// Karma configuration
// Generated on Fri May 16 2014 08:27:07 GMT+0300 (Jerusalem Daylight Time)

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

        // base path that will be used to resolve all patterns (eg. files, exclude)
        basePath: '../../',


        // frameworks to use
        // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
        frameworks: ['jasmine', 'requirejs'],


        // list of files / patterns to load in the browser
        files: [
            {pattern: 'src/libs/*.js', included: false},
            {pattern: 'src/framework/**/*.js', included: false},
            {pattern: 'src/tests/**/*.tests.js', included: false},
            'src/tests/test.main.js'
        ],


        // list of files to exclude
        exclude: [
            'src/app.main.js'
        ],


        // preprocess matching files before serving them to the browser
        // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
        preprocessors: {

        },


        // test results reporter to use
        // possible values: 'dots', 'progress'
        // available reporters: https://npmjs.org/browse/keyword/karma-reporter
        reporters: ['progress'],


        // web server port
        port: 8380,


        // enable / disable colors in the output (reporters and logs)
        colors: true,


        // level of logging
        // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
        logLevel: config.LOG_INFO,


        // enable / disable watching file and executing tests whenever any file changes
        autoWatch: true,


        // start these browsers
        // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
        browsers: [],


        // Continuous Integration mode
        // if true, Karma captures browsers, runs the tests and exits
        singleRun: false
    });
};

Here is the requirejs file -- types.tests.js这是 requirejs 文件——types.tests.js

var tests = [];
for (var file in window.__karma__.files) {
    if (/\.tests\.js$/.test(file)) {
        tests.push(file);
    }
}

requirejs.config({
    baseUrl: '/base/src',

    deps: tests,

    callback: window.__karma__.start
});

An example of a class that I wanted to test which is written in TypeScript -- types.ts我想测试的一个用 TypeScript 编写的类的例子——types.ts

class Types {
    public static isNull(value: any) : boolean
    {
        return false;
    }

    public static isUndefined(value: any) : boolean
    {
        return false;
    }

    public static isString(value: any) : boolean
    {
        return false;
    }

    public static isElement(value: any) : boolean
    {
        return false;
    }

    public static isNumber(value: any) : boolean
    {
        return false;
    }
}

export = Types;

and finally, a test that I wrote for the function 'isUndefined' -- types.tests.ts最后,我为函数“isUndefined”编写的测试——types.tests.ts

import Types = require("framework/core/types");

describe("isUndefined", () => {

    it("should return true when the object is undefined", () => {
        // Arrange
        var obj;

        // Act
        var value = Types.isUndefined(obj);

        // Assert
        expect(value).toBe(true);
    });

});

I hope that it's clear enough and that it will help others that are struggling with the same problem.我希望它足够清楚,并且它会帮助其他正在努力解决相同问题的人。

PS even though I wrote a requirejs-preprocessor for Karma to name my modules, after these changes i didn't need it and it just worked. PS,即使我为 Karma 编写了一个 requirejs-preprocessor 来命名我的模块,但在这些更改之后我不需要它,它就可以工作了。

Would changing types.tests.ts to be wrapped in a module help?types.tests.ts更改为包含在模块中会有所帮助吗? Also, I'm assuming that you're using the -m AMD switch when compiling (or have AMD selected in VS)另外,我假设您在编译时使用了-m AMD开关(或者在 VS 中选择了 AMD)

import Types = require("./../../core/types");

module CoreTypes {
    describe("isUndefined", () => {
        it("should return true when the object is undefined", () => {
        });
    });
}

export = CoreTypes;

That doesn't name the external module (which as far as I know there is not a way to do in TypeScript 1.0), but it does at least properly wrap it as an external module.这并没有命名外部模块(据我所知,在 TypeScript 1.0 中没有办法做到这一点),但它至少正确地将其包装为外部模块。

For example, take a look at this open issue: https://typescript.codeplex.com/workitem/2394例如,看看这个未解决的问题: https : //typescript.codeplex.com/workitem/2394

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM