Comparing version 1.0.0-alpha.27 to 1.0.0-alpha.28
@@ -8,2 +8,3 @@ # Upload files to Node.js | ||
input(type="file" name="userimage") | ||
input(type="hidden" name="csrf" value=csrf()) | ||
input(type="submit" value="Upload image") | ||
@@ -10,0 +11,0 @@ ``` |
{ | ||
"name": "server", | ||
"version": "1.0.0-alpha.27", | ||
"version": "1.0.0-alpha.28", | ||
"description": "A modern and powerful server for Node.js", | ||
@@ -5,0 +5,0 @@ "main": "server.js", |
@@ -20,33 +20,16 @@ // External libraries used | ||
// SKIP: request() does not accept gzip | ||
it.skip('compress', done => { | ||
const middle = ctx => | ||
ctx.res.send('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + | ||
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + | ||
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + | ||
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'); | ||
launch(middle).then(ctx => { | ||
supertest(ctx.original).get('/').then(res => { | ||
done(); | ||
}); | ||
// expect(res.caseless.dict['content-length'] < 90).toBe(true); | ||
// done(); | ||
}); | ||
}); | ||
it('compress?', () => { | ||
it('compress?', async () => { | ||
const middle = ctx => ctx.res.send(); | ||
const url = 'http://localhost:3721/favicon.ico'; | ||
const favicon = __dirname + '/../../tests/logo.png'; | ||
return handler(middle, { url }, { port: 3721, connect: { favicon } }) | ||
.then(res => expect(res.headers['content-encoding']).toBe('gzip')); | ||
const res = await handler(middle, { url }, { port: 3721, connect: { favicon } }); | ||
expect(res.headers['content-encoding']).toBe('gzip'); | ||
}); | ||
it('favicon', () => { | ||
it('favicon', async () => { | ||
const middle = ctx => ctx.res.send(); | ||
const url = 'http://localhost:3721/favicon.ico'; | ||
const favicon = __dirname + '/../../tests/logo.png'; | ||
return handler(middle, { url }, { port: 3721, connect: { favicon } }) | ||
.then(res => expect(res.headers['content-type']).toBe('image/x-icon')); | ||
const res = await handler(middle, { url }, { port: 3721, connect: { favicon } }); | ||
expect(res.headers['content-type']).toBe('image/x-icon'); | ||
@@ -57,36 +40,31 @@ // This should not go here: | ||
it('response-time', () => { | ||
it('response-time', async () => { | ||
const middle = ctx => ctx.res.send('世界'); | ||
return getter(middle).then(res => { | ||
expect(typeof res.headers['x-response-time']).toBe('string'); | ||
}); | ||
const res = await getter(middle); | ||
expect(typeof res.headers['x-response-time']).toBe('string'); | ||
}); | ||
// GETTER doesn't have that signature | ||
it('serve-index', done => { | ||
it('serve-index', async () => { | ||
const path = __dirname + '/../../tests'; | ||
return launch([], { public: path }).then(ctx => { | ||
const logoUrl = 'http://localhost:' + ctx.options.port + '/logo.png'; | ||
request(logoUrl).then(res => { | ||
expect(res.headers['content-type']).toBe('image/png'); | ||
done(); | ||
}); | ||
}); | ||
const ctx = await launch([], { public: path }); | ||
const logoUrl = 'http://localhost:' + ctx.options.port + '/logo.png'; | ||
const res = await request(logoUrl); | ||
expect(res.headers['content-type']).toBe('image/png'); | ||
}); | ||
// NOTE: for the next tests we'd need persistent `request()` (I couldn't make it) | ||
// Can handle sessions | ||
it('session', done => { | ||
it('session', async () => { | ||
const setSession = ctx => { ctx.req.session.page = 'pageA' }; | ||
const routes = [ | ||
get('/a', ctx => { ctx.req.session.page = 'pageA'; ctx.res.end(); }), | ||
get('/', ctx => ctx.res.send(ctx.req.session.page)), | ||
get('/a', setSession, ctx => ctx.res.end()), | ||
get('/b', ctx => ctx.res.send(ctx.req.session.page)), | ||
]; | ||
launch(routes).then(req.get('/a')).then(req.get('/', res => { | ||
expect(res.text).toBe('pageA'); | ||
done(); | ||
})); | ||
const ctx = await launch(routes); | ||
await req.get('/a', res => expect(res.text).toBe(''))(ctx); | ||
await req.get('/b', res => expect(res.text).toBe('pageA'))(ctx); | ||
}); | ||
it('csurf', done => { | ||
it('csurf', async () => { | ||
const routes = [ | ||
@@ -97,11 +75,22 @@ get('/', ctx => ctx.res.send(ctx.res.locals.csrf)), | ||
launch(routes).then(ctx => { | ||
supertest(ctx.server).get('/').expect(200).then(res => { | ||
expect(res.text).toBeDefined(); | ||
supertest(ctx.server).post('/').set('Cookie', cookies(res)) | ||
.send('_csrf=' + encodeURIComponent(res.text)) | ||
.expect(200).then(() => done()); | ||
}); | ||
}); | ||
const ctx = await launch(routes); | ||
const res = await supertest(ctx.server).get('/').expect(200); | ||
expect(res.text).toBeDefined(); | ||
await supertest(ctx.server).post('/').set('Cookie', cookies(res)) | ||
.send('_csrf=' + encodeURIComponent(res.text)) | ||
.expect(200); | ||
}); | ||
// SKIP: request() does not accept gzip | ||
it.skip('compress', async () => { | ||
const middle = ctx => | ||
ctx.res.send('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + | ||
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + | ||
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + | ||
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'); | ||
const ctx = await launch(middle); | ||
const res = await supertest(ctx.original).get('/'); | ||
// ... | ||
}); | ||
}); |
102
server.js
@@ -16,68 +16,74 @@ // server for Node.js (https://serverjs.io/) | ||
// Create the initial context | ||
const context = (self, req = {}, res = {}) => { | ||
return Object.assign({}, self, { req: req, res: res }); | ||
}; | ||
const context = (self, req, res) => Object.assign({}, self, { req, res }); | ||
// Main function | ||
function Server (...middle) { | ||
return new Promise((resolve, reject) => { | ||
"use strict"; | ||
const Server = async (...middle) => { | ||
// First parameter can be: | ||
// - options: Number || Object (cannot be ID'd) | ||
// - middleware: undefined || null || Boolean || Function || Array | ||
const opts = ( | ||
typeof middle[0] === 'undefined' || | ||
typeof middle[0] === 'boolean' || | ||
middle[0] === null || | ||
middle[0] instanceof Function || | ||
middle[0] instanceof Array | ||
) ? {} : middle.shift(); | ||
const ctx = {}; | ||
this.express = express; | ||
this.app = this.express(); | ||
// First parameter can be: | ||
// - options: Number || Object (cannot be ID'd) | ||
// - middleware: undefined || null || Boolean || Function || Array | ||
const opts = ( | ||
typeof middle[0] === 'undefined' || | ||
typeof middle[0] === 'boolean' || | ||
middle[0] === null || | ||
middle[0] instanceof Function || | ||
middle[0] instanceof Array | ||
) ? {} : middle.shift(); | ||
// Set the options for the context of Server.js | ||
this.plugins = module.exports.plugins; | ||
this.options = config(opts, this.plugins, this.app); | ||
ctx.express = express; | ||
ctx.app = ctx.express(); | ||
this.utils = { modern: modern }; | ||
this.modern = modern; | ||
// this.error = error(this.options.errors); | ||
this.throw = error(this.options.errors); | ||
// Set the options for the context of Server.js | ||
ctx.options = config(opts, module.exports.plugins, ctx.app); | ||
this.plugins.filter(p => p.init && this.options[p.name]).forEach(p => p.init(this)); | ||
// Only enabled plugins through the config | ||
ctx.plugins = module.exports.plugins.filter(p => ctx.options[p.name]); | ||
// PLUGIN middleware | ||
middle = join( | ||
this.plugins.filter(n => this.options[n.name]).map(p => p.beforeware || p.before), | ||
middle, | ||
this.plugins.filter(n => this.options[n.name]).map(p => p.afterware || p.after), | ||
final | ||
); | ||
ctx.utils = { modern: modern }; | ||
ctx.modern = modern; | ||
// ctx.error = error(ctx.options.errors); | ||
ctx.throw = error(ctx.options.errors); | ||
// Main thing here | ||
this.app.use((req, res) => middle(context(this, req, res))); | ||
// All the init beforehand | ||
const initAll = ctx.plugins.map(p => p.init).filter(p => p); | ||
for (let init of initAll) { | ||
await init(ctx); | ||
} | ||
const launch = () => { | ||
if (this.options.verbose) { | ||
console.log(`Server started on port ${this.options.port} http://localhost:${this.options.port}/`); | ||
// PLUGIN middleware | ||
middle = join( | ||
ctx.plugins.map(p => p.beforeware || p.before), | ||
middle, | ||
ctx.plugins.map(p => p.afterware || p.after), | ||
final | ||
); | ||
// Main thing here | ||
ctx.app.use((req, res) => middle(context(ctx, req, res))); | ||
// Start listening to requests | ||
return new Promise((resolve, reject) => { | ||
const launch = async () => { | ||
// After launching it | ||
const launchAll = ctx.plugins.map(p => p.launch).filter(p => p); | ||
for (let launch of launchAll) { | ||
await launch(ctx); | ||
} | ||
// PLUGIN.attach: ctx => {} | ||
if (ctx.options.verbose) { | ||
ctx.log(`Server started on http://localhost:${ctx.options.port}/`); | ||
} | ||
// Proxy it to the server http-server for things like .close() | ||
resolve(new Proxy(this, { | ||
get: (ctx, key) => ctx[key] || ctx.server[key] | ||
})); | ||
resolve(new Proxy(ctx, { get: (orig, k) => orig[k] || orig.server[k] })); | ||
}; | ||
// Start listening to requests | ||
this.server = this.app.listen(this.options.port, launch); | ||
this.server.on('error', err => reject(error.native(err))); | ||
ctx.server = ctx.app.listen(ctx.options.port, launch); | ||
ctx.server.on('error', err => reject(error.native(err))); | ||
}); | ||
} | ||
module.exports = (...opts) => new Server(...opts); | ||
module.exports = Server; | ||
module.exports.router = router; | ||
@@ -84,0 +90,0 @@ module.exports.utils = { |
@@ -87,3 +87,3 @@ const config = require('./index'); | ||
it('sets values to the app', done => { | ||
it('sets values to the app', () => { | ||
config({ foo: 'bar' }, [], { | ||
@@ -93,3 +93,2 @@ set: (name, value) => { | ||
expect(value).toBe('bar'); | ||
done(); | ||
} | ||
@@ -96,0 +95,0 @@ } |
@@ -0,1 +1,4 @@ | ||
const buffer = require('crypto').randomBytes(60); | ||
const token = buffer.toString('base64').replace(/\//g,'_').replace(/\+/g,'-'); | ||
// Default configuration for server | ||
@@ -8,6 +11,5 @@ module.exports = { | ||
public: 'public', | ||
secret: 'secret-' + parseInt(1000000 * Math.random()), | ||
secret: 'secret-' + token, | ||
// Dev variables - not part of the official API | ||
@@ -14,0 +16,0 @@ // Show extra info on the terminal; should depend on another variable |
@@ -49,4 +49,12 @@ const extend = require('extend'); // deep clone, not like shallow Object.assign | ||
if ((/^secret-/.test(options.secret)) && options.verbose) { | ||
console.log(` | ||
Please change the secret in your environment configuration. | ||
The default one is not recommended and should be changed. | ||
More info in https://serverjs.io/errors#defaultSecret | ||
`); | ||
} | ||
if (app) { | ||
@@ -53,0 +61,0 @@ app.options = options; |
const join = require('../join'); | ||
const modern = require('./index'); | ||
const { throws } = require('../../tests/helpers'); | ||
const middle = (req, res, next) => next(); | ||
@@ -33,5 +34,5 @@ const ctx = { req: {}, res: {} }; | ||
describe('call the middleware', () => { | ||
it('requires the context to be called', done => { | ||
modern(middle)().catch(err => { done(); }); | ||
}); | ||
it('requires the context to be called', throws(async () => { | ||
await modern(middle)(); | ||
})); | ||
@@ -42,13 +43,13 @@ it('returns a promise when called', () => { | ||
it('rejected with empty context', done => { | ||
modern(middle)({}).catch(err => { done(); }); | ||
}); | ||
it('rejected with empty context', throws(async () => { | ||
await modern(middle)({}); | ||
})); | ||
it('rejected without res', done => { | ||
modern(middle)({ req: {} }).catch(err => { done(); }); | ||
}); | ||
it('rejected without res', throws(async () => { | ||
await modern(middle)({ req: {} }); | ||
})); | ||
it('rejected without req', done => { | ||
modern(middle)({ res: {} }).catch(err => { done(); }); | ||
}); | ||
it('rejected without req', throws(async () => { | ||
await modern(middle)({ res: {} }); | ||
})); | ||
}); | ||
@@ -59,20 +60,18 @@ | ||
describe('Middleware handles the promise', () => { | ||
it('resolves when next is called empty', done => { | ||
modern((req, res, next) => next())(ctx).then(() => done()); | ||
it('resolves when next is called empty', async () => { | ||
await modern((req, res, next) => next())(ctx); | ||
}); | ||
it('cannot handle error middleware', () => { | ||
expect(() => modern((err, req, res, next) => {})).toThrow(); | ||
}); | ||
it('cannot handle error middleware', throws(async () => { | ||
await modern((err, req, res, next) => {}); | ||
})); | ||
it('passes the context', done => { | ||
it('passes the context', async () => { | ||
const ctx = { req: 1, res: 2 }; | ||
modern((req, res, next) => next())(ctx).then(ctx => { | ||
expect(ctx.req).toBe(1); | ||
expect(ctx.res).toBe(2); | ||
done(); | ||
}); | ||
const readCtx = await modern((req, res, next) => next())(ctx); | ||
expect(readCtx.req).toBe(1); | ||
expect(readCtx.res).toBe(2); | ||
}); | ||
it('can modify the context', done => { | ||
it('can modify the context', async () => { | ||
const middle = (req, res, next) => { | ||
@@ -83,10 +82,8 @@ req.user = 'myname'; | ||
}; | ||
modern(middle)({ req: {}, res: {} }).then(ctx => { | ||
expect(ctx.req.user).toBe('myname'); | ||
expect(ctx.res.send).toBe('sending'); | ||
done(); | ||
}); | ||
const ctx = await modern(middle)({ req: {}, res: {} }); | ||
expect(ctx.req.user).toBe('myname'); | ||
expect(ctx.res.send).toBe('sending'); | ||
}); | ||
it('has chainable context', done => { | ||
it('has chainable context', async () => { | ||
const ctx = { req: { user: 'a' }, res: { send: 'b' } }; | ||
@@ -98,10 +95,8 @@ const middle = (req, res, next) => { | ||
}; | ||
modern(middle)(ctx).then(modern(middle)).then(ctx => { | ||
expect(ctx.req.user).toBe('a11'); | ||
expect(ctx.res.send).toBe('b22'); | ||
done(); | ||
}); | ||
const resCtx = await modern(middle)(ctx).then(modern(middle)); | ||
expect(resCtx.req.user).toBe('a11'); | ||
expect(resCtx.res.send).toBe('b22'); | ||
}); | ||
it('factory can receive options', done => { | ||
it('factory can receive options', async () => { | ||
@@ -164,17 +159,12 @@ // The full context | ||
join(middles)(ctx).then(ctx => { | ||
expect(ctx.req.user).toBe('a111111'); | ||
expect(ctx.res.send).toBe('b111111'); | ||
done(); | ||
}); | ||
const readCtx = await join(middles)(ctx); | ||
expect(readCtx.req.user).toBe('a111111'); | ||
expect(readCtx.res.send).toBe('b111111'); | ||
}); | ||
it('rejects when next is called with an error', done => { | ||
modern((req, res, next) => next('Custom error'))(ctx).catch(err => { | ||
expect(err).toBe('Custom error'); | ||
done(); | ||
}); | ||
}); | ||
it('rejects when next is called with an error', throws(async () => { | ||
await modern((req, res, next) => next(new Error('Custom error')))(ctx); | ||
})); | ||
it('does not resolve nor reject if next is not called', done => { | ||
it('does not resolve nor reject if next is not called', async () => { | ||
modern((req, res, next) => {})(ctx).then(ctx => { | ||
@@ -185,4 +175,6 @@ expect('It was resolved').toBe(false); | ||
}); | ||
setTimeout(() => done(), 1000); | ||
return new Promise((resolve, reject) => { | ||
setTimeout(() => resolve(), 1000); | ||
}); | ||
}); | ||
}); |
@@ -48,11 +48,9 @@ const extend = require('extend'); | ||
it('still works?', done => { | ||
it('still works?', async () => { | ||
const ctx = createCtx(); | ||
ctx.req.path = '/test/francisco/presencia/bla'; | ||
get('/test/:name/:lastname/bla')(ctx).then(ctx => { | ||
expect(ctx.req.solved).toBe(true); | ||
expect(ctx.req.params.name).toBe('francisco'); | ||
expect(ctx.req.params.lastname).toBe('presencia'); | ||
done(); | ||
}); | ||
let relCtx = await get('/test/:name/:lastname/bla')(ctx); | ||
expect(relCtx.req.solved).toBe(true); | ||
expect(relCtx.req.params.name).toBe('francisco'); | ||
expect(relCtx.req.params.lastname).toBe('presencia'); | ||
}); | ||
@@ -59,0 +57,0 @@ }); |
@@ -88,1 +88,13 @@ const request = require('request'); | ||
exports.cookies = cookies; | ||
exports.throws = (cb, err = false) => async () => { | ||
try { | ||
const res = await cb(); | ||
} catch(err) { | ||
if (!(err instanceof Error)) { | ||
throw new Error('A non-error was thrown: ' + err); | ||
} | ||
return Promise.resolve(); | ||
} | ||
throw new Error('No error was thrown'); | ||
}; |
@@ -1,69 +0,78 @@ | ||
let server = require('../server'); | ||
const server = require('../server'); | ||
const { port } = require('./helpers'); | ||
describe('Options', () => { | ||
it('default settings are correct', () => { | ||
return server().then(server => { | ||
expect(server.options.port).toBe(3000); | ||
expect(server.options.engine).toBe('pug'); | ||
expect(server.options.verbose).toBe(false); | ||
it('default settings are correct', async () => { | ||
const ctx = await server(); | ||
ctx.close(); | ||
expect(ctx.options.port).toBe(3000); | ||
expect(ctx.options.engine).toBe('pug'); | ||
expect(ctx.options.verbose).toBe(false); | ||
expect(ctx.options.secret).toMatch(/^secret-/); | ||
}); | ||
// Now this is a plugin: | ||
// expect(server.options.public).toBe('public'); | ||
server.close(); | ||
}); | ||
it('accepts a single port Number', async () => { | ||
const options = port(); | ||
const ctx = await server(options); | ||
ctx.close(); | ||
expect(ctx.options.port).toBe(options); | ||
}); | ||
it('can be initialized with a single port parameter', done => { | ||
let port = 3000 + parseInt(Math.random() * 10000) % 1000; | ||
server(port).then(server => { | ||
expect(server.options.port).toBe(port); | ||
server.close(); | ||
done(); | ||
}); | ||
it('accepts a simple Object with a port prop', async () => { | ||
const options = { port: port() }; | ||
const ctx = await server(options); | ||
ctx.close(); | ||
expect(ctx.options.port).toBe(options.port); | ||
}); | ||
it('can be initialized with only a port', done => { | ||
let port = 3000 + parseInt(Math.random() * 10000) % 1000; | ||
server({ port: port }).then(server => { | ||
expect(server.options.port).toBe(port); | ||
server.close(); | ||
done(); | ||
}); | ||
it('can listen only one time to the same port', async () => { | ||
const onePort = port(); | ||
const ctx = await server(onePort); | ||
const err = await server(onePort).catch(err => err); | ||
ctx.close(); | ||
expect(err.code === 'EADDRINUSE'); | ||
}); | ||
it('can listen only one time to the same port', done => { | ||
server(3000).then(serve => { | ||
server(3000).catch(error => { | ||
expect(error.code === 'EADDRINUSE') | ||
done(); | ||
}); | ||
serve.close(); | ||
}); | ||
it('sets the engine properly `engine`', async () => { | ||
const ctx = await server({ engine: 'whatever', port: port() }); | ||
ctx.close(); | ||
expect(ctx.app.get('view engine')).toBe('whatever'); | ||
}); | ||
it('sets the view engine properly', done => { | ||
server({ 'view engine': 'whatever' }).then(server => { | ||
expect(server.app.get('view engine')).toBe('whatever'); | ||
server.close(); | ||
done(); | ||
}); | ||
it('sets the engine properly `view engine`', async () => { | ||
const ctx = await server({ 'view engine': 'whatever', port: port() }); | ||
ctx.close(); | ||
expect(ctx.app.get('view engine')).toBe('whatever'); | ||
}); | ||
it('has independent instances', done => { | ||
server(2051).then(serv1 => { | ||
server(3051).then(serv2 => { | ||
expect(serv2.options.port).toBe(3051); | ||
serv2.options.port = 3500; | ||
expect(serv1.options.port).toBe(2051); | ||
expect(serv2.options.port).toBe(3500); | ||
it('has independent instances', async () => { | ||
const portA = port(); | ||
const portB = port(); | ||
const serv1 = await server(portA); | ||
const serv2 = await server(portB); | ||
serv1.close(); | ||
serv2.close(); | ||
serv2.a = 'abc'; | ||
expect(typeof serv1.a).toBe('undefined'); | ||
expect(serv2.a).toBe('abc'); | ||
serv1.close(); | ||
serv2.close(); | ||
done(); | ||
}); | ||
}); | ||
expect(serv2.options.port).toBe(portB); | ||
const portC = port(); | ||
serv2.options.port = portC; | ||
expect(serv1.options.port).toBe(portA); | ||
expect(serv2.options.port).toBe(portC); | ||
serv2.a = 'abc'; | ||
expect(typeof serv1.a).toBe('undefined'); | ||
expect(serv2.a).toBe('abc'); | ||
}); | ||
// // NOT PART OF THE STABLE API | ||
// it('logs init string', async () => { | ||
// const logs = []; | ||
// const index = server.plugins.push({ | ||
// name: 'log', launch: ctx => { ctx.log = msg => logs.push(msg) } | ||
// }); | ||
// const ctx = await server({ port: port(), verbose: true }); | ||
// ctx.close(); | ||
// delete server.plugins[index]; | ||
// expect(logs.filter(one => /started on/.test(one)).length).toBe(1); | ||
// }); | ||
}); |
@@ -8,6 +8,5 @@ const server = require('server'); | ||
const { get, error } = server.router; | ||
const { handler, getter } = require('./helpers'); | ||
const { handler, getter, port } = require('./helpers'); | ||
const hello = ctx => ctx.res.send('Hello 世界'); | ||
const randPort = ctx => ctx.options.port = 2000 + parseInt(Math.random() * 10000); | ||
@@ -21,50 +20,32 @@ const wait = time => new Promise((resolve, reject) => setTimeout(resolve, time)); | ||
describe('Middleware', () => { | ||
it('loads as a function', done => { | ||
getter(ctx => ctx.res.send('Hello 世界')).then(res => { | ||
expect(res.body).toBe('Hello 世界'); | ||
done(); | ||
}); | ||
it('loads as a function', async () => { | ||
const res = await getter(ctx => ctx.res.send('Hello 世界')); | ||
expect(res.body).toBe('Hello 世界'); | ||
}); | ||
it('loads as an array', done => { | ||
getter([ctx => ctx.res.send('Hello 世界')]).then(res => { | ||
expect(res.body).toBe('Hello 世界'); | ||
done(); | ||
}); | ||
it('loads as an array', async () => { | ||
const res = await getter([ctx => ctx.res.send('Hello 世界')]); | ||
expect(res.body).toBe('Hello 世界'); | ||
}); | ||
// NOTE: port has to be changed for parallel tests | ||
it('loads as an function in the first parameter', () => { | ||
server.plugins.push({ init: ctx => { | ||
ctx.options.port = 2000 + parseInt(Math.random() * 10000); | ||
}}); | ||
return server(hello).then(autorequest).then(res => { | ||
expect(res.body).toBe('Hello 世界'); | ||
}); | ||
}); | ||
// it('loads as an array in the first parameter', () => { | ||
// // After others have finished | ||
// return wait(1000).then(() => { | ||
// server([hello]).then(autorequest).then(res => { | ||
// expect(res.body).toBe('Hello 世界'); | ||
// }); | ||
// }); | ||
// }); | ||
it('loads as an array in the first parameter', () => { | ||
// After others have finished | ||
return wait(1000).then(() => { | ||
server([hello]).then(autorequest).then(res => { | ||
expect(res.body).toBe('Hello 世界'); | ||
}); | ||
it('has a valid context', async () => { | ||
const res = await getter(({ req, res, options }) => { | ||
res.send(`${!!req}:${!!options}`); | ||
}); | ||
expect(res.body).toBe('true:true'); | ||
}); | ||
it('has a valid context', () => { | ||
return getter(ctx => { | ||
ctx.res.send('Hello'); | ||
expect(ctx.req).toBeDefined(); | ||
expect(ctx.res).toBeDefined(); | ||
expect(ctx.options).toBeDefined(); | ||
}); | ||
it('loads as a relative file', async () => { | ||
const res = await handler('./tests/a.js'); | ||
expect(res.body).toBe('世界'); | ||
}); | ||
it('loads as a relative file', done => { | ||
handler('./tests/a.js').then(res => { | ||
expect(res.body).toBe('世界'); | ||
done(); | ||
}); | ||
}); | ||
}); |
@@ -13,6 +13,2 @@ const request = require('request-promise-native'); | ||
describe('Full trip request', () => { | ||
it('dummy', done => { | ||
done(); | ||
}); | ||
it('can perform a simple get', () => { | ||
@@ -24,11 +20,9 @@ return getter(ctx => ctx.res.send('Hello 世界')).then(res => { | ||
it('loads as an array', done => { | ||
getter([ctx => ctx.res.send('Hello 世界')]).then(res => { | ||
expect(res.body).toBe('Hello 世界'); | ||
done(); | ||
}); | ||
it('loads as an array', async () => { | ||
const res = await getter([ctx => ctx.res.send('Hello 世界')]); | ||
expect(res.body).toBe('Hello 世界'); | ||
}); | ||
it('can perform a simple post', () => { | ||
let reply = ctx => ctx.res.send('Hello ' + ctx.req.body.a); | ||
const reply = ctx => ctx.res.send('Hello ' + ctx.req.body.a); | ||
return poster(reply, { a: '世界' }, nocsrf).then(res => { | ||
@@ -35,0 +29,0 @@ expect(res.body).toBe('Hello 世界'); |
@@ -67,8 +67,6 @@ const request = require('request-promise-native'); | ||
// multiple request to make sure the middleware remains the same | ||
it('parses params correctly', done => { | ||
it('parses params correctly', async () => { | ||
const middle = get('/:id', ctx => ctx.res.send(ctx.req.params.id)); | ||
handler(middle, { path: '/42?ignored=true' }).then(res => { | ||
expect(res.body).toBe('42'); | ||
done(); | ||
}); | ||
const res = await handler(middle, { path: '/42?ignored=true' }); | ||
expect(res.body).toBe('42'); | ||
}); | ||
@@ -78,11 +76,9 @@ | ||
// multiple request to make sure the middleware remains the same | ||
it('does not modify the router', done => { | ||
launch([get('/w', ctx => ctx.res.send('w'))].concat(routes)).then(ctx => { | ||
const url = 'http://localhost:' + ctx.options.port + '/'; | ||
request(url).then(() => request(url)).then(() => request(url)).then(body => { | ||
ctx.close(); | ||
expect(body).toBe('Hello 世界') | ||
done(); | ||
}); | ||
}); | ||
it('does not modify the router', async () => { | ||
const ctx = await launch([get('/w', ctx => ctx.res.send('w'))].concat(routes)); | ||
const full = 'http://localhost:' + ctx.options.port + '/'; | ||
for (let url of [full, full, full]) { | ||
let body = await request(url); | ||
expect(body).toBe('Hello 世界'); | ||
} | ||
}); | ||
@@ -89,0 +85,0 @@ }); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1136033
1720