UNPKG

spectacular

Version:

Advanced BDD framework for CoffeeScript and JavaScript

302 lines (283 loc) 9.25 kB
// Generated by CoffeeScript 1.6.3 var Q, SPECTACULAR_ROOT, colorize, exists, express, findrequire, fs, generateSpecRunner, glob, globPath, globPaths, jade, path, scriptNode, spawn, util, walk, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; fs = require('fs'); Q = require('q'); glob = require('glob'); path = require('path'); express = require('express'); walk = require('walkdir'); util = require('util'); spawn = require('child_process').spawn; jade = require('jade'); exists = fs.exists || path.exists; SPECTACULAR_ROOT = path.resolve(__dirname, '..'); colorize = null; findrequire = function(p, options) { var defer, res; defer = Q.defer(); res = []; exists(p, function(exist) { var emitter; if (exist) { emitter = walk(p); emitter.on('file', function(p, stat) { return res.push(path.relative('.', p)); }); return emitter.on('end', function() { return defer.resolve(res); }); } else { return defer.resolve([]); } }); return defer.promise; }; globPath = function(p) { var defer; defer = Q.defer(); glob(p, function(err, res) { if (err) { return defer.reject(err); } return defer.resolve(res); }); return defer.promise; }; globPaths = function(globs) { var p, _this = this; return Q.all((function() { var _i, _len, _results; _results = []; for (_i = 0, _len = globs.length; _i < _len; _i++) { p = globs[_i]; _results.push(globPath(p)); } return _results; })()).then(function(results) { var paths; paths = []; results.forEach(function(a) { return paths = paths.concat(a); }); return paths; }); }; scriptNode = function(path) { return "<script type='text/javascript' src='" + path + "'></script>"; }; generateSpecRunner = function(options) { var p, paths, templates; if (options.verbose) { console.log(" " + (colorize('options', 'grey')) + " " + (util.inspect(options))); } paths = ['assets/js/spectacular.js', 'assets/js/browser_reporter.js']; templates = {}; return Q.all((function() { var _i, _len, _ref, _results; _ref = options.requires; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { p = _ref[_i]; _results.push(findrequire(p, options)); } return _results; })()).then(function(requires) { var collection, f, _i, _j, _len, _len1; for (_i = 0, _len = requires.length; _i < _len; _i++) { collection = requires[_i]; for (_j = 0, _len1 = collection.length; _j < _len1; _j++) { f = collection[_j]; if (/(js|coffee)$/.test(f)) { paths.push(f); if (options.verbose) { console.log(" " + (colorize('requires', 'grey')) + " " + f); } } } } return globPaths(options.globs); }).then(function(specs) { var f, uniq, v, _i, _j, _len, _len1; if (options.verbose) { for (_i = 0, _len = specs.length; _i < _len; _i++) { f = specs[_i]; console.log(" " + (colorize('spec', 'grey')) + " " + f); } } paths = paths.concat(specs); uniq = []; for (_j = 0, _len1 = paths.length; _j < _len1; _j++) { v = paths[_j]; if (__indexOf.call(uniq, v) < 0) { uniq.push(v); } } return paths = uniq; }).then(function() { return globPaths([path.resolve(SPECTACULAR_ROOT, 'templates/formatters/*.jade')]); }).then(function(tpls) { var n, p, _i, _len; for (_i = 0, _len = tpls.length; _i < _len; _i++) { p = tpls[_i]; n = p.split('/'); n = n[n.length - 1]; n = n.split('.')[0]; templates[n] = jade.compile(fs.readFileSync(p), { client: true, compileDebug: false }).toString(); templates[n] = "<script type='text/javascript'>\nspectacular.templates['" + n + "'] = " + templates[n] + "\n</script>"; } return globPaths(options.sources); }).then(function(sources) { var f, locals, tpl, tplPath, _i, _len; if (options.verbose) { for (_i = 0, _len = sources.length; _i < _len; _i++) { f = sources[_i]; console.log(" " + (colorize('source', 'grey')) + " " + f); } } options.paths = paths.slice(2); locals = { options: util.inspect(options), paths: paths, sources: sources, pretty: true, sourceMap: options.sourceMap, templates: templates }; tplPath = path.resolve(SPECTACULAR_ROOT, 'templates/specs.jade'); if (options.verbose) { console.log(" " + (colorize('template', 'grey')) + " " + tplPath); } return tpl = jade.renderFile(tplPath, locals); }); }; exports.run = function(options) { var app, defer, phantom, port; colorize = function(str, color) { if (options.colors) { return str[color]; } else { return str; } }; defer = Q.defer(); app = express(); app.get('/', function(req, res) { return generateSpecRunner(options).then(function(html) { console.log(" " + (colorize('200', 'green')) + " " + (colorize('GET', 'cyan')) + " /"); return res.send(html); }).fail(function(reason) { var tplPath; console.log(" " + (colorize('500', 'red')) + " " + (colorize('GET', 'cyan')) + " /"); console.log(reason.stack); tplPath = path.resolve(SPECTACULAR_ROOT, 'templates/500.jade'); return res.status(500).send(jade.renderFile(tplPath, { error: reason.stack })); }); }); app.use('/assets/js', express["static"](path.resolve(SPECTACULAR_ROOT, 'lib'))); app.use('/vendor', express["static"](path.resolve(SPECTACULAR_ROOT, 'vendor'))); app.use('/assets/css', express["static"](path.resolve(SPECTACULAR_ROOT, 'css'))); app.use('/', function(req, res, next) { var compile, compiled, content, notFound, reason, serverError; serverError = function(reason) { var tplPath; tplPath = path.resolve(SPECTACULAR_ROOT, 'templates/500.jade'); console.log(" " + (colorize('500', 'red')) + " " + (colorize('GET', 'cyan')) + " " + req.url); return res.status(500).send(jade.renderFile(tplPath, { error: reason.stack })); }; notFound = function(reason) { var tplPath; tplPath = path.resolve(SPECTACULAR_ROOT, 'templates/404.jade'); console.log(" " + (colorize('404', 'red')) + " " + (colorize('GET', 'cyan')) + " " + req.url); return res.status(404).send(jade.renderFile(tplPath, { error: reason.stack })); }; if (/\.coffee$/.test(req.url) && options.coffee) { try { content = fs.readFileSync(path.resolve("." + req.url)).toString(); } catch (_error) { reason = _error; return notFound(reason); } try { compile = require('coffee-script').compile; } catch (_error) { reason = _error; return serverError(notFound); } content = compile(content); } else if (/\.coffee\.src$/.test(req.url) && options.coffee) { try { content = fs.readFileSync(path.resolve("." + (req.url.replace('.coffee.src', '.coffee')))).toString(); } catch (_error) { reason = _error; return notFound(reason); } } else if (/\.map$/.test(req.url) && options.coffee) { try { content = fs.readFileSync(path.resolve("." + (req.url.replace('.map', '.coffee')))).toString(); } catch (_error) { reason = _error; return notFound(reason); } try { compile = require('coffee-script').compile; compiled = compile(content, { sourceMap: true }); content = compiled.v3SourceMap; } catch (_error) { reason = _error; serverError(reason); } } else { try { content = fs.readFileSync(path.resolve("." + req.url)).toString(); } catch (_error) { reason = _error; return notFound(reason); } } console.log(" " + (colorize('200', 'green')) + " " + (colorize('GET', 'cyan')) + " " + req.url); return res.send(content); }); port = process.env.PORT || 5000; app.listen(port); console.log(" server listening on port " + (port.toString().cyan)); if (options.phantomjs) { console.log(" running tests on phantomjs"); phantom = spawn(options.phantomjsExecutable, ['./lib/spectacular_phantomjs.js', port]); phantom.stdout.on('data', function(data) { return util.print(data.toString()); }); phantom.stderr.on('data', function(data) { return util.print(data.toString()); }); phantom.on('exit', function(status) { return process.exit(status); }); } if (options.slimerjs) { console.log(" running tests on slimerjs"); phantom = spawn(options.slimerjsExecutable, ['./src/spectacular_slimerjs.coffee', port]); phantom.stdout.on('data', function(data) { return util.print(data.toString()); }); phantom.stderr.on('data', function(data) { return util.print(data.toString()); }); phantom.on('exit', function(status) { return process.exit(status); }); } return defer.promise; };