0

We have been using RequireJS, Bower and npm for quite some time. Now we are very impressed with jspm and SystemJS.

We like that they:

  • work with AMD minimizing the pain of converting our existing code
  • allow us to write ES2015 modules utilizing new features
  • have a similar config file as RequireJS which they maintain.
  • allow us to pull libs from Node and GitHub which don't have to be registered with bower

The only thing that we can find that is prohibiting us from making the switch, is that we need a means of telling SystemJS to give us new instances of required modules being loaded into a module containing a Jasmine test suite.

With RequireJS we do that by adding a createRequireContext to the window like so

(function (window) {
    var contextId = 0;

    window.createRequireContext = function () {
        var config = $.extend(true, window.globalRequireConfig, {
            baseUrl: '/base/src',
            context: 'new-context' + contextId++,
            paths: {
                'testData': '../test/data',
                'testFiles': '../test/testFiles'
            }
        }), 
        context = requirejs.config(config);

        return context.apply(this, arguments);
    };
})(window);

And then we call createRequireContext within a Jasmine test suite:

define(function () {
    var simpleObject;

    describe('new context for each test', function () {
        beforeEach(function (done) {
            createRequireContext(['testFiles/SimpleObjectModule'], function (newSimpleObject) {
                simpleObject = newSimpleObject;
                done();
            });
        });

        describe("createRequireContext", function () {
            it("retrieves a module with a new context and change a variable", function () {
                expect(simpleObject.foo).toBe('bar');
                simpleObject.foo = 'Old Data';
                expect(simpleObject.foo).toBe('Old Data');
            });
            it("retrieves a module with a new context and has original value", function () {
                expect(simpleObject.foo).toBe('bar');
            });
        });
    });

    describe('new context for each test suite', function () {
        beforeAll(function (done) {
            createRequireContext(['testFiles/SimpleObjectModule'], function (newSimpleObject) {
                simpleObject = newSimpleObject;
                done();
            });
        });

        describe("createRequireContext", function () {
            it("retrieves a module with a new context and change a variable", function () {
                expect(simpleObject.foo).toBe('bar');
                simpleObject.foo = 'New Data';
                expect(simpleObject.foo).toBe('New Data');
            });
            it("retrieves a module with a new context and has changed value", function () {
                expect(simpleObject.foo).toBe('New Data');
            });
        });
    });
});

Creating a new context in beforeEach isolates the required modules for every test. Creating a new context in beforeAll isolates the required modules from use in other test suites.

Is there a way that we can do this with SystemJS and jspm?

cResults
  • 733
  • 1
  • 5
  • 17

1 Answers1

0

The only way I know is to write your test in ES6 as well and then you just import modules in your test file:

import {SimpleObject} from '../../../src/SimpleObject';

let simpleObject;

describe('new context for each test',() => {
    beforeEach(() => {
          simpleObject = new SimpleObject();
    });

    describe("createRequireContext", () => {
        it("retrieves a module with a new context and change a variable", () => {
            expect(simpleObject.foo).toBe('bar');
            simpleObject.foo = 'Old Data';
            expect(simpleObject.foo).toBe('Old Data');
        });
        it("retrieves a module with a new context and has original value", function () {
            expect(simpleObject.foo).toBe('bar');
        });
    });
});

Here you can see working project It is written in TypeScript but with ES6 it works very similar. You can drop TS support (types, decorators and few more bonuses) change transpiler to babel and file extensions to *.js ;)

b091
  • 519
  • 2
  • 7
  • While I'm a huge fan of ES6 modules with the import and export key words, I'm not much of a fan of ES6 classes. I prefer object composition via the revealing module pattern. As a result, I'm looking for a solution that doesn't require me to new objects up all over the place. – cResults Jan 27 '16 at 14:56