Skip to content

Commit f77df58

Browse files
committed
Add rudimentary support for async tests
This is very hacky, but closes #8. Version 1.3 is getting published ASAP, because I like breaking things.
1 parent f273797 commit f77df58

File tree

6 files changed

+86
-16
lines changed

6 files changed

+86
-16
lines changed

examples/async-failing.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* @example
3+
* takesCallback('something', cb)
4+
* // async => 'something - here'
5+
*/
6+
7+
function takesCallback(something, cb) {
8+
cb(new Error('bad things happen'));
9+
}

examples/async.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* @example
3+
* takesCallback('something', cb)
4+
* // async => 'something - here'
5+
*/
6+
7+
function takesCallback(something, cb) {
8+
cb(null, something + ' - here');
9+
}

lib/comment-parser.js

+8-3
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,13 @@ exports.parseExamples = function commentParser$parseExamples(parsedComments) {
9292
if(parsedComments[i].type === 'code') {
9393
if(currentExample.testCase) flush();
9494
currentExample.testCase = parsedComments[i].string;
95-
} else if(parsedComments[i].type === 'comment' && currentExample.testCase &&
96-
parsedComments[i].string.indexOf('=>') === 0) {
97-
currentExample.expectedResult += parsedComments[i].string.slice(3);
95+
} else if(parsedComments[i].type === 'comment' && currentExample.testCase) {
96+
if(parsedComments[i].string.indexOf('=>') === 0) {
97+
currentExample.expectedResult += parsedComments[i].string.slice(3);
98+
} else if(parsedComments[i].string.indexOf('async =>') === 0) {
99+
currentExample.expectedResult += parsedComments[i].string.slice(9);
100+
currentExample.isAsync = true;
101+
}
98102
}
99103
}
100104

@@ -106,6 +110,7 @@ exports.parseExamples = function commentParser$parseExamples(parsedComments) {
106110
if(currentExample.expectedResult) {
107111
examples.push(currentExample);
108112
}
113+
109114
currentExample = { expectedResult: '', };
110115
}
111116
};

lib/get-example-code.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict';
2+
3+
module.exports = exports = getExampleCode;
4+
5+
/**
6+
* Compiles down an `example`. Async examples call an imaginary `done` function
7+
* once they're done.
8+
*
9+
* @param {Object} comment
10+
* @param {String} comment.testCase
11+
* @param {String} comment.expectedResult
12+
* @param {Boolean} comment.isAsync
13+
* @return {String}
14+
*/
15+
16+
function getExampleCode(comment) {
17+
var expectedResult = comment.expectedResult;
18+
var isAsync = comment.isAsync;
19+
var testCase = comment.testCase.replace();
20+
21+
if(isAsync) {
22+
return '\nfunction cb(err, result) {' +
23+
'if(err) return done(err);' +
24+
'result.should.eql(' + expectedResult + ');' +
25+
'done();' +
26+
'}\n' +
27+
testCase;
28+
} else {
29+
return '(' + testCase + ').should.eql(' + expectedResult + ');';
30+
}
31+
}
32+
33+
/**
34+
* Escapes a string for meta-quoting
35+
*/
36+
37+
function escapeString(str) {
38+
return str.replace(/\'/g, '\\\'');
39+
}
40+
41+
exports.escapeString = escapeString;

lib/index.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ var path = require('path');
44
var dox = require('dox');
55
var _ = require('lodash');
66
var commentParser = require('./comment-parser');
7+
var getExampleCode = require('./get-example-code');
78
var util = require('./util');
89

10+
var escapeString = getExampleCode.escapeString;
11+
912
var JSDOCTEST_DISABLE = process.env.JSDOCTEST_DISABLE || false;
1013

1114
/**
@@ -91,10 +94,10 @@ exports.runRegistered = function() {
9194
exports.toJsdocRegister = function jsdoctest$toJsdocRegister(comment) {
9295
var baseId = comment.ctx.name + ' - ';
9396
var compiled = _.map(comment.examples, function(example) {
94-
var id = baseId + example.testCase + ' => ' + example.expectedResult;
95-
var fn = 'function() {' +
96-
'(' + example.testCase + ').should.equal(' + example.expectedResult + ');' +
97-
'}';
97+
var id = escapeString(baseId) +
98+
escapeString(example.testCase) + ' => ' +
99+
escapeString(example.expectedResult);
100+
var fn = 'function() {' + example.testCode + '}';
98101
return '__registerTest(\'' + id + '\', ' + fn + ');';
99102
}).join('');
100103

lib/mocha.js

+12-9
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ var fs = require('fs');
33
var path = require('path');
44
var _ = require('lodash');
55
var jsdoctest = require('./index');
6+
var getExampleCode = require('./get-example-code');
67
var util = require('./util');
78

9+
var escapeString = getExampleCode.escapeString;
10+
811
/**
912
* Mocks `mocha`'s register environment for doctest mocha integration. This
1013
* works in the same manner `coffee-script/register` or `mocha --require
@@ -31,7 +34,7 @@ function contentsToMochaSpec(rootDir, filename, content) {
3134
var comments = jsdoctest.getJsdoctests(content);
3235
var moduleName = exports._getModuleName(rootDir, filename);
3336

34-
return '\ndescribe(\'' + moduleName + '\', function() {' +
37+
return '\ndescribe(\'' + escapeString(moduleName) + '\', function() {' +
3538
_.map(_.compact(comments), function(comment) {
3639
return exports.commentToMochaSpec(comment);
3740
}).join('') +
@@ -45,14 +48,14 @@ function contentsToMochaSpec(rootDir, filename, content) {
4548

4649
exports.commentToMochaSpec = function commentToMochaSpec(comment) {
4750
var ctx = comment.ctx || {};
48-
return '\ndescribe(\'' + ctx.string + '\', function() {' +
49-
_.map(comment.examples, function(example) {
50-
return 'it(\'' + example.testCase + '\', function() {' +
51-
'(' + example.testCase + ')' +
52-
'.should.eql(' + example.expectedResult + ');' +
53-
'});';
54-
}).join('\n') +
55-
'});';
51+
return '\ndescribe(\'' + escapeString(ctx.string) + '\', function() {' +
52+
_.map(comment.examples, function(example) {
53+
return 'it(\'' + escapeString(example.testCase) +
54+
'\', function(' + (example.isAsync ? 'done' : '') + ') {' +
55+
getExampleCode(example) +
56+
'});';
57+
}).join('\n') +
58+
'});';
5659
};
5760

5861
var originalLoad;

0 commit comments

Comments
 (0)