forked from pghalliday/grunt-mocha-test
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mocha-test.js
108 lines (100 loc) · 3.42 KB
/
mocha-test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
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) {
var value = grunt.option(param) || options[param];
if(value) {
options[param] = value;
}
});
// 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);
}
});
});
};