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.
		
		
		
		
		
			
		
			
				
					308 lines
				
				7.2 KiB
			
		
		
			
		
	
	
					308 lines
				
				7.2 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'use strict'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* eslint no-prototype-builtins: off */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const test = require('tap').test
							 | 
						||
| 
								 | 
							
								const sleep = require('then-sleep')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const boot = require('..')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('one level', async (t) => {
							 | 
						||
| 
								 | 
							
								  t.plan(14)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const app = boot()
							 | 
						||
| 
								 | 
							
								  let firstLoaded = false
							 | 
						||
| 
								 | 
							
								  let secondLoaded = false
							 | 
						||
| 
								 | 
							
								  let thirdLoaded = false
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  app.use(first)
							 | 
						||
| 
								 | 
							
								  app.use(third)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  async function first (s, opts) {
							 | 
						||
| 
								 | 
							
								    t.notOk(firstLoaded, 'first is not loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(secondLoaded, 'second is not loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(thirdLoaded, 'third is not loaded')
							 | 
						||
| 
								 | 
							
								    firstLoaded = true
							 | 
						||
| 
								 | 
							
								    s.use(second)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  async function second (s, opts) {
							 | 
						||
| 
								 | 
							
								    t.ok(firstLoaded, 'first is loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(secondLoaded, 'second is not loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(thirdLoaded, 'third is not loaded')
							 | 
						||
| 
								 | 
							
								    secondLoaded = true
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  async function third (s, opts) {
							 | 
						||
| 
								 | 
							
								    t.ok(firstLoaded, 'first is loaded')
							 | 
						||
| 
								 | 
							
								    t.ok(secondLoaded, 'second is loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(thirdLoaded, 'third is not loaded')
							 | 
						||
| 
								 | 
							
								    thirdLoaded = true
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const readyContext = await app.ready()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  t.equal(app, readyContext)
							 | 
						||
| 
								 | 
							
								  t.ok(firstLoaded, 'first is loaded')
							 | 
						||
| 
								 | 
							
								  t.ok(secondLoaded, 'second is loaded')
							 | 
						||
| 
								 | 
							
								  t.ok(thirdLoaded, 'third is loaded')
							 | 
						||
| 
								 | 
							
								  t.pass('booted')
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('multiple reentrant plugin loading', async (t) => {
							 | 
						||
| 
								 | 
							
								  t.plan(31)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const app = boot()
							 | 
						||
| 
								 | 
							
								  let firstLoaded = false
							 | 
						||
| 
								 | 
							
								  let secondLoaded = false
							 | 
						||
| 
								 | 
							
								  let thirdLoaded = false
							 | 
						||
| 
								 | 
							
								  let fourthLoaded = false
							 | 
						||
| 
								 | 
							
								  let fifthLoaded = false
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  app.use(first)
							 | 
						||
| 
								 | 
							
								  app.use(fifth)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  async function first (s, opts) {
							 | 
						||
| 
								 | 
							
								    t.notOk(firstLoaded, 'first is not loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(secondLoaded, 'second is not loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(thirdLoaded, 'third is not loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(fourthLoaded, 'fourth is not loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(fifthLoaded, 'fifth is not loaded')
							 | 
						||
| 
								 | 
							
								    firstLoaded = true
							 | 
						||
| 
								 | 
							
								    s.use(second)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  async function second (s, opts) {
							 | 
						||
| 
								 | 
							
								    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')
							 | 
						||
| 
								 | 
							
								    t.notOk(fifthLoaded, 'fifth is not loaded')
							 | 
						||
| 
								 | 
							
								    secondLoaded = true
							 | 
						||
| 
								 | 
							
								    s.use(third)
							 | 
						||
| 
								 | 
							
								    await sleep(10)
							 | 
						||
| 
								 | 
							
								    s.use(fourth)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  async function third (s, opts) {
							 | 
						||
| 
								 | 
							
								    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')
							 | 
						||
| 
								 | 
							
								    t.notOk(fifthLoaded, 'fifth is not loaded')
							 | 
						||
| 
								 | 
							
								    thirdLoaded = true
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  async function fourth (s, opts) {
							 | 
						||
| 
								 | 
							
								    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')
							 | 
						||
| 
								 | 
							
								    t.notOk(fifthLoaded, 'fifth is not loaded')
							 | 
						||
| 
								 | 
							
								    fourthLoaded = true
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  async function fifth (s, opts) {
							 | 
						||
| 
								 | 
							
								    t.ok(firstLoaded, 'first is loaded')
							 | 
						||
| 
								 | 
							
								    t.ok(secondLoaded, 'second is loaded')
							 | 
						||
| 
								 | 
							
								    t.ok(thirdLoaded, 'third is loaded')
							 | 
						||
| 
								 | 
							
								    t.ok(fourthLoaded, 'fourth is loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(fifthLoaded, 'fifth is not loaded')
							 | 
						||
| 
								 | 
							
								    fifthLoaded = true
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  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')
							 | 
						||
| 
								 | 
							
								  t.ok(fifthLoaded, 'fifth is loaded')
							 | 
						||
| 
								 | 
							
								  t.pass('booted')
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('async ready plugin registration (errored)', async (t) => {
							 | 
						||
| 
								 | 
							
								  t.plan(1)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const app = boot()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  app.use(async (server, opts) => {
							 | 
						||
| 
								 | 
							
								    await sleep(10)
							 | 
						||
| 
								 | 
							
								    throw new Error('kaboom')
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  try {
							 | 
						||
| 
								 | 
							
								    await app.ready()
							 | 
						||
| 
								 | 
							
								    t.fail('we should not be here')
							 | 
						||
| 
								 | 
							
								  } catch (err) {
							 | 
						||
| 
								 | 
							
								    t.equal(err.message, 'kaboom')
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('after', async (t) => {
							 | 
						||
| 
								 | 
							
								  t.plan(15)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const app = boot()
							 | 
						||
| 
								 | 
							
								  let firstLoaded = false
							 | 
						||
| 
								 | 
							
								  let secondLoaded = false
							 | 
						||
| 
								 | 
							
								  let thirdLoaded = false
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  app.use(first)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  async function first (s, opts) {
							 | 
						||
| 
								 | 
							
								    t.notOk(firstLoaded, 'first is not loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(secondLoaded, 'second is not loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(thirdLoaded, 'third is not loaded')
							 | 
						||
| 
								 | 
							
								    firstLoaded = true
							 | 
						||
| 
								 | 
							
								    s.after(second)
							 | 
						||
| 
								 | 
							
								    s.after(third)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  async function second (err) {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.ok(firstLoaded, 'first is loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(secondLoaded, 'second is not loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(thirdLoaded, 'third is not loaded')
							 | 
						||
| 
								 | 
							
								    await sleep(10)
							 | 
						||
| 
								 | 
							
								    secondLoaded = true
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  async function third () {
							 | 
						||
| 
								 | 
							
								    t.ok(firstLoaded, 'first is loaded')
							 | 
						||
| 
								 | 
							
								    t.ok(secondLoaded, 'second is loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(thirdLoaded, 'third is not loaded')
							 | 
						||
| 
								 | 
							
								    await sleep(10)
							 | 
						||
| 
								 | 
							
								    thirdLoaded = true
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const readyContext = await app.ready()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  t.equal(app, readyContext)
							 | 
						||
| 
								 | 
							
								  t.ok(firstLoaded, 'first is loaded')
							 | 
						||
| 
								 | 
							
								  t.ok(secondLoaded, 'second is loaded')
							 | 
						||
| 
								 | 
							
								  t.ok(thirdLoaded, 'third is loaded')
							 | 
						||
| 
								 | 
							
								  t.pass('booted')
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('after wrapped', async (t) => {
							 | 
						||
| 
								 | 
							
								  t.plan(15)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const app = {}
							 | 
						||
| 
								 | 
							
								  boot(app)
							 | 
						||
| 
								 | 
							
								  let firstLoaded = false
							 | 
						||
| 
								 | 
							
								  let secondLoaded = false
							 | 
						||
| 
								 | 
							
								  let thirdLoaded = false
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  app.use(first)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  async function first (s, opts) {
							 | 
						||
| 
								 | 
							
								    t.notOk(firstLoaded, 'first is not loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(secondLoaded, 'second is not loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(thirdLoaded, 'third is not loaded')
							 | 
						||
| 
								 | 
							
								    firstLoaded = true
							 | 
						||
| 
								 | 
							
								    s.after(second)
							 | 
						||
| 
								 | 
							
								    s.after(third)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  async function second (err) {
							 | 
						||
| 
								 | 
							
								    t.error(err)
							 | 
						||
| 
								 | 
							
								    t.ok(firstLoaded, 'first is loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(secondLoaded, 'second is not loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(thirdLoaded, 'third is not loaded')
							 | 
						||
| 
								 | 
							
								    await sleep(10)
							 | 
						||
| 
								 | 
							
								    secondLoaded = true
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  async function third () {
							 | 
						||
| 
								 | 
							
								    t.ok(firstLoaded, 'first is loaded')
							 | 
						||
| 
								 | 
							
								    t.ok(secondLoaded, 'second is loaded')
							 | 
						||
| 
								 | 
							
								    t.notOk(thirdLoaded, 'third is not loaded')
							 | 
						||
| 
								 | 
							
								    await sleep(10)
							 | 
						||
| 
								 | 
							
								    thirdLoaded = true
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const readyContext = await app.ready()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  t.equal(app, readyContext)
							 | 
						||
| 
								 | 
							
								  t.ok(firstLoaded, 'first is loaded')
							 | 
						||
| 
								 | 
							
								  t.ok(secondLoaded, 'second is loaded')
							 | 
						||
| 
								 | 
							
								  t.ok(thirdLoaded, 'third is loaded')
							 | 
						||
| 
								 | 
							
								  t.pass('booted')
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('promise plugins', async (t) => {
							 | 
						||
| 
								 | 
							
								  t.plan(14)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const app = boot()
							 | 
						||
| 
								 | 
							
								  let firstLoaded = false
							 | 
						||
| 
								 | 
							
								  let secondLoaded = false
							 | 
						||
| 
								 | 
							
								  let thirdLoaded = false
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  app.use(first())
							 | 
						||
| 
								 | 
							
								  app.use(third())
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  async function first () {
							 | 
						||
| 
								 | 
							
								    return async function (s, opts) {
							 | 
						||
| 
								 | 
							
								      t.notOk(firstLoaded, 'first is not loaded')
							 | 
						||
| 
								 | 
							
								      t.notOk(secondLoaded, 'second is not loaded')
							 | 
						||
| 
								 | 
							
								      t.notOk(thirdLoaded, 'third is not loaded')
							 | 
						||
| 
								 | 
							
								      firstLoaded = true
							 | 
						||
| 
								 | 
							
								      s.use(second())
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  async function second () {
							 | 
						||
| 
								 | 
							
								    return async function (s, opts) {
							 | 
						||
| 
								 | 
							
								      t.ok(firstLoaded, 'first is loaded')
							 | 
						||
| 
								 | 
							
								      t.notOk(secondLoaded, 'second is not loaded')
							 | 
						||
| 
								 | 
							
								      t.notOk(thirdLoaded, 'third is not loaded')
							 | 
						||
| 
								 | 
							
								      secondLoaded = true
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  async function third () {
							 | 
						||
| 
								 | 
							
								    return async function (s, opts) {
							 | 
						||
| 
								 | 
							
								      t.ok(firstLoaded, 'first is loaded')
							 | 
						||
| 
								 | 
							
								      t.ok(secondLoaded, 'second is loaded')
							 | 
						||
| 
								 | 
							
								      t.notOk(thirdLoaded, 'third is not loaded')
							 | 
						||
| 
								 | 
							
								      thirdLoaded = true
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const readyContext = await app.ready()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  t.equal(app, readyContext)
							 | 
						||
| 
								 | 
							
								  t.ok(firstLoaded, 'first is loaded')
							 | 
						||
| 
								 | 
							
								  t.ok(secondLoaded, 'second is loaded')
							 | 
						||
| 
								 | 
							
								  t.ok(thirdLoaded, 'third is loaded')
							 | 
						||
| 
								 | 
							
								  t.pass('booted')
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test('skip override with promise', (t) => {
							 | 
						||
| 
								 | 
							
								  t.plan(3)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const server = { my: 'server' }
							 | 
						||
| 
								 | 
							
								  const app = boot(server)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  app.override = function (s, func) {
							 | 
						||
| 
								 | 
							
								    t.pass('override called')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (func[Symbol.for('skip-override')]) {
							 | 
						||
| 
								 | 
							
								      return s
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return Object.create(s)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  app.use(first())
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  async function first () {
							 | 
						||
| 
								 | 
							
								    async function fn (s, opts) {
							 | 
						||
| 
								 | 
							
								      t.equal(s, server)
							 | 
						||
| 
								 | 
							
								      t.notOk(server.isPrototypeOf(s))
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    fn[Symbol.for('skip-override')] = true
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return fn
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								})
							 |