| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 | var MochaWrapper = require('./lib/MochaWrapper');var fs = require('fs');var path = require('path');var hooker = require('hooker');var mkdirpSync = require('mkdirp').sync;module.exports = function(grunt) {  // Helper to capture task output (adapted from tests for grunt-contrib-jshint)  var capture = function(captureFile, quiet, run, done) {    var fd;    if (captureFile) {      mkdirpSync(path.dirname(captureFile));      fd = fs.openSync(captureFile, 'w');    }    // Hook process.stdout.write    hooker.hook(process.stdout, 'write', {      // This gets executed before the original process.stdout.write      pre: function(result) {        // Write result to file if it was opened        if (fd) {          fs.writeSync(fd, result);        }        // Prevent the original process.stdout.write from executing if quiet was specified        if (quiet) {          return hooker.preempt();        }      }    });    // Execute the code whose output is to be captured    run(function(error, failureCount) {      // close the file if it was opened      if (fd) {        fs.closeSync(fd);      }      // Restore process.stdout.write to its original value      hooker.unhook(process.stdout, 'write');      // Actually test the actually-logged stdout string to the expected value      done(error, failureCount);    });  };  grunt.registerMultiTask('mochaTest', 'Run node unit tests with Mocha', function() {    var done = this.async();    var options = this.options();    var files = this.files;    // mocha CLI parameters    var params = ['grep', 'ui', 'reporter', 'timeout', 'invert', 'ignoreLeaks', 'growl', 'globals', 'require', 'colors', 'slow'];    // for every supplied CLI parameter overwrite task option    params.forEach(function(param) {      options[param] = grunt.option(param) || options[param];    });    // check if there are files to test    if (this.filesSrc.length === 0) {      grunt.log.write('No files to check...');      grunt.log.ok();      done(true);      return;    }    // Another hack copied from    // https://github.com/gregrperkins/grunt-mocha-hack    // This time we are preventing grunt handling asynchronous    // exceptions that are thrown when handling asynchronous exceptions    // (I think)    var uncaughtExceptionHandlers = process.listeners('uncaughtException');    process.removeAllListeners('uncaughtException');    var unmanageExceptions = function() {      uncaughtExceptionHandlers.forEach(        process.on.bind(process, 'uncaughtException'));    };    var restore = function() {      unmanageExceptions();    };    capture(options.captureFile, options.quiet, function(complete) {      var mochaWrapper = new MochaWrapper({        files: files,        options: options      });      mochaWrapper.run(function(error, failureCount) {        if (error) {          grunt.log.error('Mocha exploded!');          grunt.log.error(error.stack);          complete(error);        } else {          complete(null, failureCount);        }      });    }, function(error, failureCount) {      // restore the uncaught exception handlers      restore();      if (error) {        done(false);      } else if (options.noFail) {        done(true);      } else {        done(failureCount === 0);      }    });  });};
 |