Skip to content

Commit 129c86e

Browse files
committed
Rewriting unit tests to be MUCH more sane.
* If you have to build tests dynamically, it's MUCH nicer to build actual TESTS dynamically, not just have a single test with a billion assertions in crazy async loops. * Seriously.
1 parent 1befccd commit 129c86e

File tree

2 files changed

+64
-53
lines changed

2 files changed

+64
-53
lines changed

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
"grunt-contrib-nodeunit": "~0.2.0",
3333
"grunt-contrib-watch": "~0.5.3",
3434
"grunt": "~0.4.1",
35-
"async": "~0.2.9",
3635
"which": "~1.0.5"
3736
},
3837
"keywords": [

test/exit_test.js

Lines changed: 64 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
var fs = require('fs');
2424
var exec = require('child_process').exec;
25-
var async = require('async');
2625

2726
var _which = require('which').sync;
2827
function which(command) {
@@ -38,28 +37,6 @@ function which(command) {
3837
// which is Windows' horribly crippled grep alternative.
3938
var grep = which('grep') || process.platform === 'win32' && which('find');
4039

41-
function normalizeLineEndings(s) {
42-
return s.replace(/\r?\n/g, '\n');
43-
}
44-
45-
function run(command, options, callback) {
46-
if (typeof options === 'function') {
47-
callback = options;
48-
options = {};
49-
}
50-
command += ' 2>&1';
51-
if (options.pipe) {
52-
command += ' | ' + grep + ' "std"';
53-
}
54-
exec(command, function(error, stdout) {
55-
callback(command, error ? error.code : 0, normalizeLineEndings(stdout));
56-
});
57-
}
58-
59-
function fixture(filename) {
60-
return normalizeLineEndings(String(fs.readFileSync(filename)));
61-
}
62-
6340
exports['exit'] = {
6441
setUp: function(done) {
6542
this.origCwd = process.cwd();
@@ -76,34 +53,69 @@ exports['exit'] = {
7653
test.ok(grep, 'A suitable "grep" or "find" program was not found in the PATH.');
7754
test.done();
7855
},
79-
'stdout stderr': function(test) {
80-
var counts = [10, 100, 1000];
81-
var outputs = ['stdout stderr', 'stdout', 'stderr'];
82-
test.expect(counts.length * outputs.length * 2);
83-
async.eachSeries(counts, function(n, next) {
84-
async.eachSeries(outputs, function(o, next) {
85-
run('node log.js 0 ' + n + ' ' + o, {pipe: true}, function(command, code, actual) {
86-
var expected = fixture(n + '-' + o.replace(' ', '-') + '.txt');
87-
// Sometimes, the actual file lines are out of order on Windows.
88-
// But since the point of this lib is to drain the buffer and not
89-
// guarantee output order, we only test the length.
90-
test.equal(actual.length, expected.length, '(length) ' + command);
91-
// The "fail" lines in log.js should NOT be output!
92-
test.ok(actual.indexOf('fail') === -1, '(no more output after exit) ' + command);
93-
next();
94-
});
95-
}, next);
96-
}, test.done);
97-
},
98-
'exit codes': function(test) {
99-
var codes = [0, 1, 123];
100-
test.expect(codes.length);
101-
async.eachSeries(codes, function(n, next) {
102-
run('node log.js ' + n + ' 10 stdout stderr', {pipe: false}, function(command, code) {
56+
// The rest of the tests are built dynamically, to keep things sane.
57+
};
58+
59+
// A few helper functions.
60+
function normalizeLineEndings(s) {
61+
return s.replace(/\r?\n/g, '\n');
62+
}
63+
64+
// Capture command output, normalizing captured stdout to unix file endings.
65+
function run(command, callback) {
66+
exec(command, function(error, stdout) {
67+
callback(error ? error.code : 0, normalizeLineEndings(stdout));
68+
});
69+
}
70+
71+
// Read a fixture file, normalizing file contents to unix file endings.
72+
function fixture(filename) {
73+
return normalizeLineEndings(String(fs.readFileSync(filename)));
74+
}
75+
76+
function buildTests() {
77+
// Build individual unit tests for command output.
78+
var counts = [10, 100, 1000];
79+
var outputs = [' stdout stderr', ' stdout', ' stderr'];
80+
var pipes = ['', ' | ' + grep + ' "std"'];
81+
counts.forEach(function(count) {
82+
outputs.forEach(function(output) {
83+
pipes.forEach(function(pipe) {
84+
var command = 'node log.js 0 ' + count + output + ' 2>&1' + pipe;
85+
exports['exit']['output (' + command + ')'] = function(test) {
86+
test.expect(2);
87+
run(command, function(code, actual) {
88+
var expected = fixture(count + output.replace(/ /g, '-') + '.txt');
89+
// Sometimes, the actual file lines are out of order on Windows.
90+
// But since the point of this lib is to drain the buffer and not
91+
// guarantee output order, we only test the length.
92+
test.equal(actual.length, expected.length, 'should be the same length.');
93+
// The "fail" lines in log.js should NOT be output!
94+
test.ok(actual.indexOf('fail') === -1, 'should not output after exit is called.');
95+
test.done();
96+
});
97+
};
98+
});
99+
});
100+
});
101+
102+
// Build individual unit tests for exit codes.
103+
var codes = [0, 1, 123];
104+
codes.forEach(function(code) {
105+
var command = 'node log.js ' + code + ' 10 stdout stderr';
106+
exports['exit']['exit code (' + command + ')'] = function(test) {
107+
test.expect(1);
108+
run(command, function(actual) {
103109
// The specified exit code should be passed through.
104-
test.equal(code, n, 'should have exited with ' + n + ' error code.');
105-
next();
110+
test.equal(actual, code, 'should exit with ' + code + ' error code.');
111+
test.done();
106112
});
107-
}, test.done);
108-
},
109-
};
113+
};
114+
});
115+
}
116+
117+
// Don't bother building tests if grep wasn't found, otherwise everything will
118+
// fail and the error will get lost.
119+
if (grep) {
120+
buildTests();
121+
}

0 commit comments

Comments
 (0)