UNPKG

grunt-closure-coffee-stack

Version:

Everything you need for Google Closure. Precise configuration, Soy templates, localization, TDD stack, and even CoffeeScript support. File watcher included.

112 lines (94 loc) 3.21 kB
/* * grunt-este * https://github.com/este/grunt-este * Copyright (c) 2013 Daniel Steigerwald */ module.exports = function (grunt) { var jsdom = require('jsdom').jsdom; var Mocha = require('mocha'); var path = require('path'); var previousGlobalKeys = []; var requireUncache = require('require-uncache'); var React; // Useful global shortcuts available in every test. global.assert = require('chai').assert; global.sinon = require('sinon'); grunt.registerMultiTask('tests', 'Super-fast unit testing for Google Closure with Mocha in Node.js', function() { var options = this.options({ bootstrapPath: 'bower_components/closure-library/closure/goog/bootstrap/nodejs.js', depsPath: 'client/deps.js', // TODO: Try to compute it. prefix: '../../../../', mocha: { ui: 'tdd', reporter: 'dot', globals: [], timeout: 100 } }); var bootstrapPath = path.resolve(options.bootstrapPath); var depsPath = path.resolve(options.depsPath); // Delete global keys created for one test run. // Uncache does not help. previousGlobalKeys.forEach(function(key) { delete global[key]; }); // Need to be uncached. requireUncache(bootstrapPath); requireUncache(depsPath); var globalKeys = Object.keys(global); require(bootstrapPath); require(depsPath); // Mock browser. var doc = jsdom(); global.window = doc.parentWindow; global.document = doc.parentWindow.document; global.React = global.window.React = React; var testFiles = this.filesSrc; // Watch mode, map tests to tested files. testFiles = testFiles.map(function(file) { if (file.indexOf('_test.') == -1) file = file.replace('.', '_test.'); return file; }); // Watch mode, do nothing for missing test. if (testFiles.length == 1 && !grunt.file.exists(testFiles[0])) { return; } // Require tests deps. testFiles.forEach(function(testFile) { var file = testFile.replace('_test.js', '.js'); var namespaces = goog.dependencies_.pathToNames[options.prefix + file]; for (var namespace in namespaces) { // TODO: For gulp back to manual resolve because uncache // does not work reliable. goog.require(namespace); } }); previousGlobalKeys = Object.keys(global).filter(function(key) { return globalKeys.indexOf(key) == -1; }); var mocha = new Mocha(options.mocha); // Workaround for mocha "0 tests complete" issue. // github.com/visionmedia/mocha/issues/445#issuecomment-17693393 mocha.suite.on('pre-require', function(context, file) { requireUncache(file); }); testFiles.forEach(function(testFile) { mocha.addFile(path.resolve(testFile)); }); // Enforce stack on Mocha crash. var done = this.async(); try { mocha.run(function(errCount) { done(!errCount); }); } catch (e) { grunt.log.error(e.stack); done(false); } } ); };