In the end, I decided to go with hybrid tasks using grunt-contrib-jasmine for AMD's global browsers and jasmine_node for testing CommonJS. I have only one file specification that supports all 3 module type tests.
Here is my grunt configuration:
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 specification 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 I use the UMD factory 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' }; }));
source share