UNPKG

spectacular

Version:

Advanced BDD framework for CoffeeScript and JavaScript

192 lines (157 loc) 6.1 kB
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' jade = require 'jade' exists = fs.exists or path.exists SPECTACULAR_ROOT = path.resolve __dirname, '..' colorize = null findrequire = (p, options) -> defer = Q.defer() res = [] exists p, (exist) -> if exist emitter = walk p emitter.on 'file', (p, stat) -> res.push path.relative '.', p emitter.on 'end', -> defer.resolve res else defer.resolve([]) defer.promise globPath = (p) -> defer = Q.defer() glob p, (err, res) -> return defer.reject err if err defer.resolve res defer.promise globPaths= (globs) -> Q.all(globPath p for p in globs).then (results) => paths = [] results.forEach (a) -> paths = paths.concat a paths scriptNode = (path) -> "<script type='text/javascript' src='#{path}'></script>" generateSpecRunner = (options) -> console.log " #{colorize 'options', 'grey'} #{util.inspect options}" if options.verbose paths = [ 'assets/js/spectacular.js' 'assets/js/browser_reporter.js' ] templates = {} Q.all(findrequire p, options for p in options.requires) .then (requires) -> for collection in requires for f in collection if /(js|coffee)$/.test f paths.push f console.log " #{colorize 'requires', 'grey'} #{f}" if options.verbose globPaths options.globs .then (specs) -> console.log " #{colorize 'spec', 'grey'} #{f}" for f in specs if options.verbose paths = paths.concat specs uniq = [] uniq.push v for v in paths when v not in uniq paths = uniq .then -> globPaths [path.resolve SPECTACULAR_ROOT, 'templates/formatters/*.jade'] .then (tpls) -> for p in tpls 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>" globPaths options.sources .then (sources) -> console.log " #{colorize 'source', 'grey'} #{f}" for f in sources if options.verbose options.paths = paths[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' console.log " #{colorize 'template', 'grey'} #{tplPath}" if options.verbose tpl = jade.renderFile(tplPath, locals) exports.run = (options) -> colorize = (str, color) -> if options.colors then str[color] else str defer = Q.defer() app = express() app.get '/', (req, res) -> generateSpecRunner(options) .then (html) -> console.log " #{colorize '200', 'green'} #{colorize 'GET', 'cyan'} /" res.send html .fail (reason) -> console.log " #{colorize '500', 'red'} #{colorize 'GET', 'cyan'} /" console.log reason.stack tplPath = path.resolve SPECTACULAR_ROOT, 'templates/500.jade' 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 '/', (req, res, next) -> serverError = (reason) -> tplPath = path.resolve SPECTACULAR_ROOT, 'templates/500.jade' console.log " #{colorize '500', 'red'} #{colorize 'GET', 'cyan'} #{req.url}" res.status(500).send jade.renderFile tplPath, error: reason.stack notFound = (reason) -> tplPath = path.resolve SPECTACULAR_ROOT, 'templates/404.jade' console.log " #{colorize '404', 'red'} #{colorize 'GET', 'cyan'} #{req.url}" res.status(404).send jade.renderFile tplPath, error: reason.stack if /\.coffee$/.test(req.url) and options.coffee try content = fs.readFileSync(path.resolve ".#{req.url}").toString() catch reason return notFound reason try {compile} = require 'coffee-script' catch reason return serverError notFound content = compile content else if /\.coffee\.src$/.test(req.url) and options.coffee try content = fs.readFileSync(path.resolve ".#{req.url.replace '.coffee.src', '.coffee'}").toString() catch reason return notFound reason else if /\.map$/.test(req.url) and options.coffee try content = fs.readFileSync(path.resolve ".#{req.url.replace '.map', '.coffee'}").toString() catch reason return notFound reason try {compile} = require 'coffee-script' compiled = compile content, sourceMap: true content = compiled.v3SourceMap catch reason serverError reason else try content = fs.readFileSync(path.resolve ".#{req.url}").toString() catch reason return notFound reason console.log " #{colorize '200', 'green'} #{colorize 'GET', 'cyan'} #{req.url}" res.send content port = process.env.PORT or 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', (data) -> util.print data.toString() phantom.stderr.on 'data', (data) -> util.print data.toString() phantom.on 'exit', (status) -> 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', (data) -> util.print data.toString() phantom.stderr.on 'data', (data) -> util.print data.toString() phantom.on 'exit', (status) -> process.exit status defer.promise