Reputation: 9650
I'm trying to figure out the best approach to testing a Javascript module definition using a UMD factory, similar to this: https://github.com/umdjs/umd/blob/master/returnExportsGlobal.js
I don't want to test the module itself, I want to test that the module is 'exported/created' correctly in the various environments:
I would like to run these tests using grunt and jasmine. I can use grunt-contrib-jasmine to test for points 2 and 3, but not for point 1.
I guess I can use a concoction of grunt-contrib-jasmine and grunt-jasmine-node to test for correct module definitions (specific implementation i'd still need to figure out), but it feels very messy.
At a high level, does anyone know of any existing methods to achieving this without using multiple grunt plugins?
Upvotes: 6
Views: 4419
Reputation: 1055
You can also use uRequire and save your self from all the UMD boilerplate in all your modules, while using declarative features.
You simply write plain AMD or plain CommonJS modules (or a mix of two) and convert to UMD (or an rjs optimized combined.js
that runs as-is on nodejs, Web/AMD & Web/Script) with a simple build step and config, either in CLI or in grunt.
The UMD produced is based on well known templates like https://github.com/umdjs/umd/blob/master/templates/returnExportsGlobal.js, with various tweaks, one of them being that you can declaratively export to window
/global
.
You can then convert you plain AMD or commonJS specs to UMD and/or 'combined.js' and hit both in a browser or grunt-mocha. See uBerscore for many trivial and more advanced examples.
Upvotes: 0
Reputation: 9650
In the end, i decided to go with the hybrid tasks, using grunt-contrib-jasmine for browser global and browser AMD tests, and jasmine_node for CommonJS testing. I only have one spec file which supports all 3 module type tests.
Here's my grunt config:
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
jasmine: {
browserGlobal: {
src: ['src/Foo.js'],
options: {
specs: 'spec/**/*.spec.js'
}
},
browserAMD: {
src: ['src/Foo.js'],
options: {
specs: 'spec/**/*.spec.js',
template: require('grunt-template-jasmine-requirejs')
}
}
},
jasmine_node: {
specNameMatcher: 'spec',
projectRoot: 'spec/'
}
});
My jasmine spec files now support UMD:
(function (root, factory) {
if (typeof module === 'object' && module.exports) {
// Node/CommonJS
factory(
require('modulename')
);
} else if (typeof define === 'function' && define.amd) {
// AMD
define([
'modulename'
], factory);
} else {
// Browser globals
factory(root.ModuleName);
}
}(this, function factory(ModuleName) {
// Tests here
}));
And here's the UMD factory i'm using for my module:
(function (root, factory) {
if (typeof module === 'object' && module.exports) {
// Node/CommonJS
module.exports = factory();
} else if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(factory);
} else {
// Browser globals
root.ModuleName = factory();
}
}(this, function factory() {
// public API
return {
foo: 'bar'
};
}));
Upvotes: 4