Как настроить karma и systemjs для запуска тестов углового ES6, транспилированных traceur в модули ES5 формата amd

Хорошо, я слишком долго бился головой о стол, пришло время попросить о помощи. Может быть, я ошибаюсь или просто не вижу деревьев в лесу. Пожалуйста помоги.

Я пытаюсь создать приложение, используя gulp, Angular 1.3+, ES6, traceur, SystemJS, es_module_loader и http-сервер.

Пока что приложение выглядит хорошо, оно отлично компилируется, запускается и размещается из скомпилированной папки, но я не могу заставить Karma запустить один тест в моем скомпилированном проекте.

Вот структура моего проекта:

gulpfile.js
client/
    - src
        - app/
            - bootstrap.js
            - system.config.js
            - index.html
            - modules/
                  - app.module.es6
                  - AppRouter.es6
                  - app.less
                  - common/
                       - common.module.es6
                       - masterTemplate/
                               - MasterTemplateController.es6
                               - MasterTemplateController.spec.es6
                               - masterTemplate.tpl
                               - masterTemplate.less
                  - home/
                      - home.module.es6
                      - home.less
                      - greeting/
                            - GreetingController.es6
                            - GreetingController.spec.es6
                            - greeting.less
                            - greeting.tpl
                    ...

используя gulp и traceur, я могу перенести весь код es6 в модули es5 с помощью оберток amd. Скомпилированные артефакты размещаются в папке сборки следующим образом:

_build/
   - css/
   - fonts/
   - img/
   - js/
      - lib/...
      - modules/
         - common/...
         - home/
             - greeting/
                  - GreetingController.js
             - home.module.js
         - app.module.js
         - AppRouter.js
         - mock.app.module.js
      - bootstrap.js
      - system.config.js
   - index.html

Скомпилированный макет не идентичен исходному макету, но очень близок:

  • Библиотеки поставщиков находятся в папке lib и поступают из 3 разных мест (npm, bower и пользовательская загрузка).
  • Папки fonts, css и img собираются из нескольких источников.
  • Папка _build/js почти идентична папке client/src/app folder, за исключением того, что файл index.html находится на один уровень выше.
  • Файлы HTML-шаблонов (*.tpl) {некоторые называют их частичными} все скомпилированы в модуль $templateCache, сохраненный в _build/js/modules/common/templates/templates.module.js.

затем я обслуживаю его с помощью http-сервера. index.html загружает инфраструктуру времени выполнения и, наконец, bootstrap.js, который использует SystemJs для начальной загрузки angular, начиная с /modules/.

<!doctype html>
<head>
    <title>App</title>

    <link rel="icon" type="image/png" href="/favicon.png">
    <link rel="stylesheet" href="/css/app.css">

    <script src="/js/lib/traceur-runtime.js"></script>
    <script src="/js/lib/system.js"></script>
    <script src="/js/system.config.js"></script>

</head>
<body>
    <div ui-view="main" class="root-view"></div>
    <script src="/js/bootstrap.js"></script>
</body>
</html>

Это прекрасно работает. Все загружается и отображается как надо.

Теперь я иду, чтобы проверить это... Поскольку я использую SystemJs для загрузки всех зависимостей (идентифицируемых с помощью import в каждом модуле и последующем файле src), мне нужно использовать karma-systemjs, чтобы помочь карме найти и загрузить те же самые файлы.
Вот мой karma.config.js, который хранится по адресу client/src/tests/karma/karma.config.js

module.exports = function (config) {
  config.set({
    basePath: '../../../../,
    urlRoot: '',
    hostname: 'localhost',
    frameworks: [ 'systemjs','mocha','chai','chai-as-promised','sinon-chai'],
    plugins: [
      'karma-mocha',
      'karma-chai',
      'karma-chai-plugins',
      'karma-systemjs',
      'karma-traceur-preprocessor',
      'karma-chrome-launcher',
      'karma-firefox-launcher',
      'karma-spec-reporter',
      'karma-junit-reporter',
      'karma-failed-reporter'
    ],
    systemjs: {
      configFile: '_build/js/system.config.js',
      files: [
        '_build/js/lib/*.js',
        '_build/js/modules/**/*.js',
        'client/src/app/**/*Spec.es6'
      ],
      config: {
        transpiler: 'traceur',
        paths: {
          'angular':           '_build/js/lib/angular.min.js',
          'angular-animate':   '_build/js/lib/angular-animate.min.js',
          'angular-messages':  '_build/js/lib/angular-messages.min.js',
          'angular-aria':      '_build/js/lib/angular-aria.min.js',
          'angular-resource':  '_build/js/lib/angular-resource.min.js',
          'angular-cookies':   '_build/js/lib/angular-cookies.min.js',
          'angular-storage':   '_build/js/lib/angular-storage.min.js',
          'angular-material':  '_build/js/lib/angular-material.min.js',
          'angular-mocks':     '_build/js/lib/angular-mocks.js',
          'angular-ui-router': '_build/js/lib/angular-ui-router.min.js',
          'statehelper':       '_build/js/lib/statehelper.min.js',
        }
      },
      testFileSuffix: '.spec.js'
    },
    preprocessors: {
      'client/src/app/**/*.spec.es6': ['traceur']  // pre-compile tests
    },
    traceurPreprocessor: {
      options: {
        modules: 'amd',
      },
    },
    client: {
      mocha: {
        reporter: 'html',
        ui: 'bdd'
      }
    },
    reporters: ['junit', 'spec', 'failed'],
    reportSlowerThan: 1000,
    junitReporter: {
      outputFile: 'reports/unit-test-results.xml',
      suite: ''
    },
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: false,
    browsers: [
       'Chrome'
    ],
    captureTimeout: 10000,
    port: 9876,
    runnerPort: 9100,
    singleRun: true,
    background: false
  });
};

после сборки приложения и запуска gulp karma я получаю невероятно полезное сообщение об ошибке:

ERROR [karma]: Uncaught TypeError: Illegal module name "/base/client/src/app/modules/home/greeting/GreetingController.spec"
at http://localhost:9876/base/node_modules/es6-module-loader/dist/es6-module-loader.src.js?3aac9167d6f21486de90ab673ff41c414843e2b4:2667

Chrome 41.0.2272 (Mac OS X 10.10.2): Executed 0 of 0 ERROR (0.399 secs / 0 secs)


[02:17:59] 'karma' errored after 1.81 s
[02:17:59] Error: 1
    at formatError (/Users/kpburson/.nvm/versions/node/v0.12.0/lib/node_modules/gulp/bin/gulp.js:169:10)
    at Gulp.<anonymous> (/Users/kpburson/.nvm/versions/node/v0.12.0/lib/node_modules/gulp/bin/gulp.js:195:15)
    at Gulp.emit (events.js:107:17)
    at Gulp.Orchestrator._emitTaskDone (/Users/kpburson/projects/ver-client/node_modules/orchestrator/index.js:264:8)
    at /Users/kpburson/projects/ver-client/node_modules/orchestrator/index.js:275:23
    at finish (/Users/kpburson/projects/ver-client/node_modules/orchestrator/lib/runTask.js:21:8)
    at cb (/Users/kpburson/projects/ver-client/node_modules/orchestrator/lib/runTask.js:29:3)
    at removeAllListeners (/Users/kpburson/projects/ver-client/node_modules/karma/lib/server.js:220:7)
    at Server.<anonymous> (/Users/kpburson/projects/ver-client/node_modules/karma/lib/server.js:231:9)
    at Server.g (events.js:199:16)

Файл system.config.js:

System.config({
  baseURL: '/js/', 
  paths: {
    'angular':          '/js/lib/angular.js',
    'angular-animate':  '/js/lib/angular-animate.js',
    'angular-aria':     '/js/lib/angular-aria.js',
    'angular-cookies':  '/js/lib/angular-cookies.js',
    'angular-material': '/js/lib/angular-material.js',
    'angular-messages': '/js/lib/angular-messages.js',
    'angular-mocks':    '/js/lib/angular-mocks.js',
    'angular-resource': '/js/lib/angular-resource.js',
    'angular-storage':  '/js/lib/angular-storage.js',
    'angular-ui-router':'/js/lib/angular-ui-router.js',
    'statehelper':      '/js/lib/statehelper.js'
  },
  meta: {
    'angular': {format: 'global', exports: 'angular'},
    'angular-ui-router': {format: 'global', deps: ['angular']},
    'statehelper': {format: 'global', deps: ['angular', 'angular-ui-router']}
  }
});

и файл bootstrap.js:

System.import('app.module').then(
  function (a) {
    angular.element(document).ready(
      function () {
        angular.bootstrap(document, ['app']);
      }
    );
  },
  function (a, b, c) {
    console.out('\na:', a, '\nb:', b, '\nc:', c);
  }
);

Я в своем уме. Пожалуйста, помогите мне понять, как заставить тесты из папки client/src компилироваться в памяти и выполняться против предварительно скомпилированного кода в _build/js.


person Kendrick Burson    schedule 13.03.2015    source источник
comment
Я просто хочу повторить эту проблему, потому что я вижу точно такую ​​​​же проблему с очень похожей настройкой (вместо этого я использую babel, jasmine и phantomjs)   -  person JasonWilczak    schedule 26.10.2015


Ответы (1)


К сожалению, это не позволит мне комментировать, и я понимаю, что это не точный ответ, который вы ищете, но он может вам помочь, так что вот.

Рассматривали ли вы использование JSPM для упрощения этого, он может обрабатывать все ваши библиотеки и зависимости, и в сочетании с karma-jspm вам не нужно будет объявлять все эти пути. Некоторые полезные ссылки:

person David Plunkett    schedule 05.06.2015
comment
да, спасибо, я изучаю jspm уже много месяцев. Мои 2 самые большие проблемы с jspm заключаются в том, что он не обрабатывает транспиляцию *.less, хотя он обрабатывает транспиляцию es6, и у него нет надежного производственного рабочего процесса... - person Kendrick Burson; 28.10.2015
comment
Что я могу сказать о производственном рабочем процессе, так это то, что во время разработки вы захотите загрузить свои неминифицированные файлы в отдельный лист браузера оттуда, где они находятся, но для производства, по крайней мере, для angular, вы захотите предварительно обработать файлы js с помощью ngannotate. . уменьшите файлы до объединения, также вы можете использовать предварительно упакованные библиотеки поставщиков, если они доступны, или изменить конфигурацию, чтобы использовать версии CDN. Кроме того, вы можете захотеть не использовать отдельные пакеты для основного приложения и библиотек поставщиков, но это невозможно с sfx. - person Kendrick Burson; 28.10.2015