You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
424 lines
8.5 KiB
424 lines
8.5 KiB
3 years ago
|
'use strict'
|
||
|
|
||
|
const { test } = require('tap')
|
||
|
const boot = require('..')
|
||
|
const { promisify } = require('util')
|
||
|
const sleep = promisify(setTimeout)
|
||
|
const fs = require('fs').promises
|
||
|
const path = require('path')
|
||
|
|
||
|
test('await after - nested plugins with same tick callbacks', async (t) => {
|
||
|
const app = {}
|
||
|
boot(app)
|
||
|
|
||
|
let secondLoaded = false
|
||
|
|
||
|
app.use(async (app) => {
|
||
|
t.pass('plugin init')
|
||
|
app.use(async () => {
|
||
|
t.pass('plugin2 init')
|
||
|
await sleep(1)
|
||
|
secondLoaded = true
|
||
|
})
|
||
|
})
|
||
|
await app.after()
|
||
|
t.pass('reachable')
|
||
|
t.equal(secondLoaded, true)
|
||
|
|
||
|
await app.ready()
|
||
|
t.pass('reachable')
|
||
|
})
|
||
|
|
||
|
test('await after without server', async (t) => {
|
||
|
const app = boot()
|
||
|
|
||
|
let secondLoaded = false
|
||
|
|
||
|
app.use(async (app) => {
|
||
|
t.pass('plugin init')
|
||
|
app.use(async () => {
|
||
|
t.pass('plugin2 init')
|
||
|
await sleep(1)
|
||
|
secondLoaded = true
|
||
|
})
|
||
|
})
|
||
|
await app.after()
|
||
|
t.pass('reachable')
|
||
|
t.equal(secondLoaded, true)
|
||
|
|
||
|
await app.ready()
|
||
|
t.pass('reachable')
|
||
|
})
|
||
|
|
||
|
test('await after - nested plugins with future tick callbacks', async (t) => {
|
||
|
const app = {}
|
||
|
boot(app)
|
||
|
|
||
|
t.plan(4)
|
||
|
|
||
|
app.use((f, opts, cb) => {
|
||
|
t.pass('plugin init')
|
||
|
app.use((f, opts, cb) => {
|
||
|
t.pass('plugin2 init')
|
||
|
setImmediate(cb)
|
||
|
})
|
||
|
setImmediate(cb)
|
||
|
})
|
||
|
await app.after()
|
||
|
t.pass('reachable')
|
||
|
|
||
|
await app.ready()
|
||
|
t.pass('reachable')
|
||
|
})
|
||
|
|
||
|
test('await after - nested async function plugins', async (t) => {
|
||
|
const app = {}
|
||
|
boot(app)
|
||
|
|
||
|
t.plan(5)
|
||
|
|
||
|
app.use(async (f, opts) => {
|
||
|
t.pass('plugin init')
|
||
|
await app.use(async (f, opts) => {
|
||
|
t.pass('plugin2 init')
|
||
|
})
|
||
|
t.pass('reachable')
|
||
|
})
|
||
|
await app.after()
|
||
|
t.pass('reachable')
|
||
|
|
||
|
await app.ready()
|
||
|
t.pass('reachable')
|
||
|
})
|
||
|
|
||
|
test('await after - promise resolves to undefined', async (t) => {
|
||
|
const app = {}
|
||
|
boot(app)
|
||
|
|
||
|
t.plan(4)
|
||
|
|
||
|
app.use(async (f, opts, cb) => {
|
||
|
app.use((f, opts, cb) => {
|
||
|
t.pass('plugin init')
|
||
|
cb()
|
||
|
})
|
||
|
const instance = await app.after()
|
||
|
t.equal(instance, undefined)
|
||
|
})
|
||
|
t.pass('reachable')
|
||
|
|
||
|
await app.ready()
|
||
|
t.pass('reachable')
|
||
|
})
|
||
|
|
||
|
test('await after - promise returning function plugins + promise chaining', async (t) => {
|
||
|
const app = {}
|
||
|
boot(app)
|
||
|
|
||
|
t.plan(6)
|
||
|
|
||
|
app.use((f, opts) => {
|
||
|
t.pass('plugin init')
|
||
|
return app.use((f, opts) => {
|
||
|
t.pass('plugin2 init')
|
||
|
return Promise.resolve()
|
||
|
}).then((f2) => {
|
||
|
t.equal(f2, f)
|
||
|
return 'test'
|
||
|
}).then((val) => {
|
||
|
t.equal(val, 'test')
|
||
|
})
|
||
|
})
|
||
|
await app.after()
|
||
|
t.pass('reachable')
|
||
|
|
||
|
await app.ready()
|
||
|
t.pass('reachable')
|
||
|
})
|
||
|
|
||
|
test('await after - error handling, async throw', async (t) => {
|
||
|
const app = {}
|
||
|
boot(app)
|
||
|
|
||
|
t.plan(2)
|
||
|
|
||
|
const e = new Error('kaboom')
|
||
|
|
||
|
app.use(async (f, opts) => {
|
||
|
throw Error('kaboom')
|
||
|
})
|
||
|
|
||
|
await t.rejects(app.after(), e)
|
||
|
|
||
|
await t.rejects(() => app.ready(), Error('kaboom'))
|
||
|
})
|
||
|
|
||
|
test('await after - error handling, async throw, nested', async (t) => {
|
||
|
const app = {}
|
||
|
boot(app)
|
||
|
|
||
|
t.plan(2)
|
||
|
|
||
|
const e = new Error('kaboom')
|
||
|
|
||
|
app.use(async (f, opts) => {
|
||
|
app.use(async (f, opts) => {
|
||
|
throw e
|
||
|
})
|
||
|
})
|
||
|
|
||
|
await t.rejects(app.after())
|
||
|
await t.rejects(() => app.ready(), e)
|
||
|
})
|
||
|
|
||
|
test('await after - error handling, same tick cb err', async (t) => {
|
||
|
const app = {}
|
||
|
boot(app)
|
||
|
|
||
|
t.plan(2)
|
||
|
|
||
|
app.use((f, opts, cb) => {
|
||
|
cb(Error('kaboom'))
|
||
|
})
|
||
|
await t.rejects(app.after())
|
||
|
await t.rejects(app.ready(), Error('kaboom'))
|
||
|
})
|
||
|
|
||
|
test('await after - error handling, same tick cb err, nested', async (t) => {
|
||
|
const app = {}
|
||
|
boot(app)
|
||
|
|
||
|
t.plan(2)
|
||
|
|
||
|
app.use((f, opts, cb) => {
|
||
|
app.use((f, opts, cb) => {
|
||
|
cb(Error('kaboom'))
|
||
|
})
|
||
|
cb()
|
||
|
})
|
||
|
|
||
|
await t.rejects(app.after())
|
||
|
await t.rejects(app.ready(), Error('kaboom'))
|
||
|
})
|
||
|
|
||
|
test('await after - error handling, future tick cb err', async (t) => {
|
||
|
const app = {}
|
||
|
boot(app)
|
||
|
|
||
|
t.plan(2)
|
||
|
|
||
|
app.use((f, opts, cb) => {
|
||
|
setImmediate(() => { cb(Error('kaboom')) })
|
||
|
})
|
||
|
|
||
|
await t.rejects(app.after())
|
||
|
await t.rejects(app.ready(), Error('kaboom'))
|
||
|
})
|
||
|
|
||
|
test('await after - error handling, future tick cb err, nested', async (t) => {
|
||
|
const app = {}
|
||
|
boot(app)
|
||
|
|
||
|
t.plan(2)
|
||
|
|
||
|
app.use((f, opts, cb) => {
|
||
|
app.use((f, opts, cb) => {
|
||
|
setImmediate(() => { cb(Error('kaboom')) })
|
||
|
})
|
||
|
cb()
|
||
|
})
|
||
|
await t.rejects(app.after(), Error('kaboom'))
|
||
|
await t.rejects(app.ready(), Error('kaboom'))
|
||
|
})
|
||
|
|
||
|
test('await after complex scenario', async (t) => {
|
||
|
const app = {}
|
||
|
boot(app)
|
||
|
t.plan(16)
|
||
|
|
||
|
let firstLoaded = false
|
||
|
let secondLoaded = false
|
||
|
let thirdLoaded = false
|
||
|
let fourthLoaded = false
|
||
|
|
||
|
app.use(first)
|
||
|
await app.after()
|
||
|
t.ok(firstLoaded, 'first is loaded')
|
||
|
t.notOk(secondLoaded, 'second is not loaded')
|
||
|
t.notOk(thirdLoaded, 'third is not loaded')
|
||
|
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||
|
app.use(second)
|
||
|
t.ok(firstLoaded, 'first is loaded')
|
||
|
t.notOk(secondLoaded, 'second is not loaded')
|
||
|
t.notOk(thirdLoaded, 'third is not loaded')
|
||
|
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||
|
app.use(third)
|
||
|
await app.after()
|
||
|
t.ok(firstLoaded, 'first is loaded')
|
||
|
t.ok(secondLoaded, 'second is loaded')
|
||
|
t.ok(thirdLoaded, 'third is loaded')
|
||
|
t.ok(fourthLoaded, 'fourth is loaded')
|
||
|
await app.ready()
|
||
|
t.ok(firstLoaded, 'first is loaded')
|
||
|
t.ok(secondLoaded, 'second is loaded')
|
||
|
t.ok(thirdLoaded, 'third is loaded')
|
||
|
t.ok(fourthLoaded, 'fourth is loaded')
|
||
|
|
||
|
async function first () {
|
||
|
firstLoaded = true
|
||
|
}
|
||
|
|
||
|
async function second () {
|
||
|
secondLoaded = true
|
||
|
}
|
||
|
|
||
|
async function third (app) {
|
||
|
thirdLoaded = true
|
||
|
app.use(fourth)
|
||
|
}
|
||
|
|
||
|
async function fourth () {
|
||
|
fourthLoaded = true
|
||
|
}
|
||
|
})
|
||
|
|
||
|
test('without autostart and sync/async plugin mix', async (t) => {
|
||
|
const app = {}
|
||
|
boot(app, { autostart: false })
|
||
|
t.plan(21)
|
||
|
|
||
|
let firstLoaded = false
|
||
|
let secondLoaded = false
|
||
|
let thirdLoaded = false
|
||
|
let fourthLoaded = false
|
||
|
|
||
|
app.use(first)
|
||
|
await app.after()
|
||
|
t.ok(firstLoaded, 'first is loaded')
|
||
|
t.notOk(secondLoaded, 'second is not loaded')
|
||
|
t.notOk(thirdLoaded, 'third is not loaded')
|
||
|
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||
|
|
||
|
app.use(second)
|
||
|
await app.after()
|
||
|
t.ok(firstLoaded, 'first is loaded')
|
||
|
t.ok(secondLoaded, 'second is loaded')
|
||
|
t.notOk(thirdLoaded, 'third is not loaded')
|
||
|
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||
|
|
||
|
await sleep(10)
|
||
|
|
||
|
app.use(third)
|
||
|
await app.after()
|
||
|
t.ok(firstLoaded, 'first is loaded')
|
||
|
t.ok(secondLoaded, 'second is loaded')
|
||
|
t.ok(thirdLoaded, 'third is loaded')
|
||
|
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||
|
|
||
|
app.use(fourth)
|
||
|
t.ok(firstLoaded, 'first is loaded')
|
||
|
t.ok(secondLoaded, 'second is loaded')
|
||
|
t.ok(thirdLoaded, 'third is loaded')
|
||
|
t.notOk(fourthLoaded, 'fourth is not loaded')
|
||
|
|
||
|
await app.after()
|
||
|
t.ok(firstLoaded, 'first is loaded')
|
||
|
t.ok(secondLoaded, 'second is loaded')
|
||
|
t.ok(thirdLoaded, 'third is loaded')
|
||
|
t.ok(fourthLoaded, 'fourth is loaded')
|
||
|
|
||
|
await app.ready()
|
||
|
|
||
|
async function first () {
|
||
|
firstLoaded = true
|
||
|
}
|
||
|
|
||
|
async function second () {
|
||
|
const contents = await fs.readFile(path.join(__dirname, 'fixtures', 'dummy.txt'), 'utf-8')
|
||
|
t.equal(contents, 'hello, world!')
|
||
|
secondLoaded = true
|
||
|
}
|
||
|
|
||
|
async function third () {
|
||
|
await sleep(10)
|
||
|
thirdLoaded = true
|
||
|
}
|
||
|
|
||
|
function fourth (server, opts, done) {
|
||
|
fourthLoaded = true
|
||
|
done()
|
||
|
}
|
||
|
})
|
||
|
|
||
|
test('without autostart', async (t) => {
|
||
|
const app = {}
|
||
|
boot(app, { autostart: false })
|
||
|
let firstLoaded = false
|
||
|
let secondLoaded = false
|
||
|
let thirdLoaded = false
|
||
|
|
||
|
app.use(async function first (app) {
|
||
|
firstLoaded = true
|
||
|
app.use(async () => {
|
||
|
await sleep(1)
|
||
|
secondLoaded = true
|
||
|
})
|
||
|
})
|
||
|
|
||
|
await app.after()
|
||
|
t.equal(firstLoaded, true)
|
||
|
t.equal(secondLoaded, true)
|
||
|
|
||
|
await app.use(async () => {
|
||
|
thirdLoaded = true
|
||
|
})
|
||
|
|
||
|
t.equal(thirdLoaded, true)
|
||
|
|
||
|
await app.ready()
|
||
|
})
|
||
|
|
||
|
test('without autostart and with override', async (t) => {
|
||
|
const app = {}
|
||
|
const _ = boot(app, { autostart: false })
|
||
|
let count = 0
|
||
|
|
||
|
_.override = function (s) {
|
||
|
const res = Object.create(s)
|
||
|
res.count = ++count
|
||
|
|
||
|
return res
|
||
|
}
|
||
|
|
||
|
app.use(async function first (app) {
|
||
|
t.equal(app.count, 1)
|
||
|
app.use(async (app) => {
|
||
|
t.equal(app.count, 2)
|
||
|
await app.after()
|
||
|
})
|
||
|
})
|
||
|
|
||
|
await app.after()
|
||
|
|
||
|
await app.use(async (app) => {
|
||
|
t.equal(app.count, 3)
|
||
|
})
|
||
|
|
||
|
await app.ready()
|
||
|
})
|
||
|
|
||
|
test('stop processing after errors', async (t) => {
|
||
|
t.plan(2)
|
||
|
|
||
|
const app = boot()
|
||
|
|
||
|
try {
|
||
|
await app.use(async function first (app) {
|
||
|
t.pass('first should be loaded')
|
||
|
throw new Error('kaboom')
|
||
|
})
|
||
|
} catch (e) {
|
||
|
t.equal(e.message, 'kaboom')
|
||
|
}
|
||
|
})
|