Ok, I have been pounding my head against the desk for far too long, it is time to ask for help. Maybe I am way off base, or I just cannot see the trees in the forest. Please help.
I am trying to build an application using gulp, Angular 1.3+, ES6, traceur, SystemJS, es_module_loader and http-server.
So far the app is looking good, it compiles and runs and hosts just fine from the compiled folder location, but I cannot get Karma to run a single test within my compiled project.
Here is my project structure:
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
...
using gulp and traceur I am able to transpile all the es6 code to es5 modules with amd wrappers. The compiled artifacts are laid out in a build folder as such:
_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
The compiled layout is not identical to the source layout, but it is very close:
- The vendor libs are in the
libfolder and come from 3 different places (npm, bower and a custom download). - The
fonts,cssandimgfolders are collected from several sources. - The
_build/jsfolder is nearly identical to theclient/src/app folder, except theindex.htmlfile is one level up. - The html template files (
*.tpl) {some call these partials} are all compiled into a $templateCache module saved under_build/js/modules/common/templates/templates.module.js
then I serve it up using http-server. The index.html loads up the runtime infrastructure
and finally the bootstrap.js, which uses SystemJs to bootstrap angular starting with the /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>
This works great. Everything loads and present as it should.
Now I go to test it... Because I am using SystemJs to load all dependencies (identified using import in each module and subsequent src file) I need to use karma-systemjs to help karma find and load those same files.
Here is my karma.config.js, which is stored at 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
});
};
after I build the app and run gulp karma I get this incredibly useful error message:
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)
The system.config.js file is:
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']}
}
});
and the bootstrap.js file is:
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);
}
);
I am at my wits end. Please help me figure out how to get the tests from the client/src folder
to compile in memory and execute against the pre-compiled code in _build/js.