'use strict'; var grunt = require('grunt'); var vm = require('vm'); var browserify = require('browserify'); var jsdom = require('jsdom').jsdom; function readFile(path) { return grunt.file.read(path); } function compareOutputs(fn1, fn2) { return (grunt.util.normalizelf(fn1.toString()) === grunt.util.normalizelf(fn2.toString())); } function moduleExported(context, modulePath) { var module = modulePath.match(/(\w+)\.js/)[1]; return compareOutputs(context.exports[module], require(modulePath)); } function moduleNotExported(context, modulePath) { return !moduleExported(context, modulePath); } function getIncludedModules(file, context) { var c = context || {}; var actual = readFile(file); c.required = function (exports) { c.exports = exports; }; vm.runInNewContext(actual, c); return c; } function domWindow() { var html = '' + '' + '' + 'Test' + '' + '' + '' + ''; var window = jsdom(html).createWindow(); var context = vm.createContext(window); Object.keys(window).forEach(function (k) { context[k] = window[k]; }); return context; } module.exports = { basic: function (test) { test.expect(2); var context = getIncludedModules('tmp/basic.js'); test.ok(moduleExported(context, './fixtures/basic/a.js')); test.ok(moduleExported(context, './fixtures/basic/b.js')); test.done(); }, ignores: function (test) { test.expect(3); var context = getIncludedModules('tmp/ignores.js'); test.ok(moduleExported(context, './fixtures/ignore/a.js')); test.ok(moduleExported(context, './fixtures/ignore/b.js')); test.ok(moduleNotExported(context, './fixtures/ignore/ignore.js')); test.done(); }, alias: function (test) { test.expect(1); var context = getIncludedModules('tmp/alias.js'); var aliasedFile = require('./fixtures/alias/toBeAliased.js'); test.ok(compareOutputs(context.exports.alias, aliasedFile)); test.done(); }, aliasString: function (test) { test.expect(1); var context = getIncludedModules('tmp/aliasString.js'); var aliasedFile = require('./fixtures/alias/toBeAliased.js'); test.ok(compareOutputs(context.exports.alias, aliasedFile)); test.done(); }, aliasMappings: function (test) { test.expect(4); var context = getIncludedModules('tmp/aliasMappings.js'); var rootFile = require('./fixtures/aliasMappings/root.js'); var fooFile = require('./fixtures/aliasMappings/foo/foo.js'); var fooBarFile = require('./fixtures/aliasMappings/foo/bar/foobar.js'); test.ok(compareOutputs(context.exports.root, rootFile)); test.ok(compareOutputs(context.exports.foo, fooFile)); test.ok(compareOutputs(context.exports.foobar, fooBarFile)); test.ok(compareOutputs(context.exports.otherbar, fooBarFile)); test.done(); }, external: function (test) { test.expect(4); var actual = readFile('tmp/external.js'); var core = browserify(); core.require(__dirname + '/fixtures/external/a.js'); core.require('events'); core.bundle(function (err, src) { var c = { required: function (exports) { c.exports = exports; } }; vm.runInNewContext(src, c); vm.runInNewContext(actual, c); test.ok(moduleExported(c, './fixtures/external/a.js')); test.ok(moduleExported(c, './fixtures/external/b.js')); //make sure a.js contents aren't in the bundle test.ok(!actual.match('this should be a common require')); //make sure events module isn't included test.ok(!actual.match('EventEmitter')); test.done(); }); }, externalDir: function (test) { test.expect(2); var actual = readFile('tmp/external-dir.js'); var core = browserify(); core.require(__dirname + '/fixtures/external-dir/b'); core.bundle(function (err, src) { var c = { required: function (exports) { c.exports = exports; } }; vm.runInNewContext(src, c); vm.runInNewContext(actual, c); test.ok(moduleExported(c, './fixtures/external-dir/a.js')); //make sure b directory contents aren't in the bundle test.ok(!actual.match('this should be a common module require')); test.done(); }); }, externalize: function (test) { test.expect(4); var actual = readFile('tmp/externalize.js'); var c = {}; vm.runInNewContext(actual, c); var depen = browserify(); depen.external(__dirname + '/fixtures/externalize/a.js'); depen.add(__dirname + '/fixtures/externalize/entry.js'); depen.bundle(function (err, src) { c.required = function (exports) { c.exports = exports; }; vm.runInNewContext(src, c); test.ok(moduleExported(c, './fixtures/externalize/a.js')); test.ok(moduleExported(c, './fixtures/externalize/b.js')); //require should be exposed test.ok(c.require); //common module required test.ok(c.require('events')); test.done(); }); }, noParse: function (test) { test.expect(2); var context = getIncludedModules('tmp/noParse.js', domWindow()); test.ok(moduleExported(context, './fixtures/noParse/a.js')); //jquery is defined on the window test.ok(context.window.$); test.done(); }, shim: function (test) { test.expect(2); var context = getIncludedModules('tmp/shim.js', domWindow()); test.ok(moduleExported(context, './fixtures/shim/a.js')); //jquery is defined on the window test.ok(context.window.$); test.done(); }, sourceMaps: function (test) { test.expect(1); var actual = readFile('tmp/sourceMaps.js'); test.ok(actual.match(/\/\/@ sourceMappingURL=/)); test.done(); } };