diff --git a/.jshintrc b/.jshintrc index fa9c2d2..103c8ae 100644 --- a/.jshintrc +++ b/.jshintrc @@ -16,7 +16,6 @@ }, "curly": true, "eqeqeq": true, - "esversion": 6, "freeze": true, "indent": 2, "latedef": false, diff --git a/.travis.yml b/.travis.yml index c8c7beb..cfdb8ec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,4 +2,4 @@ language: node_js script: npm test node_js: - "8" - - "10" + - "9" diff --git a/appveyor.yml b/appveyor.yml index da70154..5f9a377 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,8 +2,9 @@ environment: matrix: # node.js + - nodejs_version: "6" + - nodejs_version: "7" - nodejs_version: "8" - - nodejs_version: "10" # Install scripts. (runs after repo cloning) install: # Get the latest stable version of Node.js or io.js diff --git a/lib/app.js b/lib/app.js deleted file mode 100644 index 85ef8fa..0000000 --- a/lib/app.js +++ /dev/null @@ -1,51 +0,0 @@ -const path = require("path"); -const stack = require("./stack"); - - -const compression = require("./middleware/compression"); -const notFound = require("./middleware/not-found"); -const proxy = require("./middleware/proxy"); -const serveIndex = require('serve-index'); -const serveStatic = require("serve-static"); -const ssr = require("./middleware/ssr"); -const staticErrorPage = require("./middleware/static-errorpage"); -const staticPushstate = require("./middleware/static-pushstate"); - -module.exports = function (options) { - let layers = [ - compression() - ]; - - if(options.proxy) { - layers.push(proxy(options.proxy, options)); - //layers.push(proxy(options.proxy, options, "/socket.io/")); - } - - layers.push(serveStatic(path.join(options.path))); - - if(!options.static) { - let steal = { - config: path.join(options.path, 'package.json') + '!npm', - liveReload: options.liveReload - }; - - if(options.main) { - steal.main = options.main; - } - - layers.push(ssr(steal, options)); - } else { - layers.push(staticPushstate(options)); - layers.push(serveIndex(path.join(options.path), { icons: true })); - - if(options.errorPage) { - layers.push(staticErrorPage(options)); - } - } - - // 404s - layers.push(notFound); - - const app = stack(layers); - return app; -}; diff --git a/lib/cli/index.js b/lib/cli/index.js index 1a31136..d73e9dd 100644 --- a/lib/cli/index.js +++ b/lib/cli/index.js @@ -28,8 +28,54 @@ program.version(pkg.version) exports.program = program; exports.run = function(){ - const serve = require("../index"); - let exec = require("child_process").exec; + var makeServer = require("../index"); + var exec = require("child_process").exec; + var startServer = function(app){ + var servers = []; + // If using TLS, set up an HTTP2 server with automatic + // http->https forwarding. + if(options.key && options.cert) { + var net = require("net"); + var spdy = require("donejs-spdy"); + port = Number(port); + var httpPort = port + 1; + var httpsPort = httpPort + 1; + var server = spdy.createServer({ + key: fs.readFileSync(options.key), + cert: fs.readFileSync(options.cert), + spdy: { + protocols: ['h2', 'http/1.1'] + } + }, app); + server.listen(httpsPort); + servers.push(server); + + server = require("http").createServer(function(req, res){ + var host = req.headers.host; + res.writeHead(301, { "Location": "https://" + host + req.url }); + res.end(); + }); + server.listen(httpPort); + + // This is a TCP server that forwards to the correct port for + // http or https + net.createServer(function(conn){ + conn.once("data", function (buf) { + // A TLS handshake record starts with byte 22. + var address = (buf[0] === 22) ? httpsPort : httpPort; + var proxy = net.createConnection(address, function (){ + proxy.write(buf); + conn.pipe(proxy).pipe(conn); + }); + }); + }).listen(port); + + servers.push(server); + } else { + servers.push(app.listen(port)); + } + return servers; + }; var options = { path: program.args[0] ? path.join(process.cwd(), program.args[0]) : process.cwd(), @@ -84,10 +130,11 @@ exports.run = function(){ } } - let port = program.port || process.env.PORT || 3030; - let mainServer = serve(port, options); + var app = makeServer(options); + var port = program.port || process.env.PORT || 3030; + var servers = startServer(app); - mainServer.on('error', function(e) { + servers[0].on('error', function(e) { if(e.code === 'EADDRINUSE') { console.error('ERROR: Can not start done-serve on port ' + port + '.\nAnother application is already using it.'); @@ -97,8 +144,8 @@ exports.run = function(){ } }); - mainServer.on('listening', function() { - var address = mainServer.address(); + servers[0].on('listening', function() { + var address = servers[0].address(); var url = 'http://' + (address.address === '::' ? 'localhost' : address.address) + ':' + port; @@ -109,5 +156,5 @@ exports.run = function(){ console.log('done-serve starting on ' + url); }); - return mainServer; + return servers[0]; }; diff --git a/lib/http1.js b/lib/http1.js deleted file mode 100644 index c797cb7..0000000 --- a/lib/http1.js +++ /dev/null @@ -1,15 +0,0 @@ -const http1Symbol = Symbol.for("is-http/1"); - -function isHTTP1(req) { - return req[http1Symbol] === true; -} - -function markHTTP1(req) { - req[http1Symbol] = true; -} - -exports.is = isHTTP1; -exports.isHTTP1 = isHTTP1; - -exports.mark = markHTTP1; -exports.markHTTP1 = markHTTP1; diff --git a/lib/index.js b/lib/index.js index 0d7aca1..324c405 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,10 +1,99 @@ +var path = require('path'); -module.exports = function(port, options) { - let createApp = require("./app"); - let createServers = require("./servers").create; +var compression = require('compression'); +var errorFormat = require('donejs-error-format'); +var express = require('express'); +var serveIndex = require('serve-index'); +var debug = require('debug')('done-serve'); +var middleware = require('done-ssr-middleware'); +var fs = require('fs'); - let app = createApp(options); - let [mainServer] = createServers(port, options, app); +var proxy = require('./proxy'); - return mainServer; +function notFoundHandler(req, res, next) { + res.status(404); + next(new Error('File not found')); +} + +module.exports = function (options) { + var app = express() + .use(compression()); + + debug('Initializing done-serve application', options); + + if (options.configure) { + options.configure(app); + } + + if (options.proxy) { + proxy(app, options); + } + + app.use(express.static(path.join(options.path))); + + if(!options.static) { + var steal = { + config: path.join(options.path, 'package.json') + '!npm', + liveReload: options.liveReload + }; + + if(options.main) { + steal.main = options.main; + } + + var mw = middleware(steal, options); + + debug('Registering done-ssr-middleware'); + app.use(mw); + + // Error handler + app.use(function(error, request, response, next) { + var parts = errorFormat.extract(error); + var errorOptions = { + liveReload: !!options.liveReload + }; + var html = errorFormat.html(parts, errorOptions); + + if(options.logErrors !== false) { + console.log('\033c'); + console.error(error.stack); + } + + response.status(500).type('html').end(html); + }); + } else { + // Unobtrusively handle pushstate routing when SSR is turned off. + app.get('*', function (req, res, next) { + var urlParts = path.parse(req.url); + var isPushstateRoute = !urlParts.ext || urlParts.name.includes('?'); + if (isPushstateRoute) { + var env = process.env.NODE_ENV || 'development'; + var htmlPath = path.join(options.path, './' + env + '.html'); + if (!fs.existsSync(htmlPath)) { + htmlPath = path.join(options.path, './production.html'); + } + if (fs.existsSync(htmlPath)) { + return res.sendFile(htmlPath); + } + } + return next(); + }); + + app.use(serveIndex(path.join(options.path), { icons: true })); + app.use(notFoundHandler); + + if(options.errorPage) { + var filename = path.join(process.cwd(), options.errorPage); + + debug('Registering pushState file', filename); + + app.use(function(err, req, res, next) { + debug('Pushstate error handler', filename); + res.status(200); + res.sendFile(filename); + }); + } + } + + return app; }; diff --git a/lib/middleware/compression.js b/lib/middleware/compression.js deleted file mode 100644 index 4028ee6..0000000 --- a/lib/middleware/compression.js +++ /dev/null @@ -1,24 +0,0 @@ -const compression = require("compression"); -const {isHTTP1} = require("../http1"); - -module.exports = function() { - const mw = compression(); - - return function(req, res, next) { - let response; - - if(!isHTTP1(req)) { - response = Object.create(res, { - _implicitHeader: { - value: function(){ - this.writeHead(this.statusCode); - } - } - }); - } else { - response = res; - } - - mw(req, response, next); - }; -}; diff --git a/lib/middleware/error.js b/lib/middleware/error.js deleted file mode 100644 index fee5d68..0000000 --- a/lib/middleware/error.js +++ /dev/null @@ -1,23 +0,0 @@ -const errorFormat = require('donejs-error-format'); - -module.exports = function(options) { - return function(error, request, response) { - let parts = errorFormat.extract(error); - let errorOptions = { - liveReload: !!options.liveReload - }; - let html = errorFormat.html(parts, errorOptions); - - if(options.logErrors !== false) { - console.log('\033c'); - console.error(error.stack); - } - - response.writeHead(500, { - "content-type": "text/html", - "content-length": Buffer.byteLength(html) - }); - - response.end(html); - }; -}; diff --git a/lib/middleware/not-found.js b/lib/middleware/not-found.js deleted file mode 100644 index 1eb3775..0000000 --- a/lib/middleware/not-found.js +++ /dev/null @@ -1,7 +0,0 @@ -const chalk = require('chalk'); - -module.exports = function(req, res, next) { - console.error(`${chalk.red('404')} ${chalk.yellow.bgBlackBright.bold(' ' + req.url + ' ')}`); - res.writeHead(404); - res.end('Not found.'); -}; diff --git a/lib/middleware/proxy.js b/lib/middleware/proxy.js deleted file mode 100644 index 607d0ae..0000000 --- a/lib/middleware/proxy.js +++ /dev/null @@ -1,117 +0,0 @@ -var httpProxy = require('http-proxy'); -var url = require('url'); -const pathtoRegexp = require("path-to-regexp"); -const {isHTTP1} = require("../http1"); -var proxy = httpProxy.createProxyServer(); - -exports = module.exports = function (target, options, prefix) { - let apiPath = options.proxyTo || '/api'; - - if(apiPath.charAt(0) !== '/') { - apiPath = '/' + apiPath; - } - - if(prefix) { - target = baseDomain(options.proxy) + prefix.substr(1); - } - - const re = pathtoRegexp(apiPath, [], { - end: false - }); - - function updateUrl(request) { - request.originalUrl = request.originalUrl || request.url; - request.url = request.url.replace(apiPath, ''); - } - - return function(req, res, next) { - if(!re.test(req.url)) { - next(); - return; - } - - let [request, response] = httponeify(req, res); - updateUrl(request); - - proxy.web(request, response, { - target: target, - changeOrigin: true, - secure: options.proxyCertCheck - }, next); - }; -}; - -exports.ws = function(options, server) { - let target = baseDomain(options.proxy); - - server.on('upgrade', function(req,res) { - proxy.ws(req, res, { - target - }); - }, logError); -}; - -function logError(err) { - console.error(err); -} - -function httponeify(req, res) { - if(isHTTP1(req)) { - return [req, res]; - } - - let headers = Object.create(null); - for(let [key, value] of Object.entries(req.headers)) { - if(key.startsWith(":")) { - continue; - } - headers[key] = value; - } - let proxyableRequest = Object.create(req, { - headers: { - enumerable: true, - value: headers - } - }); - - let outHeaders = Object.create(null); - - let proxyableResponse = Object.create(res, { - writeHead: { - value: function(status, headers) { - let finalHeaders = Object.assign(outHeaders, headers); - deleteBannedHeaders(finalHeaders); - Reflect.apply(res.writeHead, this, [status, finalHeaders]); - } - }, - setHeader: { - value: function(key, value) { - Reflect.set(outHeaders, key, value); - } - }, - // This prevents a warning - statusMessage: { - get: Function.prototype, - set: Function.prototype - } - }); - - return [proxyableRequest, proxyableResponse]; -} - -const bannedHeaders = [ - "connection", - "transfer-encoding" -]; - -function deleteBannedHeaders(headers) { - bannedHeaders.forEach(name => { - Reflect.deleteProperty(headers, name); - }); -} - -function baseDomain(proxy){ - var parsed = url.parse(proxy); - parsed.pathname = parsed.path = '/'; - return url.format(parsed); -} diff --git a/lib/middleware/ssr.js b/lib/middleware/ssr.js deleted file mode 100644 index 7b1cf07..0000000 --- a/lib/middleware/ssr.js +++ /dev/null @@ -1,33 +0,0 @@ -const os = require("os"); -const path = require("path"); -const ssr = require("done-ssr"); - -module.exports = function(stealConfig, options) { - let steal = stealConfig || {}; - let pkgPath = path.join(path.dirname(steal.config), 'package.json'); - let pkg = require(pkgPath); - - // Default to using the npm plugin - if(!steal.config) { - steal.config = pkgPath + '!npm'; - } - // liveReload is off by default. - steal.liveReload = !!steal.liveReload; - steal.liveReloadAttempts = steal.liveReloadAttempts || 3; - steal.liveReloadHost = os.hostname(); - - // In production we need to pass in the main, otherwise it doesn't know what - // bundle to load from. - if(process.env.NODE_ENV === 'production' && !steal.main) { - steal.main = (pkg.system && pkg.system.main) || - (pkg.steal && pkg.steal.main) || pkg.main; - } - - let render = ssr(steal, options); - - return function(req, res, next) { - let stream = render(req); - stream.on("error", next); - stream.pipe(res); - }; -}; diff --git a/lib/middleware/static-errorpage.js b/lib/middleware/static-errorpage.js deleted file mode 100644 index 0b36fe4..0000000 --- a/lib/middleware/static-errorpage.js +++ /dev/null @@ -1,13 +0,0 @@ -const fs = require("fs"); -const path = require("path"); - -module.exports = function(options) { - let filename = path.join(process.cwd(), options.errorPage); - - return function(req, res) { - res.writeHead(200, { - "content-type": "text/html" - }); - fs.createReadStream(filename).pipe(res); - }; -}; diff --git a/lib/middleware/static-pushstate.js b/lib/middleware/static-pushstate.js deleted file mode 100644 index e172639..0000000 --- a/lib/middleware/static-pushstate.js +++ /dev/null @@ -1,24 +0,0 @@ -const path = require("path"); -const fs = require("fs"); - -module.exports = function(options) { - return function(req, res, next) { - var urlParts = path.parse(req.url); - var isPushstateRoute = !urlParts.ext || urlParts.name.includes('?'); - if (isPushstateRoute) { - var env = process.env.NODE_ENV || 'development'; - var htmlPath = path.join(options.path, './' + env + '.html'); - if (!fs.existsSync(htmlPath)) { - htmlPath = path.join(options.path, './production.html'); - } - if (fs.existsSync(htmlPath)) { - res.writeHead(200, { - "content-type": "text/html" - }); - fs.createReadStream(htmlPath).pipe(res); - return; - } - } - return next(); - }; -}; diff --git a/lib/proto/h1.js b/lib/proto/h1.js deleted file mode 100644 index b6d4a83..0000000 --- a/lib/proto/h1.js +++ /dev/null @@ -1,5 +0,0 @@ -const { ServerResponse } = require("http"); -const addons = require("./response"); - -const res = Object.create(ServerResponse.prototype, addons); -module.exports = res; diff --git a/lib/proto/h2.js b/lib/proto/h2.js deleted file mode 100644 index e5b56d4..0000000 --- a/lib/proto/h2.js +++ /dev/null @@ -1,6 +0,0 @@ -const { Http2ServerResponse } = require("http2"); -const addons = require("./response"); - -const res = Object.create(Http2ServerResponse.prototype, addons); - -module.exports = res; diff --git a/lib/proto/response.js b/lib/proto/response.js deleted file mode 100644 index b94dbbe..0000000 --- a/lib/proto/response.js +++ /dev/null @@ -1,92 +0,0 @@ -const cookie = require("cookie"); -const mime = require("send").mime; -const sign = require('cookie-signature').sign; -const charsetRegExp = /;\s*charset\s*=/; - -function header(field, val) { - if(arguments.length === 2) { - var value = Array.isArray(val) ? - val.map(String) : - String(val); - - // add charset to content-type - if (field.toLowerCase() === 'content-type') { - if (Array.isArray(value)) { - throw new TypeError('Content-Type cannot be set to an Array'); - } - if (!charsetRegExp.test(value)) { - var charset = mime.charsets.lookup(value.split(';')[0]); - if (charset) { - value += '; charset=' + charset.toLowerCase(); - } - } - } - - this.setHeader(field, value); - } else { - for (var key in field) { - this.set(key, field[key]); - } - } - return this; -} - -module.exports = { - headers: { - enumerable: false, - value: header - }, - set: { - enumerable: false, - value: header - }, - append: { - enumerable: false, - value: function(field, val) { - var prev = this.getHeader(field); - var value = val; - - if (prev) { - // concat the new and prev vals - value = Array.isArray(prev) ? prev.concat(val) - : Array.isArray(val) ? [prev].concat(val) - : [prev, val]; - } - - return this.set(field, value); - }, - }, - cookie: { - enumerable: false, - value: function(name, value, options) { - var opts = Object.assign({}, options); - var secret = this.req && this.req.secret; - var signed = opts.signed; - - if (signed && !secret) { - throw new Error('cookieParser("secret") required for signed cookies'); - } - - var val = typeof value === 'object' ? - 'j:' + JSON.stringify(value) : - String(value); - - if (signed) { - val = 's:' + sign(val, secret); - } - - if ('maxAge' in opts) { - opts.expires = new Date(Date.now() + opts.maxAge); - opts.maxAge /= 1000; - } - - if (opts.path == null) { - opts.path = '/'; - } - - this.append("Set-Cookie", cookie.serialize(name, String(val), opts)); - - return this; - } - } -}; diff --git a/lib/proxy.js b/lib/proxy.js new file mode 100644 index 0000000..75095f7 --- /dev/null +++ b/lib/proxy.js @@ -0,0 +1,48 @@ +var httpProxy = require('http-proxy'); +var url = require('url'); +var proxy = httpProxy.createProxyServer(); + +module.exports = function (app, options) { + var apiPath = options.proxyTo || '/api'; + var oldListen = app.listen; + var middleware = function(target) { + return function(req, res) { + proxy.web(req, res, { + target: target, + changeOrigin: true, + secure: options.proxyCertCheck + }, logError); + }; + }; + + if(apiPath.charAt(0) !== '/') { + apiPath = '/' + apiPath; + } + + app.use(apiPath, middleware(options.proxy)); + + app.use('/socket.io/', middleware(baseDomain(options.proxy) + 'socket.io/')); + + + app.listen = function() { + var server = oldListen.apply(this, arguments); + + server.on('upgrade', function(req,res){ + proxy.ws(req, res, { + target: baseDomain(options.proxy) + }); + }, logError); + + return server; + }; +}; + +function logError(err) { + console.error(err); +} + +function baseDomain(proxy){ + var parsed = url.parse(proxy); + parsed.pathname = parsed.path = '/'; + return url.format(parsed); +} diff --git a/lib/servers.js b/lib/servers.js deleted file mode 100644 index 6bf9313..0000000 --- a/lib/servers.js +++ /dev/null @@ -1,94 +0,0 @@ -const proxy = require("./middleware/proxy"); -const errorHandler = require("./middleware/error"); -const fs = require("fs"); -const {markHTTP1} = require("./http1"); - -exports.create = function(port, options, app) { - let servers = []; - let handleErrors = errorHandler(options); - - // If using TLS, set up an HTTP2 server with automatic - // http->https forwarding. - if(options.key && options.cert) { - let net = require("net"); - let h2 = require("http2"); - let responseProto = require("./proto/h2"); - - port = Number(port); - let httpPort = port + 1; - let httpsPort = httpPort + 1; - - let h2Server = h2.createSecureServer({ - key: fs.readFileSync(options.key), - cert: fs.readFileSync(options.cert) - }); - - h2Server.on("request", function(request, response) { - Object.setPrototypeOf(response, responseProto); - app(request, response, handleErrors); - }); - - if(options.proxy) { - proxy.ws(options, h2Server); - } - - h2Server.listen(httpsPort); - servers.push(h2Server); - - let httpServer = require("http").createServer(function(req, res){ - var host = req.headers.host; - res.writeHead(301, { "Location": "https://" + host + req.url }); - res.end(); - }); - httpServer.listen(httpPort); - - // This is a TCP server that forwards to the correct port for - // http or https - let tcpServer = net.createServer(function(conn){ - conn.once("data", function (buf) { - // A TLS handshake record starts with byte 22. - var address = (buf[0] === 22) ? httpsPort : httpPort; - var proxy = net.createConnection(address, function (){ - proxy.write(buf); - conn.pipe(proxy).pipe(conn); - }); - }); - }); - tcpServer.listen(port); - - servers.push(httpServer); - - // When the main server is closed, also close the HTTP and TCP servers. - let _close = h2Server.close; - h2Server.close = function(cb){ - let closed = 0; - let onClosed = function() { - closed++; - if(closed === 3 && cb) { - cb.apply(this, arguments); - } - }; - - _close.call(this, onClosed); - httpServer.close(onClosed); - tcpServer.close(onClosed); - }; - } else { - let responseProto = require("./proto/h1"); - let server = require("http").createServer(function(request, response) { - markHTTP1(request); - Object.setPrototypeOf(response, responseProto); - app(request, response, handleErrors); - }); - - if(options.proxy) { - proxy.ws(options, server); - } - - server.listen(port); - - servers.push(server); - } - - return servers; -}; diff --git a/lib/stack.js b/lib/stack.js deleted file mode 100644 index 743aeb9..0000000 --- a/lib/stack.js +++ /dev/null @@ -1,26 +0,0 @@ - -module.exports = function(layers) { - let stack = core; - - layers.reverse().forEach(function(layer) { - let child = stack; - stack = function(a, b, next) { - try { - layer(a, b, function(err) { - if(err) { - return next(err, a, b); - } - child(a, b, next); - }); - } catch(err) { - next(err, a, b); - } - }; - }); - - return stack; -}; - -function core(a, b, next) { - next(); -} diff --git a/package.json b/package.json index cb17784..f7bc4ab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "done-serve", - "version": "3.0.0-pre.1", + "version": "2.3.0", "description": "DoneJS development server", "main": "lib/index.js", "directories": { @@ -29,33 +29,30 @@ }, "homepage": "https://github.com/donejs/done-serve#readme", "dependencies": { - "chalk": "^2.4.1", "commander": "^2.8.1", "compression": "^1.6.1", - "cookie": "^0.3.1", - "cookie-signature": "^1.1.0", "debug": "^2.6.3", - "done-ssr": "^3.0.0-pre.3", + "done-ssr-middleware": "^2.0.0", "donejs-error-format": "^1.2.0", + "donejs-spdy": "^3.4.7", + "express": "^4.13.4", "http-proxy": "^1.13.2", "kill-on-exit": "^1.2.0", - "path-to-regexp": "^2.4.0", - "send": "^0.16.2", - "serve-index": "^1.9.1", - "serve-static": "^1.13.2" + "serve-index": "^1.9.1" }, "devDependencies": { "can-component": "^4.0.0", - "can-define": "^2.0.0", "can-event": "^3.7.4", + "can-define": "^2.0.0", "can-route": "^4.0.0", - "can-route-pushstate": "^4.0.0", + "can-route-pushstate": "^5.0.6", "copy-dir": "0.0.8", "done-autorender": "^2.0.0", "is-ci": "^1.0.10", "jquery": "2.x - 3.x", "jshint": "^2.9.5", "nock": "^9.0.11", + "request": "^2.69.0", "socket.io": "^2.1.1", "socket.io-client": "^2.1.1", "spawn-mochas": "^1.1.0", diff --git a/test/cli_test.js b/test/cli_test.js index 5ae4d31..3e4ef26 100644 --- a/test/cli_test.js +++ b/test/cli_test.js @@ -9,7 +9,7 @@ function node(args){ } function serverExpects(opts){ - var server = td.replace("../lib/app"); + var server = td.replace("../lib/index"); td.when(server(td.matchers.contains(opts))) .thenReturn({ listen: function(){ @@ -107,9 +107,9 @@ describe("done-serve cli", function(){ cli.run(); }); - + it("Sets the NODE_ENV to development", function() { - cli.program.parse(node(["--develop"])); + cli.program.parse(node(["--develop"])); cli.run(); assert(process.env.NODE_ENV === "development"); }); diff --git a/test/config/cert.pem b/test/config/cert.pem deleted file mode 100644 index 37f021c..0000000 --- a/test/config/cert.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEpDCCAowCCQCtKfnPII/tyDANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls -b2NhbGhvc3QwHhcNMTgwOTA1MTUyNTU2WhcNMTkwOTA1MTUyNTU2WjAUMRIwEAYD -VQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDL -sVYzbGju4o6RORY7XfGZPO94sllxsVh8x8ettCINHsuOE2WcL+UAUvh1VG4mgpJA -UTcbsFHvlbP8QzOIniqOoZrA4G2Ixkdag3YiB4iB2jFDgxLe/8xmdkdsH6JGjxgs -yO2RAs2r0+5nVadeAUH/8yLAZlxC0ERJc3ybrpYoShJF1euYueK7CyOqDhigdHG+ -kSF8nILCJ06Zaqd9qcx+n9JzrREnXAVVWOVUyB3H0wiTQB+5NOUvCp92upEW30Cg -/pUNHfkahH/81Y8jJdfJ86rAL3VJYvlycxodfZ9jsit/HWNbzOnSrMuRh65eksSm -h47wEG09MkjCppeMcvk1v6/S2iKbaiR0mQ/XAcw0vck97Qi1XQ+TE/FLl0YoeSDF -soAJxFrl7fbuehtb2o8flDupToKkfjvognrZa3YeFpXZDCkPG4XeHrZ9J4RdeyG4 -ABrIB0UZoE14jvX8A5q1re4juqZ19gogu4hpMbBWyf62evsjhsJXMGxEreDFBb/T -EVRV0KjQyNCdiFA9UjcYEEvhrFQ4cW6Ayk/Z0iWl6Y/Fm13tYYxMyik+Z4pXk/Cm -Ud8COVfGEimYF5kKr2FRe1X5c8BOKRgys8YdFfEgUB/cgEzH9JlxD457sUQdCMeh -4F1nQsT5zFWR6C58Swzyhtb009gIoHB0rOgHwS04ZQIDAQABMA0GCSqGSIb3DQEB -CwUAA4ICAQCRby3IlrS5+cm0kSk/EtlqrNw4mUxkGHS1XOXL0HuyOLRbqRPar7kM -OWAiZl5L+t14nXSXnion1sRUg/AVRNsS+R1xkZzLHNsC+Ht7cMwvwb76fz5fMuxp -K3UNImEiAe7FFJ4GKqMXQfnfimmSYZQ7VYOZT8Likkvqsvb/d4n8/rBYoH5xgyW8 -l8Ls9WjVILQvLQYkeBwsnoj78KeEVUtuqQez8E/paxb2u4XdFXh60rPmXm/UPD4A -WfY/pmUPnKrSgfLGvJIy+9WRY/l5bx8aVDrA/87RyPuz1Bi3Rqe3VkoF3qGooyuF -p3qy4MVxyi/RmMCFLi/KlRrqVGhTm6tsULSEXINfYp9BdF76bPTnuf/lB6b5RupA -gJawhCkGAktFbj2CqZbxe7GuqWu5EFhsieVMSOahN1Ll+D/siz7SxDrhk10pamnK -2V22IXihVxaWaeEwExXeaa9BnJIymcPTFsib8+PuybwsrhX7Nrf7W7UMKFOiOCOn -KvMaoFWdWu25fNEUOEv4dQ4z9lwnIJrLPj2PqBAKJpB1bZgpUSGMuMdotfqvsmP6 -Xj3JuOqiw7cioH/ZujhebDvopTpTxOxQiBr8dkxcaeA6fZ8lHVSI/ObJRiSOEAyD -pm5/bhOJaGMQBvU/riFedBcTx/qMTc/OmFyiJeQ0Tioa4fXfOAhNcQ== ------END CERTIFICATE----- diff --git a/test/config/key.pem b/test/config/key.pem deleted file mode 100644 index b9d4180..0000000 --- a/test/config/key.pem +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -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 -A01XBP/7FvYlxJxpnbRsLgp237Qe8CE= ------END PRIVATE KEY----- diff --git a/test/cookie_server_test.js b/test/cookie_server_test.js index 1fce4ee..291454b 100644 --- a/test/cookie_server_test.js +++ b/test/cookie_server_test.js @@ -1,51 +1,46 @@ -// jshint ignore: start -const assert = require("assert"); -const helpers = require("./helpers"); -const path = require('path'); -const nock = require("nock"); -const serve = require('../lib/index'); - -runTests(helpers.modes.H2); - -function runTests(mode) { - const request = helpers.makeRequest(mode); - const createServerOptions = helpers.makeCreateServerOptions(mode); - - describe("done-serve cookie_server - " + mode, function() { - this.timeout(10000); - - var scope; - var server; - - before(function(done) { - server = serve(5050, createServerOptions({ - path: path.join(__dirname, 'tests'), - main: "cookie/index.stache!done-autorender" - })); - - scope = nock("http://www.example.org").get( "/session" ).delay( 20 ).reply( - function ( uri, requestBody ) { - return [ - 200, - "request body", - { "set-cookie": "ajaxResDurringSSR=setsACookie" } - ]; - } - ); - - server.on('listening', done); - }); +var assert = require('assert'); +var path = require('path'); +var request = require('request'); +var nock = require( "nock" ); + +var serve = require('../lib/index'); + +describe("done-serve cookie_server", function() { + this.timeout(10000); + + var scope; + var server; + + before(function(done) { + server = serve({ + path: path.join(__dirname, 'tests'), + main: "cookie/index.stache!done-autorender" + }).listen(5050); + + scope = nock("http://www.example.org").get( "/session" ).delay( 20 ).reply( + function ( uri, requestBody ) { + return [ + 200, + "request body", + { "set-cookie": "ajaxResDurringSSR=setsACookie" } + ]; + } + ); + + server.on('listening', done); + }); - after(function(done) { - nock.restore(); - server.close(done); - }); + after(function(done) { + nock.restore(); + server.close(done); + }); - it('starts SSR with package.json settings and outputs page with 200 status', async function() { - let [err, res] = await request('http://localhost:5050'); - let cookie = res.headers["set-cookie"]; - assert.equal(cookie[0], "newCookieKey=newCookieValue; Path=/"); - assert.equal(cookie[1], "ajaxResDurringSSR=setsACookie; Path=/"); + it.only('starts SSR with package.json settings and outputs page with 200 status', function(done) { + var j = request.jar(); + request({ url: 'http://localhost:5050', jar: j }, function(err, res, body) { + var cookie_string = j.getCookieString( "http://localhost:5050/" ); + assert.equal(cookie_string, "newCookieKey=newCookieValue; ajaxResDurringSSR=setsACookie", "Cookies created from ajax response during SSR are forwarded to the initial ssr response."); + done(); }); }); -} +}); diff --git a/test/helpers.js b/test/helpers.js deleted file mode 100644 index 5cca8ca..0000000 --- a/test/helpers.js +++ /dev/null @@ -1,120 +0,0 @@ -/* jshint -W079 */ -const fs = require("fs"); -const path = require("path"); -const {URL} = require("url"); - -function makeExpectation(name) { - return function(expr) { - var count = 0; - var old = console[name]; - console[name] = function(err) { - if(expr) { - if(err && expr.test(err.toString())) { - count++; - } - } else { - count++; - } - }; - - return function() { - console[name] = old; - return count; - }; - }; -} - -exports.willError = makeExpectation('error'); - -exports.makeCreateServerOptions = function(mode) { - return function(options) { - if(mode === "HTTP/2") { - return Object.assign(options, { - key: path.join(__dirname, "config", "key.pem"), - cert: path.join(__dirname, "config", "cert.pem") - }); - } - return options; - }; -}; - -exports.makeRequest = function(mode) { - return function(url, callback) { - let options = {}; - if(typeof url === "object") { - options = url; - url = options.url; - } - - let urlObj = new URL(url); - - if(mode === "HTTP/2") { - return makeH2Request(urlObj, options); - } else { - return makeH1Request(urlObj, options); - } - }; -}; - -function makeH2Request(urlObj, options) { - urlObj.protocol = "https:"; - - let pth = urlObj.pathname + urlObj.search; - urlObj.pathname = ""; - - let h2 = require("http2"); - let error = null; - let response = {body: ''}; - - let client = h2.connect(urlObj.toString(), { - ca: fs.readFileSync(path.join(__dirname, "config", "cert.pem")) - }); - - return new Promise((resolve) => { - client.on("error", err => { - error = err; - }); - - let headers = options.headers || {}; - headers[":path"] = pth; - const req = client.request(headers); - - req.on("response", (headers) => { - response.statusCode = headers[":status"]; - response.headers = headers; - }); - - req.on("data", chunk => { response.body += chunk; }); - - req.on("end", () => { - client.close(); - resolve([error, response]); - }); - }); -} - -function makeH1Request(urlObj, options) { - const http = require("http"); - let response = {body: ""}; - - return new Promise(resolve => { - http.get(urlObj.toString(), res => { - response.statusCode = res.statusCode; - response.headers = res.headers; - - res.setEncoding("utf8"); - res.on("data", chunk => { response.body += chunk; }); - res.on("end", () => { - resolve([null, response]); - }); - }) - .on("error", error => { - resolve([error]); - }); - }); -} - -exports.modes = { - H1: "HTTP/1", - H2: "HTTP/2" -}; diff --git a/test/server_path_test.js b/test/server_path_test.js index e1e88a8..d3c9c34 100644 --- a/test/server_path_test.js +++ b/test/server_path_test.js @@ -1,81 +1,75 @@ -// jshint ignore: start var assert = require('assert'); var path = require('path'); -const helpers = require("./helpers"); var http = require('http'); var request = require('request'); var socketio = require('socket.io'); var socketClient = require('socket.io-client'); + var serve = require('../lib/index'); -runTests(helpers.modes.H1); +describe('done-serve server_path', function() { + this.timeout(10000); -function runTests(mode) { - const request = helpers.makeRequest(mode); - const createServerOptions = helpers.makeCreateServerOptions(mode); + var server, other, io; - describe('done-serve server_path - ' + mode, function() { - this.timeout(10000); + before(function(done) { + server = serve({ + path: path.join(__dirname, 'tests'), + proxy: 'http://localhost:6060/api', + }).listen(5050); - var server, other, io; + other = http.createServer(function(req, res) { + res.writeHead(200, {'Content-Type': 'text/plain'}); + res.end('Other server\n'); + }).listen(6060); - before(function(done) { - server = serve(5050, { - path: path.join(__dirname, 'tests'), - proxy: 'http://localhost:6060/api', - }); + io = socketio().listen(other); - other = http.createServer(function(req, res) { - res.writeHead(200, {'Content-Type': 'text/plain'}); - res.end('Other server\n'); - }).listen(6060); + server.on('listening', done); + }); - io = socketio().listen(other); + after(function(done) { + server.close(done); + }); - server.on('listening', done); + it('proxies to other servers on a path', function(done) { + request('http://localhost:5050/api/', function(err, res, body) { + assert.equal(body, 'Other server\n', 'Got message from other server'); + done(); }); + }); - after(function(done) { - server.close(() => other.close(done)); + describe('proxying socket.io websockets', function(){ + beforeEach(function(){ + this.oldDocument = global.document; + delete global.document; }); - it('proxies to other servers on a path', async function() { - let [err, res] = await request('http://localhost:5050/api/'); - assert.equal(res.body, 'Other server\n', 'Got message from other server'); + afterEach(function(){ + global.document = this.document; }); - describe.skip('proxying socket.io websockets', function(){ - beforeEach(function(){ - this.oldDocument = global.document; - delete global.document; - }); + it('proxies Socket.io websockets', function(done) { + var original = { hello: 'world' }; - afterEach(function(){ - global.document = this.document; + io.on('connection', function (socket) { + socket.emit('news', original); }); - it('proxies Socket.io websockets', function(done) { - const expected = { hello: 'world' }; + var socket = socketClient('http://localhost:5050'); - io.on('connection', function (socket) { - socket.emit('news', original); - }); - - var socket = socketClient('http://localhost:5050'); - - socket.on('news', function(data) { - assert.deepEqual(data, expected); - socket.disconnect(); - }); - - socket.on('disconnect', function() { - // Timeout for Socket.io cleanup on slower machiens (like CI) finish - setTimeout(function() { - done(); - }, 500); - }); + socket.on('news', function(data) { + assert.deepEqual(data, original); + socket.disconnect(); }); + socket.on('disconnect', function() { + // Timeout for Socket.io cleanup on slower machiens (like CI) finish + setTimeout(function() { + done(); + }, 500); + }); }); + }); -} +}); diff --git a/test/server_test.js b/test/server_test.js index 5cd2c70..a9ee7e5 100644 --- a/test/server_test.js +++ b/test/server_test.js @@ -1,252 +1,223 @@ -// jshint ignore: start var assert = require('assert'); var path = require('path'); -var helpers = require('./helpers'); var http = require('http'); +var request = require('request'); var socketio = require('socket.io'); var socketClient = require('socket.io-client'); var serve = require('../lib/index'); -// Run the tests in both http and http2 -runTests("HTTP/2"); -runTests("HTTP/1"); +describe('done-serve server', function() { + this.timeout(10000); -function runTests(mode) { - const request = helpers.makeRequest(mode); - const createServerOptions = helpers.makeCreateServerOptions(mode); + var server, other, io; - describe('done-serve server - ' + mode, function() { - this.timeout(10000); + before(function(done) { + server = serve({ + path: path.join(__dirname, 'tests'), + proxy: 'http://localhost:6060', + proxyTo: 'testing', + logErrors: false, + liveReload: true + }).listen(5050); - var server, other, io; + other = http.createServer(function(req, res) { + res.writeHead(200, {'Content-Type': 'text/plain'}); + res.end('Other server\n'); + }).listen(6060); - before(function(done) { - server = serve(5050, createServerOptions({ - path: path.join(__dirname, 'tests'), - proxy: 'http://localhost:6060', - proxyTo: 'testing', - logErrors: false, - liveReload: true - })); + io = socketio().listen(other); - other = http.createServer(function(req, res) { - if(req.url === '/stuff.ndjson') { - res.writeHead(200, {'Content-Type': 'application/x-ndjson'}); - res.write('{"row": "one"}\n'); - res.write('{"row": "two"}'); - res.end(); - } else { - res.writeHead(200, {'Content-Type': 'text/plain'}); - res.end('Other server\n'); - } - }).listen(6060); - - io = socketio().listen(other); - - server.on('listening', done); - }); + server.on('listening', done); + }); - after(function(done) { - server.close(function(){ - other.close(done); - }); - }); + after(function(done) { + server.close(done); + }); - it('starts SSR with package.json settings and outputs page with 200 status', async function() { - let [err, res] = await request('http://localhost:5050'); + it('starts SSR with package.json settings and outputs page with 200 status', function(done) { + request('http://localhost:5050', function(err, res, body) { assert.equal(res.statusCode, 200); - assert.ok(/You are home/.test(res.body), 'Got body'); + assert.ok(/You are home/.test(body), 'Got body'); + done(); }); + }); - it('route errors send 404 status', async function() { - let [err, res] = await request('http://localhost:5050/invalid/route'); + it('route errors send 404 status', function(done) { + request('http://localhost:5050/invalid/route', function(err, res, body) { assert.equal(res.statusCode, 404); - assert.ok(/Error: Not found/.test(res.body), 'Got body'); + assert.ok(/Error: Not found/.test(body), 'Got body'); + done(); }); + }); - it('proxies to other servers on a path', async function() { - let [err, res] = await request('http://localhost:5050/testing/'); - assert.equal(res.body, 'Other server\n', 'Got message from other server'); + it('proxies to other servers on a path', function(done) { + request('http://localhost:5050/testing/', function(err, res, body) { + assert.equal(body, 'Other server\n', 'Got message from other server'); + done(); }); + }); - it('proxies Socket.io websockets', function(done) { - var original = { hello: 'world' }; - var oldDocument = global.document; + it('proxies Socket.io websockets', function(done) { + var original = { hello: 'world' }; + var oldDocument = global.document; - // socket.io-client doesn't like our document shim but we don't need it for this test - // See https://github.com/socketio/socket.io-client/issues/916 - delete global.document; + // socket.io-client doesn't like our document shim but we don't need it for this test + // See https://github.com/socketio/socket.io-client/issues/916 + delete global.document; - io.on('connection', function (socket) { - socket.emit('news', original); - }); + io.on('connection', function (socket) { + socket.emit('news', original); + }); - var socket = socketClient('http://localhost:6060'); + var socket = socketClient('http://localhost:6060'); - socket.on('news', function(data) { - assert.deepEqual(data, original); - socket.disconnect(); - }); + socket.on('news', function(data) { + assert.deepEqual(data, original); + socket.disconnect(); + }); - socket.on('disconnect', function() { - // Timeout for Socket.io cleanup on slower machiens (like CI) finish - setTimeout(function() { - global.document = oldDocument; - done(); - }, 500); - }); + socket.on('disconnect', function() { + // Timeout for Socket.io cleanup on slower machiens (like CI) finish + setTimeout(function() { + global.document = oldDocument; + done(); + }, 500); }); + }); - it('server should parse URL parameters (#52)', async function() { - let [err, res] = await request('http://localhost:5050/test?param=paramtest') + it('server should parse URL parameters (#52)', function(done) { + request('http://localhost:5050/test?param=paramtest', function(err, res, body) { assert.equal(res.statusCode, 200); - assert.ok(/paramtest/.test(res.body), 'Param printed in body'); + assert.ok(/paramtest/.test(body), 'Param printed in body'); + done(); }); + }); - it('errors when rendering an app trigger Express error handler (#58)', async function() { - let [err, res] = await request('http://localhost:5050/?err=true') + it('errors when rendering an app trigger Express error handler (#58)',function(done) { + request('http://localhost:5050/?err=true', function(err, res, body) { assert.equal(res.statusCode, 500); - assert.ok(/Something went wrong/.test(res.body), 'Got error message'); + assert.ok(/Something went wrong/.test(body), 'Got error message'); + done(); }); + }); - it('Error page connects to live-reload', async function() { - let [err, res] = await request('http://localhost:5050/?err=true'); - assert.ok(/id="live-reload"/.test(res.body), "live-reload script included"); + it('Error page connects to live-reload',function(done) { + request('http://localhost:5050/?err=true', function(err, res, body) { + assert.ok(/id="live-reload"/.test(body), "live-reload script included"); + done(); }); + }); - it('can serve only static content', function(done) { - var server = serve(8889, createServerOptions({ - path: path.join(__dirname), - static: true - })); + it('can serve only static content', function(done) { + var server = serve({ + path: path.join(__dirname), + static: true + }).listen(8889); - server.on('listening', async function() { - let [err, res] = await request('http://localhost:8889/server_test.js'); + server.on('listening', function() { + request('http://localhost:8889/server_test.js', function(err, res, body) { assert.ok(res.statusCode === 200); server.close(done); }); }); + }); - it('shows a nice 404 message when in static mode', function(done) { - var server = serve(8889, createServerOptions({ - path: path.join(__dirname), - static: true - })); - - var undo = helpers.willError(/404/); - - server.on('listening', async function() { - let [err, res] = await request('http://localhost:8889/not-exists'); - assert.equal(undo(), 1, "There was a 404 message"); - server.close(done); - }); - }); - - it('serves development.html when there\'s no index.html and NODE_ENV is not set', function(done) { - var server = serve(8889, createServerOptions({ - path: path.join(__dirname, 'tests', 'pushstate'), - static: true - })); + it('serves development.html when there\'s no index.html and NODE_ENV is not set', function(done) { + var server = serve({ + path: path.join(__dirname, 'tests', 'pushstate'), + static: true + }).listen(8889); - server.on('listening', async function() { - let [err, res] = await request('http://localhost:8889'); - assert(res.body === 'Development'); + server.on('listening', function() { + request('http://localhost:8889', function(err, res, body) { + assert(body === 'Development'); assert.ok(res.statusCode === 200); server.close(done); }); }); + }); - it('serves production.html when NODE_ENV is not development', function(done) { - process.env.NODE_ENV = 'ci'; - var server = serve(8889, createServerOptions({ - path: path.join(__dirname, 'tests', 'pushstate'), - static: true - })); + it('serves production.html when NODE_ENV is not development', function(done) { + process.env.NODE_ENV = 'ci'; + var server = serve({ + path: path.join(__dirname, 'tests', 'pushstate'), + static: true + }).listen(8889); - server.on('listening', async function() { - let [err, res] = await request('http://localhost:8889'); - assert(res.body === 'Production'); + server.on('listening', function() { + request('http://localhost:8889', function(err, res, body) { + assert(body === 'Production'); assert.ok(res.statusCode === 200); delete process.env.NODE_ENV; server.close(done); }); }); + }); - it('serves qa.html when NODE_ENV is qa', function(done) { - process.env.NODE_ENV = 'qa'; - var server = serve(8889, createServerOptions({ - path: path.join(__dirname, 'tests', 'pushstate'), - static: true - })); + it('serves qa.html when NODE_ENV is qa', function(done) { + process.env.NODE_ENV = 'qa'; + var server = serve({ + path: path.join(__dirname, 'tests', 'pushstate'), + static: true + }).listen(8889); - server.on('listening', async function() { - let [err, res] = await request('http://localhost:8889'); - assert(res.body === 'QA'); + server.on('listening', function() { + request('http://localhost:8889', function(err, res, body) { + assert(body === 'QA'); assert.ok(res.statusCode === 200); delete process.env.NODE_ENV; server.close(done); }); }); + }); - it('serves development.html for a non-matched static route (pushstate route)', function(done) { - var server = serve(8889, createServerOptions({ - path: path.join(__dirname, 'tests', 'pushstate'), - static: true - })); + it('serves development.html for a non-matched static route (pushstate route)', function(done) { + var server = serve({ + path: path.join(__dirname, 'tests', 'pushstate'), + static: true + }).listen(8889); - server.on('listening', async function() { - let [err, res] = await request('http://localhost:8889/users'); - assert(res.body === 'Development'); + server.on('listening', function() { + request('http://localhost:8889/users', function(err, res, body) { + assert(body === 'Development'); assert.ok(res.statusCode === 200); server.close(done); }); }); + }); - it('serves a custom error page in static mode', function(done) { - var server = serve(8891, createServerOptions({ - path: path.join(__dirname), - static: true, - errorPage: path.join('test', 'tests', 'error-page.html') - })); + it('serves a custom error page in static mode', function(done) { + var server = serve({ + path: path.join(__dirname), + static: true, + errorPage: path.join('test', 'tests', 'error-page.html') + }).listen(8891); - server.on('listening', async function() { - let [err, res] = await request('http://localhost:8891/not-a-real-page'); + server.on('listening', function() { + request('http://localhost:8891/not-a-real-page', function(err, res, body) { assert.ok(res.statusCode === 200); - assert.equal(res.body, 'This is the error page!'); + assert.equal(body, 'This is the error page!'); server.close(done); }); }); + }); - it('serves a directory listing in static mode', function(done) { - var server = serve(8891, createServerOptions({ - path: path.join(__dirname), - static: true, - })); + it('serves a directory listing in static mode', function(done) { + var server = serve({ + path: path.join(__dirname), + static: true, + }).listen(8891); - server.on('listening', async function() { - let [err, res] = await request('http://localhost:8891/'); + server.on('listening', function() { + request('http://localhost:8891/', function(err, res, body) { assert.ok(res.statusCode === 200); - assert.ok(/server_test\.js/.test(res.body), 'Got body'); - server.close(done); - }); - }); - - it('does not compress application/x-ndjson', async function() { - var options = { - url: 'http://localhost:5050/testing/stuff.ndjson', - headers: { - 'accept': '*/*', - 'accept-encoding': 'gzip, deflate, br' - } - }; - let [err, res] = await request(options); + assert.ok(/server_test\.js/.test(body), 'Got body'); - var h = res.headers; - assert.equal(h['content-type'], 'application/x-ndjson', 'Set from the proxy'); - assert.equal(h['content-encoding'], undefined, 'gzip not set'); + server.close(done); + }); }); - }); -} + +}); diff --git a/test/tests/progressive/appstate.js b/test/tests/progressive/appstate.js index a86267d..fae121c 100644 --- a/test/tests/progressive/appstate.js +++ b/test/tests/progressive/appstate.js @@ -1,7 +1,6 @@ var DefineMap = require("can-define/map/map"); module.exports = DefineMap.extend({ - page: "string", param: "string", err: "boolean", statusMessage: { diff --git a/test/tests/timeout/app.js b/test/tests/timeout/app.js index a754309..3a6bb2e 100644 --- a/test/tests/timeout/app.js +++ b/test/tests/timeout/app.js @@ -20,4 +20,4 @@ module.exports = DefineMap.extend({ } }); -route.register("{page}"); +route("{page}"); diff --git a/test/timeout_test.js b/test/timeout_test.js index fbbd6ed..abbe159 100644 --- a/test/timeout_test.js +++ b/test/timeout_test.js @@ -1,53 +1,47 @@ -// jshint ignore: start var assert = require("assert"); -var helpers = require("./helpers"); var path = require("path"); var request = require("request"); var isCI = require("is-ci"); var serve = require("../lib/index"); -runTests(helpers.modes.H1); -runTests(helpers.modes.H2); +describe("done-serve timeout", function() { + this.timeout(10000); -function runTests(mode) { - const request = helpers.makeRequest(mode); - const createServerOptions = helpers.makeCreateServerOptions(mode); + var server; - describe("done-serve timeout", function() { - this.timeout(10000); + before(function(done) { + this.timeout(30000); - var server; + server = serve({ + path: path.join(__dirname, 'tests'), + main: "timeout/index.stache!done-autorender", + timeout: 50 + }).listen(5050); - before(function(done) { - this.timeout(30000); - - server = serve(5050, createServerOptions({ - path: path.join(__dirname, 'tests'), - main: "timeout/index.stache!done-autorender", - timeout: 50 - })); - - server.on('listening', async function(){ - // Make an initial request so that steal is preloaded - await request("http://localhost:5050/slow"); + server.on('listening', function(){ + // Make an initial request so that steal is preloaded + request("http://localhost:5050/slow", function(err, res, body){ setTimeout(done, isCI ? 20000 : 5000); }); }); + }); - after(function(done) { - server.close(done); - }); + after(function(done) { + server.close(done); + }); - it("Times out when exceeding the timeout", async function(){ - let [err, res] = await request("http://localhost:5050/slow"); - assert.ok(/failed/.test(res.body), "This route timed out"); + it("Times out when exceeding the timeout", function(done){ + request("http://localhost:5050/slow", function(err, res, body){ + assert.ok(/failed/.test(body), "This route timed out"); + done(); }); + }); - it("Doesn't timeout when it renders on time", async function(){ - let [err, res] = await request("http://localhost:5050/fast"); - assert.ok(/passed/.test(res.body), "This route timed out"); + it("Doesn't timeout when it renders on time", function(done){ + request("http://localhost:5050/fast", function(err, res, body){ + assert.ok(/passed/.test(body), "This route timed out"); + done(); }); }); - -} +});