strong-tie/inbound-calls
0
1'use strict'2 3const { test } = require('tap')4const boot = require('..')5 6test('boot an empty app', (t) => {7 t.plan(1)8 const app = boot()9 app.on('start', () => {10 t.pass('booted')11 })12})13 14test('start returns app', (t) => {15 t.plan(1)16 const app = boot({}, { autostart: false })17 app18 .start()19 .ready((err) => {20 t.error(err)21 })22})23 24test('boot an app with a plugin', (t) => {25 t.plan(4)26 27 const app = boot()28 let after = false29 30 app.use(function (server, opts, done) {31 t.equal(server, app, 'the first argument is the server')32 t.same(opts, {}, 'no options')33 t.ok(after, 'delayed execution')34 done()35 })36 37 after = true38 39 app.on('start', () => {40 t.pass('booted')41 })42})43 44test('boot an app with a promisified plugin', (t) => {45 t.plan(4)46 47 const app = boot()48 let after = false49 50 app.use(function (server, opts) {51 t.equal(server, app, 'the first argument is the server')52 t.same(opts, {}, 'no options')53 t.ok(after, 'delayed execution')54 return Promise.resolve()55 })56 57 after = true58 59 app.on('start', () => {60 t.pass('booted')61 })62})63 64test('boot an app with a plugin and a callback /1', (t) => {65 t.plan(2)66 67 const app = boot(() => {68 t.pass('booted')69 })70 71 app.use(function (server, opts, done) {72 t.pass('plugin loaded')73 done()74 })75})76 77test('boot an app with a plugin and a callback /2', (t) => {78 t.plan(2)79 80 const app = boot({}, () => {81 t.pass('booted')82 })83 84 app.use(function (server, opts, done) {85 t.pass('plugin loaded')86 done()87 })88})89 90test('boot a plugin with a custom server', (t) => {91 t.plan(4)92 93 const server = {}94 const app = boot(server)95 96 app.use(function (s, opts, done) {97 t.equal(s, server, 'the first argument is the server')98 t.same(opts, {}, 'no options')99 done()100 })101 102 app.onClose(() => {103 t.ok('onClose called')104 })105 106 app.on('start', () => {107 app.close(() => {108 t.pass('booted')109 })110 })111})112 113test('custom instance should inherits avvio methods /1', (t) => {114 t.plan(6)115 116 const server = {}117 const app = boot(server, {})118 119 server.use(function (s, opts, done) {120 t.equal(s, server, 'the first argument is the server')121 t.same(opts, {}, 'no options')122 done()123 }).after(() => {124 t.ok('after called')125 })126 127 server.onClose(() => {128 t.ok('onClose called')129 })130 131 server.ready(() => {132 t.ok('ready called')133 })134 135 app.on('start', () => {136 server.close(() => {137 t.pass('booted')138 })139 })140})141 142test('custom instance should inherits avvio methods /2', (t) => {143 t.plan(6)144 145 const server = {}146 const app = new boot(server, {}) // eslint-disable-line new-cap147 148 server.use(function (s, opts, done) {149 t.equal(s, server, 'the first argument is the server')150 t.same(opts, {}, 'no options')151 done()152 }).after(() => {153 t.ok('after called')154 })155 156 server.onClose(() => {157 t.ok('onClose called')158 })159 160 server.ready(() => {161 t.ok('ready called')162 })163 164 app.on('start', () => {165 server.close(() => {166 t.pass('booted')167 })168 })169})170 171test('boot a plugin with options', (t) => {172 t.plan(3)173 174 const server = {}175 const app = boot(server)176 const myOpts = {177 hello: 'world'178 }179 180 app.use(function (s, opts, done) {181 t.equal(s, server, 'the first argument is the server')182 t.same(opts, myOpts, 'passed options')183 done()184 }, myOpts)185 186 app.on('start', () => {187 t.pass('booted')188 })189})190 191test('boot a plugin with a function that returns the options', (t) => {192 t.plan(4)193 194 const server = {}195 const app = boot(server)196 const myOpts = {197 hello: 'world'198 }199 const myOptsAsFunc = parent => {200 t.equal(parent, server)201 return parent.myOpts202 }203 204 app.use(function (s, opts, done) {205 s.myOpts = opts206 done()207 }, myOpts)208 209 app.use(function (s, opts, done) {210 t.equal(s, server, 'the first argument is the server')211 t.same(opts, myOpts, 'passed options via function accessing parent injected variable')212 done()213 }, myOptsAsFunc)214 215 app.on('start', () => {216 t.pass('booted')217 })218})219 220test('throw on non-function use', (t) => {221 t.plan(1)222 const app = boot()223 t.throws(() => {224 app.use({})225 })226})227 228// https://github.com/mcollina/avvio/issues/20229test('ready and nextTick', (t) => {230 const app = boot()231 process.nextTick(() => {232 app.ready(() => {233 t.end()234 })235 })236})237 238// https://github.com/mcollina/avvio/issues/20239test('promises and microtask', (t) => {240 const app = boot()241 Promise.resolve()242 .then(() => {243 app.ready(function () {244 t.end()245 })246 })247})248 249test('always loads nested plugins after the current one', (t) => {250 t.plan(2)251 252 const server = {}253 const app = boot(server)254 255 let second = false256 257 app.use(function (s, opts, done) {258 app.use(function (s, opts, done) {259 second = true260 done()261 })262 t.notOk(second)263 264 done()265 })266 267 app.on('start', () => {268 t.ok(second)269 })270})271 272test('promise long resolve', (t) => {273 t.plan(2)274 275 const app = boot()276 277 setTimeout(function () {278 t.throws(() => {279 app.use((s, opts, done) => {280 done()281 })282 }, 'root plugin has already booted')283 })284 285 app.ready(function (err) {286 t.notOk(err)287 })288})289 290test('do not autostart', (t) => {291 const app = boot(null, {292 autostart: false293 })294 app.on('start', () => {295 t.fail()296 })297 t.end()298})299 300test('start with ready', (t) => {301 t.plan(2)302 303 const app = boot(null, {304 autostart: false305 })306 307 app.on('start', () => {308 t.pass()309 })310 311 app.ready(function (err) {312 t.error(err)313 })314})315 316test('load a plugin after start()', (t) => {317 t.plan(1)318 319 let startCalled = false320 const app = boot(null, {321 autostart: false322 })323 324 app.use((s, opts, done) => {325 t.ok(startCalled)326 done()327 })328 329 // we use a timer because330 // it is more reliable than331 // nextTick and setImmediate332 // this almost always will come333 // after those are completed334 setTimeout(() => {335 app.start()336 startCalled = true337 }, 2)338})339 340test('booted should be set before ready', (t) => {341 t.plan(2)342 343 const app = boot()344 345 app.ready(function (err) {346 t.error(err)347 t.equal(app.booted, true)348 })349})350 351test('start should be emitted after ready resolves', (t) => {352 t.plan(1)353 354 const app = boot()355 let ready = false356 357 app.ready().then(function () {358 ready = true359 })360 361 app.on('start', function () {362 t.equal(ready, true)363 })364})365 366test('throws correctly if registering after ready', (t) => {367 t.plan(1)368 369 const app = boot()370 371 app.ready(function () {372 t.throws(() => {373 app.use((a, b, done) => done())374 }, 'root plugin has already booted')375 })376})377 378test('preReady errors must be managed', (t) => {379 t.plan(2)380 381 const app = boot()382 383 app.use((f, opts, cb) => {384 cb()385 })386 387 app.on('preReady', () => {388 throw new Error('boom')389 })390 391 app.ready(err => {392 t.pass('ready function is called')393 t.equal(err.message, 'boom')394 })395})396 397test('preReady errors do not override plugin\'s errors', (t) => {398 t.plan(3)399 400 const app = boot()401 402 app.use((f, opts, cb) => {403 cb(new Error('baam'))404 })405 406 app.on('preReady', () => {407 t.pass('preReady is executed')408 throw new Error('boom')409 })410 411 app.ready(err => {412 t.pass('ready function is called')413 t.equal(err.message, 'baam')414 })415})416 417test('support faux modules', (t) => {418 t.plan(4)419 420 const app = boot()421 let after = false422 423 // Faux modules are modules built with TypeScript424 // or Babel that they export a .default property.425 app.use({426 default: function (server, opts, done) {427 t.equal(server, app, 'the first argument is the server')428 t.same(opts, {}, 'no options')429 t.ok(after, 'delayed execution')430 done()431 }432 })433 434 after = true435 436 app.on('start', () => {437 t.pass('booted')438 })439})440 