diff options
| author | Jules Laplace <jules@okfoc.us> | 2012-09-24 16:22:07 -0400 |
|---|---|---|
| committer | Jules Laplace <jules@okfoc.us> | 2012-09-24 16:22:07 -0400 |
| commit | 686106d544ecc3b6ffd4db2b665d3bc879a58d8c (patch) | |
| tree | a5b5e50237cef70e12f0745371896e96f5f6d578 /.bin | |
ok
Diffstat (limited to '.bin')
| -rwxr-xr-x | .bin/_mocha | 345 | ||||
| -rwxr-xr-x | .bin/express | 416 | ||||
| -rwxr-xr-x | .bin/mocha | 32 |
3 files changed, 793 insertions, 0 deletions
diff --git a/.bin/_mocha b/.bin/_mocha new file mode 100755 index 0000000..3a7a903 --- /dev/null +++ b/.bin/_mocha @@ -0,0 +1,345 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var program = require('commander') + , exec = require('child_process').exec + , path = require('path') + , resolve = path.resolve + , mocha = require('../') + , utils = mocha.utils + , reporters = mocha.reporters + , interfaces = mocha.interfaces + , Context = mocha.Context + , Runner = mocha.Runner + , Suite = mocha.Suite + , vm = require('vm') + , fs = require('fs') + , join = path.join + , cwd = process.cwd(); + +/** + * Files. + */ + +var files = []; + +/** + * Images. + */ + +var images = { + fail: __dirname + '/../images/error.png' + , pass: __dirname + '/../images/ok.png' +}; + +// options + +program + .version(mocha.version) + .usage('[debug] [options] [files]') + .option('-r, --require <name>', 'require the given module') + .option('-R, --reporter <name>', 'specify the reporter to use', 'dot') + .option('-u, --ui <name>', 'specify user-interface (bdd|tdd|exports)', 'bdd') + .option('-g, --grep <pattern>', 'only run tests matching <pattern>') + .option('-t, --timeout <ms>', 'set test-case timeout in milliseconds [2000]') + .option('-s, --slow <ms>', '"slow" test threshold in milliseconds [75]', parseInt) + .option('-w, --watch', 'watch files for changes') + .option('-c, --colors', 'force enabling of colors') + .option('-C, --no-colors', 'force disabling of colors') + .option('-G, --growl', 'enable growl notification support') + .option('-d, --debug', "enable node's debugger, synonym for node --debug") + .option('-b, --bail', "bail after first test failure") + .option('--debug-brk', "enable node's debugger breaking on the first line") + .option('--globals <names>', 'allow the given comma-delimited global [names]', list, []) + .option('--ignore-leaks', 'ignore global variable leaks') + .option('--interfaces', 'display available interfaces') + .option('--reporters', 'display available reporters') + .option('--compilers <ext>:<module>,...', 'use the given module(s) to compile files', list, []) + +program.name = 'mocha'; + +// --reporters + +program.on('reporters', function(){ + console.log(); + console.log(' dot - dot matrix'); + console.log(' doc - html documentation'); + console.log(' spec - hierarchical spec list'); + console.log(' json - single json object'); + console.log(' progress - progress bar'); + console.log(' list - spec-style listing'); + console.log(' tap - test-anything-protocol'); + console.log(' landing - unicode landing strip'); + console.log(' xunit - xunit reportert'); + console.log(' teamcity - teamcity ci support'); + console.log(' html-cov - HTML test coverage'); + console.log(' json-cov - JSON test coverage'); + console.log(' min - minimal reporter (great with --watch)'); + console.log(' json-stream - newline delimited json events'); + console.log(' markdown - markdown documentation (github flavour)'); + console.log(); + process.exit(); +}); + +// --interfaces + +program.on('interfaces', function(){ + console.log(''); + console.log(' bdd'); + console.log(' tdd'); + console.log(' qunit'); + console.log(' exports'); + console.log(''); + process.exit(); +}); + +// -r, --require + +module.paths.push(cwd, join(cwd, 'node_modules')); + +program.on('require', function(mod){ + var abs = path.existsSync(mod) + || path.existsSync(mod + '.js'); + + if (abs) mod = join(cwd, mod); + require(mod); +}); + +// mocha.opts support + +try { + var opts = fs.readFileSync('test/mocha.opts', 'utf8') + .trim() + .split(/\s+/); + + process.argv = process.argv + .slice(0, 2) + .concat(opts.concat(process.argv.slice(2))); +} catch (err) { + // ignore +} + +// parse args + +program.parse(process.argv); + +// infinite stack traces + +Error.stackTraceLimit = Infinity; // TODO: config + +// reporter + +var suite = new Suite('', new Context) + , Base = require('../lib/reporters/base') + , Reporter = require('../lib/reporters/' + program.reporter) + , ui = interfaces[program.ui](suite); + +// --no-colors + +if (!program.colors) Base.useColors = false; + +// --colors + +if (~process.argv.indexOf('--colors') || + ~process.argv.indexOf('-c')) { + Base.useColors = true; +} + +// --slow <ms> + +if (program.slow) Base.slow = program.slow; + +// --timeout + +if (program.timeout) suite.timeout(program.timeout); + +// --bail + +suite.bail(program.bail); + +// custom compiler support + +var extensions = ['js']; +program.compilers.forEach(function(c) { + var compiler = c.split(':') + , ext = compiler[0] + , mod = compiler[1]; + + if (mod[0] == '.') mod = join(process.cwd(), mod); + require(mod); + extensions.push(ext); +}); + +var re = new RegExp('\\.(' + extensions.join('|') + ')$'); + +// files + +var files = program.args; + +// default files to test/*.{js,coffee} + +if (!files.length) { + files = fs.readdirSync('test').filter(function(path){ + return path.match(re); + }).map(function(path){ + return join('test', path); + }); +} + +// resolve + +files = files.map(function(path){ + return resolve(path); +}); + +// --watch + +if (program.watch) { + console.log(); + hideCursor(); + process.on('SIGINT', function(){ + showCursor(); + console.log('\n'); + process.exit(); + }); + + var frames = [ + ' \033[96m◜ \033[90mwatching\033[0m' + , ' \033[96m◠ \033[90mwatching\033[0m' + , ' \033[96m◝ \033[90mwatching\033[0m' + , ' \033[96m◞ \033[90mwatching\033[0m' + , ' \033[96m◡ \033[90mwatching\033[0m' + , ' \033[96m◟ \033[90mwatching\033[0m' + ]; + + var watchFiles = utils.files(cwd); + + function loadAndRun() { + load(files, function(){ + run(suite, function(){ + play(frames); + }); + }); + } + + function purge() { + watchFiles.forEach(function(file){ + delete require.cache[file]; + }); + } + + loadAndRun(); + + utils.watch(watchFiles, function(){ + purge(); + stop() + suite = suite.clone(); + ui = interfaces[program.ui](suite); + loadAndRun(); + }); + + return; +} + +// load + +load(files, function(){ + run(suite, process.exit); +}); + +// require test files before +// running the root suite + +function load(files, fn) { + var pending = files.length; + files.forEach(function(file){ + delete require.cache[file]; + suite.emit('pre-require', global, file); + suite.emit('require', require(file), file); + suite.emit('post-require', global, file); + --pending || fn(); + }); +} + +// run the given suite + +function run(suite, fn) { + suite.emit('run'); + var runner = new Runner(suite); + var reporter = new Reporter(runner); + runner.globals(program.globals); + if (program.ignoreLeaks) runner.ignoreLeaks = true; + if (program.grep) runner.grep(new RegExp(program.grep)); + if (program.growl) growl(runner, reporter); + runner.run(fn); +} + +// enable growl notifications + +function growl(runner, reporter) { + var notify = require('growl'); + + runner.on('end', function(){ + var stats = reporter.stats; + if (stats.failures) { + var msg = stats.failures + ' of ' + runner.total + ' tests failed'; + notify(msg, { title: 'Failed', image: images.fail }); + } else { + notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', { + title: 'Passed' + , image: images.pass + }); + } + }); +} + +/** + * Parse list. + */ + +function list(str) { + return str.split(/ *, */); +} + +/** + * Hide the cursor. + */ + +function hideCursor(){ + process.stdout.write('\033[?25l'); +}; + +/** + * Show the cursor. + */ + +function showCursor(){ + process.stdout.write('\033[?25h'); +}; + +/** + * Stop play()ing. + */ + +function stop() { + process.stdout.write('\033[2K'); + clearInterval(play.timer); +} + +/** + * Play the given array of strings. + */ + +function play(arr, interval) { + var len = arr.length + , interval = interval || 100 + , i = 0; + + play.timer = setInterval(function(){ + var str = arr[i++ % len]; + process.stdout.write('\r' + str); + }, interval); +} diff --git a/.bin/express b/.bin/express new file mode 100755 index 0000000..2c902c3 --- /dev/null +++ b/.bin/express @@ -0,0 +1,416 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var fs = require('fs') + , os = require('os') + , exec = require('child_process').exec + , mkdirp = require('mkdirp'); + +/** + * Framework version. + */ + +var version = '2.5.8'; + +/** + * Add session support. + */ + +var sessions = false; + +/** + * CSS engine to utilize. + */ + +var cssEngine; + +/** + * End-of-line code. + */ + +var eol = os.platform + ? ('win32' == os.platform() ? '\r\n' : '\n') + : '\n'; + +/** + * Template engine to utilize. + */ + +var templateEngine = 'jade'; + +/** + * Usage documentation. + */ + +var usage = '' + + '\n' + + ' Usage: express [options] [path]\n' + + '\n' + + ' Options:\n' + + ' -s, --sessions add session support\n' + + ' -t, --template <engine> add template <engine> support (jade|ejs). default=jade\n' + + ' -c, --css <engine> add stylesheet <engine> support (stylus). default=plain css\n' + + ' -v, --version output framework version\n' + + ' -h, --help output help information\n' + ; + +/** + * Routes index template. + */ + +var index = [ + '' + , '/*' + , ' * GET home page.' + , ' */' + , '' + , 'exports.index = function(req, res){' + , ' res.render(\'index\', { title: \'Express\' })' + , '};' +].join(eol); + +/** + * Jade layout template. + */ + +var jadeLayout = [ + '!!!' + , 'html' + , ' head' + , ' title= title' + , ' link(rel=\'stylesheet\', href=\'/stylesheets/style.css\')' + , ' body!= body' +].join(eol); + +/** + * Jade index template. + */ + +var jadeIndex = [ + 'h1= title' + , 'p Welcome to #{title}' +].join(eol); + +/** + * EJS layout template. + */ + +var ejsLayout = [ + '<!DOCTYPE html>' + , '<html>' + , ' <head>' + , ' <title><%= title %></title>' + , ' <link rel=\'stylesheet\' href=\'/stylesheets/style.css\' />' + , ' </head>' + , ' <body>' + , ' <%- body %>' + , ' </body>' + , '</html>' +].join(eol); + +/** + * EJS index template. + */ + +var ejsIndex = [ + '<h1><%= title %></h1>' + , '<p>Welcome to <%= title %></p>' + ].join(eol); + +/** + * Default css template. + */ + +var css = [ + 'body {' + , ' padding: 50px;' + , ' font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;' + , '}' + , '' + , 'a {' + , ' color: #00B7FF;' + , '}' +].join(eol); + +/** + * Default stylus template. + */ + +var stylus = [ + 'body' + , ' padding: 50px' + , ' font: 14px "Lucida Grande", Helvetica, Arial, sans-serif' + , 'a' + , ' color: #00B7FF' +].join(eol); + +/** + * App template. + */ + +var app = [ + '' + , '/**' + , ' * Module dependencies.' + , ' */' + , '' + , 'var express = require(\'express\')' + , ' , routes = require(\'./routes\');' + , '' + , 'var app = module.exports = express.createServer();' + , '' + , '// Configuration' + , '' + , 'app.configure(function(){' + , ' app.set(\'views\', __dirname + \'/views\');' + , ' app.set(\'view engine\', \':TEMPLATE\');' + , ' app.use(express.bodyParser());' + , ' app.use(express.methodOverride());{sess}{css}' + , ' app.use(app.router);' + , ' app.use(express.static(__dirname + \'/public\'));' + , '});' + , '' + , 'app.configure(\'development\', function(){' + , ' app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));' + , '});' + , '' + , 'app.configure(\'production\', function(){' + , ' app.use(express.errorHandler());' + , '});' + , '' + , '// Routes' + , '' + , 'app.get(\'/\', routes.index);' + , '' + , 'app.listen(3000);' + , 'console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);' + , '' +].join(eol); + +// Parse arguments + +var args = process.argv.slice(2) + , path = '.'; + +while (args.length) { + var arg = args.shift(); + switch (arg) { + case '-h': + case '--help': + abort(usage); + break; + case '-v': + case '--version': + abort(version); + break; + case '-s': + case '--session': + case '--sessions': + sessions = true; + break; + case '-c': + case '--css': + args.length + ? (cssEngine = args.shift()) + : abort('--css requires an argument'); + break; + case '-t': + case '--template': + args.length + ? (templateEngine = args.shift()) + : abort('--template requires an argument'); + break; + default: + path = arg; + } +} + +// Generate application + +(function createApplication(path) { + emptyDirectory(path, function(empty){ + if (empty) { + createApplicationAt(path); + } else { + confirm('destination is not empty, continue? ', function(ok){ + if (ok) { + process.stdin.destroy(); + createApplicationAt(path); + } else { + abort('aborting'); + } + }); + } + }); +})(path); + +/** + * Create application at the given directory `path`. + * + * @param {String} path + */ + +function createApplicationAt(path) { + console.log(); + process.on('exit', function(){ + console.log(); + console.log(' dont forget to install dependencies:'); + console.log(' $ cd %s && npm install', path); + console.log(); + }); + + mkdir(path, function(){ + mkdir(path + '/public'); + mkdir(path + '/public/javascripts'); + mkdir(path + '/public/images'); + mkdir(path + '/public/stylesheets', function(){ + switch (cssEngine) { + case 'stylus': + write(path + '/public/stylesheets/style.styl', stylus); + break; + default: + write(path + '/public/stylesheets/style.css', css); + } + }); + + mkdir(path + '/routes', function(){ + write(path + '/routes/index.js', index); + }); + + mkdir(path + '/views', function(){ + switch (templateEngine) { + case 'ejs': + write(path + '/views/layout.ejs', ejsLayout); + write(path + '/views/index.ejs', ejsIndex); + break; + case 'jade': + write(path + '/views/layout.jade', jadeLayout); + write(path + '/views/index.jade', jadeIndex); + break; + } + }); + + // CSS Engine support + switch (cssEngine) { + case 'stylus': + app = app.replace('{css}', eol + ' app.use(require(\'stylus\').middleware({ src: __dirname + \'/public\' }));'); + break; + default: + app = app.replace('{css}', ''); + } + + // Session support + app = app.replace('{sess}', sessions + ? eol + ' app.use(express.cookieParser());' + eol + ' app.use(express.session({ secret: \'your secret here\' }));' + : ''); + + // Template support + app = app.replace(':TEMPLATE', templateEngine); + + // package.json + var json = '{' + eol; + json += ' "name": "application-name"' + eol; + json += ' , "version": "0.0.1"' + eol; + json += ' , "private": true' + eol; + json += ' , "dependencies": {' + eol; + json += ' "express": "' + version + '"' + eol; + if (cssEngine) json += ' , "' + cssEngine + '": ">= 0.0.1"' + eol; + if (templateEngine) json += ' , "' + templateEngine + '": ">= 0.0.1"' + eol; + json += ' }' + eol; + json += '}'; + + + write(path + '/package.json', json); + write(path + '/app.js', app); + }); +} + +/** + * Check if the given directory `path` is empty. + * + * @param {String} path + * @param {Function} fn + */ + +function emptyDirectory(path, fn) { + fs.readdir(path, function(err, files){ + if (err && 'ENOENT' != err.code) throw err; + fn(!files || !files.length); + }); +} + +/** + * echo str > path. + * + * @param {String} path + * @param {String} str + */ + +function write(path, str) { + fs.writeFile(path, str); + console.log(' \x1b[36mcreate\x1b[0m : ' + path); +} + +/** + * Prompt confirmation with the given `msg`. + * + * @param {String} msg + * @param {Function} fn + */ + +function confirm(msg, fn) { + prompt(msg, function(val){ + fn(/^ *y(es)?/i.test(val)); + }); +} + +/** + * Prompt input with the given `msg` and callback `fn`. + * + * @param {String} msg + * @param {Function} fn + */ + +function prompt(msg, fn) { + // prompt + if (' ' == msg[msg.length - 1]) { + process.stdout.write(msg); + } else { + console.log(msg); + } + + // stdin + process.stdin.setEncoding('ascii'); + process.stdin.once('data', function(data){ + fn(data); + }).resume(); +} + +/** + * Mkdir -p. + * + * @param {String} path + * @param {Function} fn + */ + +function mkdir(path, fn) { + mkdirp(path, 0755, function(err){ + if (err) throw err; + console.log(' \033[36mcreate\033[0m : ' + path); + fn && fn(); + }); +} + +/** + * Exit with the given `str`. + * + * @param {String} str + */ + +function abort(str) { + console.error(str); + process.exit(1); +} diff --git a/.bin/mocha b/.bin/mocha new file mode 100755 index 0000000..811ed9d --- /dev/null +++ b/.bin/mocha @@ -0,0 +1,32 @@ +#!/usr/bin/env node + +/** + * This tiny wrapper file checks for known node flags and appends them + * when found, before invoking the "real" _mocha(1) executable. + */ + +var spawn = require('child_process').spawn + , args = [ __dirname + '/_mocha' ]; + +process.argv.slice(2).forEach(function (arg) { + switch (arg) { + case '-d': + args.unshift('--debug'); + break; + case 'debug': + case '--debug': + case '--debug-brk': + args.unshift(arg); + break; + case '-gc': + case '--expose-gc': + args.unshift('--expose-gc'); + break; + default: + args.push(arg); + break; + } +}); + +var proc = spawn(process.argv[0], args, { customFds: [0,1,2] }); +proc.on('exit', process.exit); |
