5

I'm a bit stuck on this. I have a complex stack composed of middleman, karma, jasmine, babeljs to build a static website.

Considering this is an experiment, I wanted to use ES6 with modules. Everything fine on middleman side, though, I'm having hard times setting up karma + jasmine for testing.

The main problem lies within babel: if you set it to use modules: "ignore" you have to manually use System.import for all your modules in your specs, which is something I don't want. I would like to use the ES6 syntax, but if I set modules: "system", babeljs wraps all my tests into System.register, with something like the following:

System.register(["mymodule"], function (_export) {
  "use strict";

  var Mymodule;
  return {
    setters: [function (_mymodule) {
      Mymodule = _mymodule["default"];
    }],
    execute: function () {

      console.log("I'm here!!!");
      console.log(Mymodule);

      describe("Mymodule", function () {

        it("has version", function () {
          expect(Mymodule.VERSION).toEqual("1.0.0");
        });


      });
    }
  };
});

So the tests are not automatically executed. I then created the following script to work around it (which is included after all specs are included):

basePath = "/base/spec/"

modules = []

for own fileName, fileHash of window.__karma__.files
  if fileName.indexOf(basePath) is 0
    isRunner   = fileName.indexOf("spec_runner") >= 0
    isRunner ||= fileName.indexOf("spec_helper") >= 0
    unless isRunner
      moduleName = fileName.replace(basePath, "")
      moduleName = moduleName.replace(".js", "")
      modules.push(path: fileName, name: moduleName)

mappedModules = {}
baseSpecsPath = "http://localhost:9876"

for module in modules
  mappedModules[module.name] = baseSpecsPath + module.path

System.config
  baseURL: "http://localhost:4567/javascripts/"
  map:     mappedModules

for module in modules
  System.import(module.name)

This code is simple: it prepares the map configuration for SystemJS, I can correctly load modules from my app (located in http://localhost:4567) and tests wrapped in System.register (located in http://localhost:9876).

However, my tests are not run, and no error reported. Even worse, I correctly get the message logged "I'm here!!!" and Mymodule is logged in console correctly. I even tried to log the value of describe and it's correctly a Suite object. So, why on earth my tests are not run? (The it block is never run)

What solutions do I have? I'm ok with changing the setup a bit to get it working, but I want to keep the following things: Middleman, ES6 modules, no dynamic module loading (all my modules are exposed, in the end, in a single file or required with a bunch of <script> tags), jasmine

Francesco Belladonna
  • 11,361
  • 12
  • 77
  • 147
  • I'm digging into jasmine to understand (possibly) why it's not running the `describe` block. I even tried to add it to window object, but didn't change anything – Francesco Belladonna Aug 18 '15 at 17:24
  • In case anyone is interested, I opened a question even on Jasmine google group: https://groups.google.com/forum/#!topic/jasmine-js/M4qRl6jcyE8 – Francesco Belladonna Aug 19 '15 at 10:40

1 Answers1

2

I finally solved the issue. I include this file as last one:

basePath = "/base/spec/"

modules = []

for own fileName, fileHash of window.__karma__.files
  if fileName.indexOf(basePath) is 0
    isRunner   = fileName.indexOf("spec_runner") >= 0
    isRunner ||= fileName.indexOf("spec_helper") >= 0
    unless isRunner
      moduleName = fileName.replace(basePath, "")
      moduleName = moduleName.replace(".js", "")
      modules.push(path: fileName, name: moduleName)

mappedModules = {}
baseSpecsPath = "http://localhost:9876"
specModules   = []

for module in modules
  mappedModules[module.name] = baseSpecsPath + module.path
  specModules.push(module.name)

System.config
  baseURL: "http://localhost:4567/javascripts/"
  map:     mappedModules

moduleImports = specModules.map (moduleName) ->
  System.import(moduleName)

Promise.all(moduleImports).then ->
  window.__karma__.start     = window.__lastKarmaStart__
  window.__lastKarmaStart__  = null
  delete window.__lastKarmaStart__
  window.__karma__.start()

It does the following things:

  • Temporary disable karma start function replacing it with an empty one
  • Fetches each test stored in a System.register, run System.import for all tests (waits them with Promise.all)
  • After all imports are completed, it attaches back __karma__start and executes it, running Jasmine
Francesco Belladonna
  • 11,361
  • 12
  • 77
  • 147