allow options for tests and benchmarks.

This commit is contained in:
Christopher Jeffrey 2013-02-07 03:51:43 -06:00
parent 55a3a81e7f
commit 6246784914
3 changed files with 208 additions and 24 deletions

View File

@ -72,6 +72,8 @@ function main(argv, callback) {
while (argv.length) { while (argv.length) {
arg = getarg(); arg = getarg();
switch (arg) { switch (arg) {
case 'test':
return require('../test').main(process.argv.slice());
case '-o': case '-o':
case '--output': case '--output':
output = argv.shift(); output = argv.shift();

View File

@ -1,7 +1,8 @@
var fs = require('fs'); var fs = require('fs');
var main = require('../') var test = require('../')
, load = main.load; , runTests = test.runTests
, load = test.load;
var express = require('express') var express = require('express')
, app = express(); , app = express();
@ -28,7 +29,7 @@ app.get('/test.js', function(req, res, next) {
, files = load(); , files = load();
test = test.replace('__TESTS__', JSON.stringify(files)); test = test.replace('__TESTS__', JSON.stringify(files));
test = test.replace('__MAIN__', main + ''); test = test.replace('__MAIN__', runTests + '');
res.contentType('.js'); res.contentType('.js');
res.send(test); res.send(test);

View File

@ -1,9 +1,23 @@
#!/usr/bin/env node #!/usr/bin/env node
/**
* marked tests
* Copyright (c) 2011-2013, Christopher Jeffrey. (MIT Licensed)
* https://github.com/chjj/marked
*/
/**
* Modules
*/
var fs = require('fs') var fs = require('fs')
, path = require('path') , path = require('path')
, marked = require('../'); , marked = require('../');
/**
* Load Tests
*/
function load() { function load() {
var dir = __dirname + '/tests' var dir = __dirname + '/tests'
, files = {} , files = {}
@ -37,10 +51,22 @@ function load() {
return files; return files;
} }
function runTests(options) { /**
var options = options || {} * Test Runner
*/
function runTests(engine, options) {
if (typeof engine !== 'function') {
options = engine;
engine = null;
}
var engine = engine || marked
, options = options || {}
, files = options.files || load() , files = options.files || load()
, complete = 0 , complete = 0
, failed = 0
, skipped = 0
, keys = Object.keys(files) , keys = Object.keys(files)
, i = 0 , i = 0
, len = keys.length , len = keys.length
@ -51,13 +77,28 @@ function runTests(options) {
, j , j
, l; , l;
if (options.marked) {
marked.setOptions(options.marked);
}
main: main:
for (; i < len; i++) { for (; i < len; i++) {
filename = keys[i]; filename = keys[i];
file = files[filename]; file = files[filename];
if ((~filename.indexOf('.gfm.') && !marked.defaults.gfm)
|| (~filename.indexOf('.tables.') && !marked.defaults.tables)
|| (~filename.indexOf('.breaks.') && !marked.defaults.breaks)
|| (~filename.indexOf('.pedantic.') && !marked.defaults.pedantic)
|| (~filename.indexOf('.sanitize.') && !marked.defaults.sanitize)
|| (~filename.indexOf('.smartlists.') && !marked.defaults.smartLists)) {
skipped++;
console.log('#%d. %s skipped.', i + 1, filename);
continue main;
}
try { try {
text = marked(file.text).replace(/\s/g, ''); text = engine(file.text).replace(/\s/g, '');
html = file.html.replace(/\s/g, ''); html = file.html.replace(/\s/g, '');
} catch(e) { } catch(e) {
console.log('%s failed.', filename); console.log('%s failed.', filename);
@ -77,6 +118,8 @@ main:
Math.max(j - 30, 0), Math.max(j - 30, 0),
Math.min(j + 30, html.length)); Math.min(j + 30, html.length));
failed++;
console.log( console.log(
'\n#%d. %s failed at offset %d. Near: "%s".\n', '\n#%d. %s failed at offset %d. Near: "%s".\n',
i + 1, filename, j, text); i + 1, filename, j, text);
@ -97,8 +140,14 @@ main:
} }
console.log('%d/%d tests completed successfully.', complete, len); console.log('%d/%d tests completed successfully.', complete, len);
if (failed) console.log('%d/%d tests failed.', failed, len);
if (skipped) console.log('%d/%d tests skipped.', skipped, len);
} }
/**
* Benchmark a function
*/
function bench(name, func) { function bench(name, func) {
var files = bench.files || load(); var files = bench.files || load();
@ -139,37 +188,60 @@ function bench(name, func) {
console.log('%s completed in %dms.', name, Date.now() - start); console.log('%s completed in %dms.', name, Date.now() - start);
} }
function runBench() { /**
* Benchmark all engines
*/
function runBench(options) {
var options = options || {};
// Non-GFM, Non-pedantic
marked.setOptions({ marked.setOptions({
gfm: false, gfm: false,
tables: false, tables: false,
breaks: false, breaks: false,
pedantic: false, pedantic: false,
sanitize: false sanitize: false,
smartLists: false
}); });
if (options.marked) {
marked.setOptions(options.marked);
}
bench('marked', marked); bench('marked', marked);
// GFM
marked.setOptions({ marked.setOptions({
gfm: true, gfm: true,
tables: false, tables: false,
breaks: false, breaks: false,
pedantic: false, pedantic: false,
sanitize: false sanitize: false,
smartLists: false
}); });
if (options.marked) {
marked.setOptions(options.marked);
}
bench('marked (gfm)', marked); bench('marked (gfm)', marked);
// Pedantic
marked.setOptions({ marked.setOptions({
gfm: false, gfm: false,
tables: false, tables: false,
breaks: false, breaks: false,
pedantic: true, pedantic: true,
sanitize: false sanitize: false,
smartLists: false
}); });
if (options.marked) {
marked.setOptions(options.marked);
}
bench('marked (pedantic)', marked); bench('marked (pedantic)', marked);
// Discount
var discount = require('discount').parse; var discount = require('discount').parse;
bench('discount', discount); bench('discount', discount);
// Showdown (Reusing the converter)
var showdown = (function() { var showdown = (function() {
var Showdown = require('showdown').Showdown; var Showdown = require('showdown').Showdown;
var convert = new Showdown.converter(); var convert = new Showdown.converter();
@ -179,6 +251,7 @@ function runBench() {
})(); })();
bench('showdown (reuse converter)', showdown); bench('showdown (reuse converter)', showdown);
// Showdown
var showdown_slow = (function() { var showdown_slow = (function() {
var Showdown = require('showdown').Showdown; var Showdown = require('showdown').Showdown;
return function(text) { return function(text) {
@ -188,37 +261,145 @@ function runBench() {
})(); })();
bench('showdown (new converter)', showdown_slow); bench('showdown (new converter)', showdown_slow);
// markdown-js
var markdownjs = require('markdown'); var markdownjs = require('markdown');
bench('markdown-js', function(text) { bench('markdown-js', function(text) {
markdownjs.parse(text); markdownjs.parse(text);
}); });
} }
function time() { /**
var marked = require('../'); * A simple one-time benchmark
*/
function time(options) {
var options = options || {};
if (options.marked) {
marked.setOptions(options.marked);
}
bench('marked', marked); bench('marked', marked);
} }
function main(argv) { /**
if (~argv.indexOf('--bench')) { * Argument Parsing
return runBench(); */
function parseArg(argv) {
var argv = process.argv.slice(2)
, options = {}
, orphans = []
, arg;
function getarg() {
var arg = argv.shift();
if (arg.indexOf('--') === 0) {
// e.g. --opt
arg = arg.split('=');
if (arg.length > 1) {
// e.g. --opt=val
argv.unshift(arg.slice(1).join('='));
}
arg = arg[0];
} else if (arg[0] === '-') {
if (arg.length > 2) {
// e.g. -abc
argv = arg.substring(1).split('').map(function(ch) {
return '-' + ch;
}).concat(argv);
arg = argv.shift();
} else {
// e.g. -a
}
} else {
// e.g. foo
}
return arg;
} }
if (~argv.indexOf('--time')) { while (argv.length) {
return time(); arg = getarg();
switch (arg) {
case '-b':
case '--bench':
options.bench = true;
break;
case '-s':
case '--stop':
options.stop = true;
break;
case '-t':
case '--time':
options.time = true;
break;
default:
if (arg.indexOf('--') === 0) {
opt = camelize(arg.replace(/^--(no-)?/, ''));
if (!marked.defaults.hasOwnProperty(opt)) {
continue;
}
options.marked = options.marked || {};
if (arg.indexOf('--no-') === 0) {
options.marked[opt] = typeof marked.defaults[opt] !== 'boolean'
? null
: false;
} else {
options.marked[opt] = typeof marked.defaults[opt] !== 'boolean'
? argv.shift()
: true;
}
} else {
orphans.push(arg);
}
break;
}
} }
return runTests({ return options;
stop: !!~argv.indexOf('--stop') }
/**
* Helpers
*/
function camelize(text) {
return text.replace(/(\w)-(\w)/g, function(_, a, b) {
return a + b.toUpperCase();
}); });
} }
/**
* Main
*/
function main(argv) {
var opt = parseArg();
if (opt.bench) {
return runBench(opt);
}
if (opt.time) {
return time(opt);
}
return runTests(opt);
}
/**
* Execute
*/
if (!module.parent) { if (!module.parent) {
process.title = 'marked';
main(process.argv.slice()); main(process.argv.slice());
} else { } else {
main = runTests; exports = main;
main.main = main; exports.main = main;
main.load = load; exports.runTests = runTests;
main.bench = bench; exports.runBench = runBench;
module.exports = main; exports.load = load;
exports.bench = bench;
module.exports = exports;
} }