Jonatan Nilsson
9c43b429c4
All checks were successful
continuous-integration/appveyor/branch AppVeyor build succeeded
flaska: Add promise-based listen and close methods
623 lines
17 KiB
JavaScript
623 lines
17 KiB
JavaScript
import { Eltro as t, spy, assert} from 'eltro'
|
|
import { Flaska } from '../flaska.mjs'
|
|
import { fakeHttp, createReq, createRes } from './helper.mjs'
|
|
|
|
const faker = fakeHttp()
|
|
|
|
t.describe('#requestStart()', function() {
|
|
t.test('calls on correct events on both req and res', function(cb) {
|
|
const assertErrorOne = new Error('Erics Birth')
|
|
const assertErrorTwo = new Error('Contactic Eric')
|
|
const onReqError = spy()
|
|
const onResError = spy()
|
|
const onEnded = spy()
|
|
const assertReq = createReq({ url: '', a: 1 })
|
|
const assertRes = createRes({ b: 2 })
|
|
let flaska = new Flaska({}, faker)
|
|
|
|
flaska.onreqerror(onReqError)
|
|
flaska.onreserror(onResError)
|
|
flaska.requestEnded = onEnded
|
|
|
|
flaska.requestEnd = function(err, ctx) {
|
|
try {
|
|
assert.ok(err)
|
|
assert.strictEqual(assertReq.on.callCount, 2)
|
|
assert.strictEqual(assertRes.on.callCount, 2)
|
|
|
|
|
|
assert.strictEqual(assertRes.on.firstCall[0], 'error')
|
|
assert.strictEqual(typeof(assertRes.on.firstCall[1]), 'function')
|
|
assertRes.on.firstCall[1](assertErrorTwo, ctx)
|
|
assert.strictEqual(onResError.callCount, 1)
|
|
assert.strictEqual(onResError.firstCall[0], assertErrorTwo)
|
|
assert.strictEqual(onResError.firstCall[1], ctx)
|
|
|
|
assert.strictEqual(assertRes.on.secondCall[0], 'finish')
|
|
assert.strictEqual(typeof(assertRes.on.secondCall[1]), 'function')
|
|
assert.strictEqual(onEnded.callCount, 0)
|
|
assertRes.on.secondCall[1]()
|
|
assert.strictEqual(onEnded.callCount, 1)
|
|
assert.strictEqual(onEnded.firstCall[0], ctx)
|
|
|
|
assert.strictEqual(assertReq.on.firstCall[0], 'error')
|
|
assert.strictEqual(typeof(assertReq.on.firstCall[1]), 'function')
|
|
assertReq.on.firstCall[1](assertErrorOne, ctx)
|
|
assert.strictEqual(onReqError.callCount, 1)
|
|
assert.strictEqual(onReqError.firstCall[0], assertErrorOne)
|
|
assert.strictEqual(onReqError.firstCall[1], ctx)
|
|
|
|
assert.strictEqual(assertReq.on.secondCall[0], 'aborted')
|
|
assert.strictEqual(typeof(assertReq.on.secondCall[1]), 'function')
|
|
assert.notStrictEqual(ctx.aborted, false)
|
|
assertReq.on.secondCall[1]()
|
|
assert.strictEqual(ctx.aborted, true)
|
|
|
|
// Test abort and close
|
|
|
|
cb()
|
|
} catch (err) { cb(err) }
|
|
}
|
|
flaska._beforeCompiled = function(ctx) {
|
|
throw new Error()
|
|
}
|
|
|
|
flaska.requestStart(assertReq, assertRes)
|
|
})
|
|
|
|
t.test('calls beforeCompiled correctly', function(cb) {
|
|
const assertError = new Error('test')
|
|
const assertReq = createReq({ url: '', a: 1 })
|
|
const assertRes = createRes({ b: 2 })
|
|
let flaska = new Flaska({}, faker)
|
|
|
|
flaska.requestEnd = function(err, ctx) {
|
|
if (err && err !== assertError) return cb(err)
|
|
|
|
try {
|
|
assert.ok(err)
|
|
assert.strictEqual(err, assertError)
|
|
assert.deepStrictEqual(ctx.state, {})
|
|
assert.strictEqual(ctx.req, assertReq)
|
|
assert.strictEqual(ctx.res, assertRes)
|
|
cb()
|
|
} catch (err) { cb(err) }
|
|
}
|
|
flaska._beforeCompiled = function(ctx) {
|
|
assert.strictEqual(ctx.req, assertReq)
|
|
assert.strictEqual(ctx.res, assertRes)
|
|
throw assertError
|
|
}
|
|
|
|
flaska.requestStart(assertReq, assertRes)
|
|
})
|
|
|
|
t.test('calls beforeAsyncCompiled correctly if defined', function(cb) {
|
|
const assertError = new Error('test')
|
|
const assertReq = createReq({ url: '', a: 1 })
|
|
const assertRes = createRes({ b: 2 })
|
|
let flaska = new Flaska({}, faker)
|
|
flaska.compile()
|
|
|
|
flaska._beforeAsyncCompiled = function(ctx) {
|
|
assert.strictEqual(ctx.req, assertReq)
|
|
assert.strictEqual(ctx.res, assertRes)
|
|
return Promise.resolve().then(function() { return Promise.reject(assertError) })
|
|
}
|
|
|
|
flaska.requestEnd = function(err, ctx) {
|
|
if (err && err !== assertError) return cb(err)
|
|
|
|
try {
|
|
assert.ok(err)
|
|
assert.strictEqual(err, assertError)
|
|
assert.deepStrictEqual(ctx.state, {})
|
|
assert.strictEqual(ctx.req, assertReq)
|
|
assert.strictEqual(ctx.res, assertRes)
|
|
cb()
|
|
} catch (err) { cb(err) }
|
|
}
|
|
|
|
flaska.requestStart(assertReq, assertRes)
|
|
})
|
|
|
|
t.test('calls correct router with correct url and context', function(cb) {
|
|
const assertError = new Error('test')
|
|
const assertMethod = 'test'
|
|
const assertPath = '/test/me'
|
|
const assertSearch = '?asdf=test'
|
|
const assertLog = { info: function() {}, error: function() {} }
|
|
let flaska = new Flaska({ log: assertLog }, faker)
|
|
assert.strictEqual(flaska.log, assertLog)
|
|
flaska.compile()
|
|
|
|
flaska.routers.test = {
|
|
match: function(path) {
|
|
assert.strictEqual(path, assertPath)
|
|
throw assertError
|
|
}
|
|
}
|
|
|
|
flaska.requestEnd = function(err, ctx) {
|
|
if (err && err !== assertError) return cb(err)
|
|
|
|
try {
|
|
assert.ok(err)
|
|
assert.strictEqual(err, assertError)
|
|
assert.strictEqual(ctx.url, assertPath)
|
|
assert.strictEqual(ctx.search, assertSearch)
|
|
assert.strictEqual(ctx.method, assertMethod)
|
|
assert.strictEqual(ctx.status, 200)
|
|
assert.strictEqual(ctx.body, null)
|
|
assert.strictEqual(ctx.type, null)
|
|
assert.strictEqual(ctx.length, null)
|
|
assert.strictEqual(ctx.log, assertLog)
|
|
assert.ok(ctx.query)
|
|
assert.ok(ctx.query.get)
|
|
assert.ok(ctx.query.set)
|
|
assert.ok(ctx.query.delete)
|
|
cb()
|
|
} catch (err) { cb(err) }
|
|
}
|
|
|
|
flaska.requestStart(createReq({
|
|
url: assertPath + assertSearch,
|
|
method: assertMethod,
|
|
}), createRes())
|
|
})
|
|
|
|
t.test('calls correct router with correct url and context if beforeAsync', function(cb) {
|
|
const assertError = new Error('test')
|
|
const assertMethod = 'test'
|
|
const assertPath = '/test/me'
|
|
const assertSearch = '?asdf=test'
|
|
let flaska = new Flaska({}, faker)
|
|
flaska.compile()
|
|
flaska._beforeAsyncCompiled = function() { return Promise.resolve() }
|
|
|
|
flaska.routers.test = {
|
|
match: function(path) {
|
|
assert.strictEqual(path, assertPath)
|
|
throw assertError
|
|
}
|
|
}
|
|
|
|
flaska.requestEnd = function(err, ctx) {
|
|
if (err && err !== assertError) return cb(err)
|
|
|
|
try {
|
|
assert.ok(err)
|
|
assert.strictEqual(err, assertError)
|
|
assert.strictEqual(ctx.url, assertPath)
|
|
assert.strictEqual(ctx.search, assertSearch)
|
|
assert.strictEqual(ctx.method, assertMethod)
|
|
cb()
|
|
} catch (err) { cb(err) }
|
|
}
|
|
|
|
flaska.requestStart(createReq({
|
|
url: assertPath + assertSearch,
|
|
method: assertMethod,
|
|
}), createRes())
|
|
})
|
|
|
|
t.test('calls handleMiddleware correctly', function(cb) {
|
|
const assertError = new Error('test')
|
|
const assertMiddles = [1, 2]
|
|
const assertParams = { a: 1, b: 2 }
|
|
let checkMiddleCtx = null
|
|
|
|
let flaska = new Flaska({}, faker)
|
|
flaska.compile()
|
|
|
|
flaska.routers.GET.match = function() {
|
|
return {
|
|
handler: function() {},
|
|
middlewares: assertMiddles,
|
|
params: assertParams,
|
|
}
|
|
}
|
|
flaska.handleMiddleware = function(ctx, middles, index) {
|
|
assert.strictEqual(index, 0)
|
|
assert.strictEqual(middles, assertMiddles)
|
|
checkMiddleCtx = ctx
|
|
throw assertError
|
|
}
|
|
|
|
flaska.requestEnd = function(err, ctx) {
|
|
if (err && err !== assertError) return cb(err)
|
|
|
|
try {
|
|
assert.ok(err)
|
|
assert.ok(ctx)
|
|
assert.strictEqual(err, assertError)
|
|
assert.strictEqual(ctx, checkMiddleCtx)
|
|
assert.strictEqual(ctx.params, assertParams)
|
|
cb()
|
|
} catch (err) { cb(err) }
|
|
}
|
|
|
|
flaska.requestStart(createReq({
|
|
url: '',
|
|
method: 'GET',
|
|
}), createRes({}))
|
|
})
|
|
|
|
t.test('calls route handler correctly', function(cb) {
|
|
const assertError = new Error('test')
|
|
let checkHandlerCtx = null
|
|
let handler = function(ctx) {
|
|
assert.strictEqual(ctx.params.id, 'test')
|
|
checkHandlerCtx = ctx
|
|
throw assertError
|
|
}
|
|
|
|
let flaska = new Flaska({}, faker)
|
|
flaska.get('/:id', handler)
|
|
flaska.compile()
|
|
|
|
flaska.requestEnd = function(err, ctx) {
|
|
if (err && err !== assertError) return cb(err)
|
|
|
|
try {
|
|
assert.ok(err)
|
|
assert.ok(ctx)
|
|
assert.strictEqual(err, assertError)
|
|
assert.strictEqual(ctx, checkHandlerCtx)
|
|
cb()
|
|
} catch (err) { cb(err) }
|
|
}
|
|
|
|
flaska.requestStart(createReq({
|
|
url: '/test',
|
|
method: 'GET',
|
|
}), createRes())
|
|
})
|
|
|
|
t.test('calls 404 if route handler is not found', function(cb) {
|
|
const on404Error = spy()
|
|
|
|
let handler = function() {
|
|
throw new Error('should not be called')
|
|
}
|
|
|
|
let flaska = new Flaska({}, faker)
|
|
flaska.on404(on404Error)
|
|
flaska.get('/test', function() { throw new Error('should not be called') })
|
|
flaska.compile()
|
|
|
|
flaska.requestEnd = function(err, ctx) {
|
|
if (err) return cb(err)
|
|
|
|
try {
|
|
assert.ok(ctx)
|
|
assert.strictEqual(on404Error.callCount, 1)
|
|
assert.strictEqual(on404Error.firstCall[0], ctx)
|
|
cb()
|
|
} catch (err) { cb(err) }
|
|
}
|
|
|
|
flaska.requestStart(createReq({
|
|
url: '/nope',
|
|
method: 'GET',
|
|
}), createRes())
|
|
})
|
|
|
|
t.test('calls 404 if route handler is not found and supports promise', function(cb) {
|
|
let checkCtx = null
|
|
const assertError = new Error('should be seen')
|
|
const on404Error = function(ctx) {
|
|
checkCtx = ctx
|
|
return Promise.resolve().then(function() { return Promise.reject(assertError) })
|
|
}
|
|
|
|
let flaska = new Flaska({}, faker)
|
|
flaska.on404(on404Error)
|
|
flaska.get('/test', function() { throw new Error('should not be called') })
|
|
flaska.compile()
|
|
|
|
flaska.requestEnd = function(err, ctx) {
|
|
if (err && err !== assertError) return cb(err)
|
|
|
|
try {
|
|
assert.ok(err)
|
|
assert.ok(ctx)
|
|
assert.strictEqual(ctx, checkCtx)
|
|
assert.strictEqual(err, assertError)
|
|
cb()
|
|
} catch (err) { cb(err) }
|
|
}
|
|
|
|
flaska.requestStart(createReq({
|
|
url: '/nope',
|
|
method: 'GET',
|
|
}), createRes())
|
|
})
|
|
|
|
t.test(`should handle unexpected errors in on404 correctly`, function(cb) {
|
|
const assertError = new Error('should be seen')
|
|
let checkCtx = null
|
|
|
|
let flaska = new Flaska({}, faker)
|
|
flaska.on404(function(ctx) {
|
|
checkCtx = ctx
|
|
throw assertError
|
|
})
|
|
flaska.get('/test', function() { throw new Error('should not be called') })
|
|
flaska.compile()
|
|
|
|
flaska.requestEnd = function(err, ctx) {
|
|
if (err && err !== assertError) return cb(err)
|
|
|
|
try {
|
|
assert.ok(err)
|
|
assert.ok(ctx)
|
|
assert.strictEqual(ctx, checkCtx)
|
|
assert.strictEqual(err, assertError)
|
|
cb()
|
|
} catch (err) { cb(err) }
|
|
}
|
|
|
|
flaska.requestStart(createReq({
|
|
url: '/nope',
|
|
method: 'GET',
|
|
}), createRes())
|
|
})
|
|
|
|
t.test(`should handle unexpected errors in middleware correctly`, function(cb) {
|
|
const assertError = new Error('should be seen')
|
|
let checkCtx = null
|
|
|
|
let flaska = new Flaska({}, faker)
|
|
let middles = [function(ctx) {
|
|
checkCtx = ctx
|
|
throw assertError
|
|
}]
|
|
flaska.get('/test', middles, function() { throw new Error('should not be called') })
|
|
flaska.compile()
|
|
|
|
flaska.requestEnd = function(err, ctx) {
|
|
if (err && err !== assertError) return cb(err)
|
|
|
|
try {
|
|
assert.ok(err)
|
|
assert.ok(ctx)
|
|
assert.strictEqual(ctx, checkCtx)
|
|
assert.strictEqual(err, assertError)
|
|
cb()
|
|
} catch (err) { cb(err) }
|
|
}
|
|
|
|
flaska.requestStart(createReq({
|
|
url: '/test',
|
|
method: 'GET',
|
|
}), createRes())
|
|
})
|
|
|
|
t.test('should work with synchronous handler', function(cb) {
|
|
const assertBody = { a: 1 }
|
|
let handler = function(ctx) {
|
|
assert.strictEqual(ctx.params.path, 'test/something/here')
|
|
ctx.body = assertBody
|
|
}
|
|
|
|
let flaska = new Flaska({}, faker)
|
|
flaska.get('/::path', handler)
|
|
flaska.compile()
|
|
flaska.handleMiddleware = function() {
|
|
throw new Error('should not be called')
|
|
}
|
|
|
|
flaska.requestEnd = function(err, ctx) {
|
|
try {
|
|
assert.notOk(err)
|
|
assert.ok(ctx)
|
|
assert.strictEqual(ctx.body, assertBody)
|
|
cb()
|
|
} catch (err) { cb(err) }
|
|
}
|
|
|
|
flaska.requestStart(createReq({
|
|
url: '/test/something/here',
|
|
method: 'GET',
|
|
}), createRes())
|
|
})
|
|
|
|
t.test('calls handleMiddleware correctly if is promise', function(cb) {
|
|
const assertError = new Error('test')
|
|
const assertMiddles = [1]
|
|
|
|
let flaska = new Flaska({}, faker)
|
|
flaska.compile()
|
|
|
|
flaska.routers.GET.match = function() {
|
|
return {
|
|
handler: function() {},
|
|
middlewares: assertMiddles,
|
|
}
|
|
}
|
|
flaska.handleMiddleware = function() {
|
|
return Promise.resolve().then(function() { return Promise.reject(assertError) })
|
|
}
|
|
|
|
flaska.requestEnd = function(err, ctx) {
|
|
if (err && err !== assertError) return cb(err)
|
|
|
|
try {
|
|
assert.ok(err)
|
|
assert.ok(ctx)
|
|
assert.strictEqual(err, assertError)
|
|
cb()
|
|
} catch (err) { cb(err) }
|
|
}
|
|
|
|
flaska.requestStart(createReq({
|
|
url: '',
|
|
method: 'GET',
|
|
}), createRes())
|
|
})
|
|
|
|
t.test('calls route handler correctly with promise middle', function(cb) {
|
|
const assertError = new Error('test')
|
|
let checkHandlerCtx = null
|
|
let handler = function(ctx) {
|
|
assert.strictEqual(ctx.params.id, 'test')
|
|
checkHandlerCtx = ctx
|
|
throw assertError
|
|
}
|
|
|
|
let flaska = new Flaska({}, faker)
|
|
flaska.get('/:id', [function() { return Promise.resolve() }], handler)
|
|
flaska.compile()
|
|
|
|
flaska.requestEnd = function(err, ctx) {
|
|
if (err && err !== assertError) return cb(err)
|
|
|
|
try {
|
|
assert.ok(err)
|
|
assert.ok(ctx)
|
|
assert.strictEqual(err, assertError)
|
|
assert.strictEqual(ctx, checkHandlerCtx)
|
|
cb()
|
|
} catch (err) { cb(err) }
|
|
}
|
|
|
|
flaska.requestStart(createReq({
|
|
url: '/test',
|
|
method: 'GET',
|
|
}), createRes())
|
|
})
|
|
|
|
t.test('calls promise route handler correctly with promise middle', function(cb) {
|
|
const assertError = new Error('test')
|
|
let checkHandlerCtx = null
|
|
let handler = function(ctx) {
|
|
assert.strictEqual(ctx.params.id, 'test')
|
|
checkHandlerCtx = ctx
|
|
return Promise.resolve().then(function() { return Promise.reject(assertError) })
|
|
}
|
|
|
|
let flaska = new Flaska({}, faker)
|
|
flaska.get('/:id', [function() { return Promise.resolve() }], handler)
|
|
flaska.compile()
|
|
|
|
flaska.requestEnd = function(err, ctx) {
|
|
if (err && err !== assertError) return cb(err)
|
|
|
|
try {
|
|
assert.ok(err)
|
|
assert.ok(ctx)
|
|
assert.strictEqual(err, assertError)
|
|
assert.strictEqual(ctx, checkHandlerCtx)
|
|
cb()
|
|
} catch (err) { cb(err) }
|
|
}
|
|
|
|
flaska.requestStart(createReq({
|
|
url: '/test',
|
|
method: 'GET',
|
|
}), createRes())
|
|
})
|
|
|
|
t.test('should work with promise middle and promise handler correctly', function(cb) {
|
|
const assertBody = { a: 1 }
|
|
const assertState = { b: 2 }
|
|
let middle = function(ctx) {
|
|
return Promise.resolve().then(function() {
|
|
ctx.state = assertState
|
|
})
|
|
}
|
|
let handler = function(ctx) {
|
|
assert.strictEqual(ctx.params.path, 'test/something/here')
|
|
assert.strictEqual(ctx.state, assertState)
|
|
|
|
return Promise.resolve().then(function() {
|
|
ctx.body = assertBody
|
|
})
|
|
}
|
|
|
|
let flaska = new Flaska({}, faker)
|
|
flaska.get('/::path', [middle], handler)
|
|
flaska.compile()
|
|
|
|
flaska.requestEnd = function(err, ctx) {
|
|
try {
|
|
assert.notOk(err)
|
|
assert.ok(ctx)
|
|
assert.strictEqual(ctx.body, assertBody)
|
|
assert.strictEqual(ctx.state, assertState)
|
|
cb()
|
|
} catch (err) { cb(err) }
|
|
}
|
|
|
|
flaska.requestStart(createReq({
|
|
url: '/test/something/here',
|
|
method: 'GET',
|
|
}), createRes())
|
|
})
|
|
|
|
t.test('calls route handler correctly if promise', function(cb) {
|
|
const assertError = new Error('test')
|
|
let checkHandlerCtx = null
|
|
let handler = function(ctx) {
|
|
assert.strictEqual(ctx.params.id, 'test')
|
|
checkHandlerCtx = ctx
|
|
return Promise.resolve().then(function() {
|
|
return Promise.reject(assertError)
|
|
})
|
|
}
|
|
|
|
let flaska = new Flaska({}, faker)
|
|
flaska.get('/:id', handler)
|
|
flaska.compile()
|
|
|
|
flaska.requestEnd = function(err, ctx) {
|
|
if (err && err !== assertError) return cb(err)
|
|
|
|
try {
|
|
assert.ok(err)
|
|
assert.ok(ctx)
|
|
assert.strictEqual(err, assertError)
|
|
assert.strictEqual(ctx, checkHandlerCtx)
|
|
cb()
|
|
} catch (err) { cb(err) }
|
|
}
|
|
|
|
flaska.requestStart(createReq({
|
|
url: '/test',
|
|
method: 'GET',
|
|
}), createRes())
|
|
})
|
|
|
|
t.test('should work with promise handler', function(cb) {
|
|
const assertBody = { a: 1 }
|
|
let handler = function(ctx) {
|
|
return Promise.resolve().then(function() {
|
|
assert.strictEqual(ctx.params.path, 'test/something/here')
|
|
ctx.body = assertBody
|
|
})
|
|
}
|
|
|
|
let flaska = new Flaska({}, faker)
|
|
flaska.get('/::path', [], handler)
|
|
flaska.compile()
|
|
|
|
flaska.handleMiddleware = function() {
|
|
throw new Error('should not be called')
|
|
}
|
|
|
|
flaska.requestEnd = function(err, ctx) {
|
|
try {
|
|
assert.notOk(err)
|
|
assert.ok(ctx)
|
|
assert.strictEqual(ctx.body, assertBody)
|
|
cb()
|
|
} catch (err) { cb(err) }
|
|
}
|
|
|
|
flaska.requestStart(createReq({
|
|
url: '/test/something/here',
|
|
method: 'GET',
|
|
}), createRes())
|
|
})
|
|
})
|