4

When I run Karma Tests in Angular2 i get the following error.

Uncaught TypeError: Unexpected anonymous System.register call. at http://localhost:9876/base/node_modules/systemjs/dist/system.src.js?38538ebca96bc7b222f7e7ba15943f173a485f6e:2885

I suppose its because the var System is currently not available. Even if its actually loaded. Does anyone have an idea why this is not working?

Here is my stripped down configuration:

C:\project\karma.conf.js

module.exports = function(config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine'],
    files: [
      'node_modules/systemjs/dist/system.src.js',
      'node_modules/angular2/bundles/angular2.dev.js',
      'tests/**/*Spec.js'
    ],
    exclude: [
    ],
    preprocessors: {
    },
    reporters: ['progress'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: false,
    browsers: ['Chrome', 'Firefox'],
    singleRun: false,
    concurrency: Infinity
  })
}

C:\project\tests\MyTestSpec.ts This one line is enough to trigger the error.

import {describe, expect, it, xit, inject, beforeEachProviders} from 'angular2/testing';

that renders to C:\project\tests\MyTestSpec.js and produces an error on the first occurance of System

System.register([], function(exports_1) {
    return {
        setters:[],
        execute: function() {
        }
    }
});
//# sourceMappingURL=CmiCloudSpec.js.map

C:\project\tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "system",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false,
    "watch": true,
  },
  "exclude": [
    "node_modules",
    "typings/main",
    "typings/main.d.ts"
  ]
}

C:\project\src\node_modules

contains the folders angular2 and systemjs as well as karma, karma-jasmine, jasmine-core and typescript

3 Answers 3

1

The problem is that you should include all your test files into Karma directly within the files attribute of karma.conf.js. Because you don't define an outFile property in your tsc configuration (and that's fine here), the name of modules aren't specified into the compiled JS files.

You need rather to create a karma-test-shim.js file (that will be included) and configure SystemJS to load module by file names and import these file using System.import.

Here is a sample of karma-test-shim.js file:

Error.stackTraceLimit = Infinity;
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;

__karma__.loaded = function() {};

System.config({
  packages: {
    'base/dist': {
        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) {
  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\/dist\/(?!.*\.spec\.js$).*\.js$/.test(filePath);
}

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

function resolveTestFiles() {
  return Object.keys(window.__karma__.files)
    .filter(onlySpecFiles)
    .map(function(moduleName) {
        return System.import(moduleName);
    });
}

and the corresponding configuration in karma.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/http.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: 'dist/**/*.js', included: false, watched: true},

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

It think that this article and its source code could help you:

Sign up to request clarification or add additional context in comments.

1 Comment

Did OP find this answer helpful? Should be accepted.
0

Thank you very much. The explanation that the bundled files in 'tests/**/*Spec.js' could not be loaded made perfect sense.

And it is working now.

To keep the explanation simple I added the karma-test-shim.js to the files section and that was it.

I will change the files section style later.

module.exports = function(config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine'],
    files: [
      'node_modules/systemjs/dist/system.src.js',
      'node_modules/angular2/bundles/angular2.dev.js',
      'karma-test-shim.js',
      'tests/**/*Spec.js'
    ],
    exclude: [
    ],
    preprocessors: {
    },
    reporters: ['progress'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: false,
    browsers: ['Chrome', 'Firefox'],
    singleRun: false,
    concurrency: Infinity
  })
}

Comments

0

Another thing was necessary in the karma.conf.js file

basePath: '.',

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

Needed because otherwise the tests will not be executed

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.