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 | ||
|  |   } | ||
|  | }) |