Skip to content

Commit

Permalink
Merge pull request #23 from mcollina/ready-close-context
Browse files Browse the repository at this point in the history
Updated encapsulation handling
  • Loading branch information
delvedor authored Sep 18, 2017
2 parents 7549f8a + f1b6860 commit 49c8873
Show file tree
Hide file tree
Showing 5 changed files with 248 additions and 25 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,9 @@ jspm_packages

# Optional REPL history
.node_repl_history

# mac files
.DS_Store

# vim swap files
*.swp
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ all their dependencies. The `'start'` event is not emitted yet.
The callback changes basing on the parameters your are giving:
1. If one parameter is given to the callback, that parameter will be the `error` object.
2. If two parameters are given to the callback, the first will be the `error` object, the second will be the `done` callback.
3. If three parameters are given to the callback, the first will be the `error` object, the second will be the `context` and the third the `done` callback.
3. If three parameters are given to the callback, the first will be the `error` object, the second will be the top level `context` unless you have specified both server and override, in that case the `context` will be what the override returns, and the third the `done` callback.

```js
const server = {}
Expand Down Expand Up @@ -231,7 +231,7 @@ Calls a function after all the plugins and `after` call are completed, but befor
The callback changes basing on the parameters your are giving:
1. If one parameter is given to the callback, that parameter will be the `error` object.
2. If two parameters are given to the callback, the first will be the `error` object, the second will be the `done` callback.
3. If three parameters are given to the callback, the first will be the `error` object, the second will be the `context` and the third the `done` callback.
3. If three parameters are given to the callback, the first will be the `error` object, the second will be the top level `context` unless you have specified both server and override, in that case the `context` will be what the override returns, and the third the `done` callback.

```js
const server = {}
Expand Down Expand Up @@ -325,7 +325,7 @@ Registers a new callback that will be fired once then `close` api is called.

The callback changes basing on the parameters your are giving:
1. If one parameter is given to the callback, that parameter will be the `context`.
2. If two parameters are given to the callback, the first will be the `context`, the second will be the `done` callback.
2. If two parameters are given to the callback, the first will be the top level `context` unless you have specified both server and override, in that case the `context` will be what the override returns, the second will be the `done` callback.

```js
const server = {}
Expand Down Expand Up @@ -355,7 +355,7 @@ Starts the shotdown procedure, the callback is called once all the registered ca
The callback changes basing on the parameters your are giving:
1. If one parameter is given to the callback, that parameter will be the `error` object.
2. If two parameters are given to the callback, the first will be the `error` object, the second will be the `done` callback.
3. If three parameters are given to the callback, the first will be the `error` object, the second will be the `context` and the third the `done` callback.
3. If three parameters are given to the callback, the first will be the `error` object, the second will be the top level `context` unless you have specified both server and override, in that case the `context` will be what the override returns, and the third the `done` callback.

```js
const server = {}
Expand Down
62 changes: 47 additions & 15 deletions boot.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,23 @@ function wrap (server, opts, instance) {
return this
}

server[afterKey] = function (cb) {
instance.after(cb)
server[afterKey] = function (func) {
instance.after(encapsulateThreeParam(func, this))
return this
}

server[readyKey] = function (cb) {
instance.ready(cb)
server[readyKey] = function (func) {
instance.ready(encapsulateThreeParam(func, this))
return this
}

server[onCloseKey] = function (cb) {
instance.onClose(cb)
server[onCloseKey] = function (func) {
instance.onClose(encapsulateTwoParam(func, this))
return this
}

server[closeKey] = function (cb) {
instance.close(cb)
server[closeKey] = function (func) {
instance.close(encapsulateThreeParam(func, this))
return this
}
}
Expand Down Expand Up @@ -174,23 +174,29 @@ Boot.prototype._addPlugin = function (plugin, opts, callback) {
}

Boot.prototype.after = function (func, cb) {
this.use(function (s, opts, done) {
this.use(_after.bind(this), cb)

function _after (s, opts, done) {
callWithCbOrNextTick.call(this, func, done)
}.bind(this), cb)
}

return this
}

Boot.prototype.onClose = function (func) {
this._closeQ.unshift(func, err => {
this._closeQ.unshift(func, callback.bind(this))

function callback (err) {
if (err) this._error = err
})
}

return this
}

Boot.prototype.close = function (cb) {
Boot.prototype.close = function (func) {
this._error = null
if (cb) {
this._closeQ.push(cb)
if (func) {
this._closeQ.push(func)
this._thereIsCloseCb = true
}
process.nextTick(this._closeQ.resume.bind(this._closeQ))
Expand Down Expand Up @@ -241,6 +247,32 @@ function closeWithCbOrNextTick (func, cb, context) {
}
}

function encapsulateTwoParam (func, that) {
return _encapsulateTwoParam.bind(that)
function _encapsulateTwoParam (context, cb) {
if (func.length === 0 || func.length === 1) {
func(this)
process.nextTick(cb)
} else {
func(this, cb)
}
}
}

function encapsulateThreeParam (func, that) {
return _encapsulateThreeParam.bind(that)
function _encapsulateThreeParam (err, cb) {
if (func.length === 0 || func.length === 1) {
func(err)
process.nextTick(cb)
} else if (func.length === 2) {
func(err, cb)
} else {
func(err, this, cb)
}
}
}

module.exports = Boot
module.exports.express = function (app) {
return Boot(app, {
Expand Down
108 changes: 107 additions & 1 deletion test/after-and-ready.js
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ test('if `use` has a callback without parameters, the error must reach ready', (
})
})

test('shold pass the errors from after to ready', (t) => {
test('should pass the errors from after to ready', (t) => {
t.plan(6)

const server = {}
Expand Down Expand Up @@ -372,3 +372,109 @@ test('shold pass the errors from after to ready', (t) => {
})
})
})

test('after no encapsulation', t => {
t.plan(4)

const app = boot()
app.override = function (s, fn, opts) {
s = Object.create(s)
return s
}

app.use(function (instance, opts, next) {
instance.test = true
instance.after(function (err, i, done) {
t.error(err)
t.notOk(i.test)
done()
})
next()
})

app.after(function (err, i, done) {
t.error(err)
t.notOk(i.test)
done()
})
})

test('ready no encapsulation', t => {
t.plan(4)

const app = boot()
app.override = function (s, fn, opts) {
s = Object.create(s)
return s
}

app.use(function (instance, opts, next) {
instance.test = true
instance.ready(function (err, i, done) {
t.error(err)
t.notOk(i.test)
done()
})
next()
})

app.ready(function (err, i, done) {
t.error(err)
t.notOk(i.test)
done()
})
})

test('after encapsulation with a server', t => {
t.plan(4)

const server = { my: 'server' }
const app = boot(server)
app.override = function (s, fn, opts) {
s = Object.create(s)
return s
}

app.use(function (instance, opts, next) {
instance.test = true
instance.after(function (err, i, done) {
t.error(err)
t.ok(i.test)
done()
})
next()
})

app.after(function (err, i, done) {
t.error(err)
t.notOk(i.test)
done()
})
})

test('ready encapsulation with a server', t => {
t.plan(4)

const server = { my: 'server' }
const app = boot(server)
app.override = function (s, fn, opts) {
s = Object.create(s)
return s
}

app.use(function (instance, opts, next) {
instance.test = true
instance.ready(function (err, i, done) {
t.error(err)
t.ok(i.test)
done()
})
next()
})

app.ready(function (err, i, done) {
t.error(err)
t.notOk(i.test)
done()
})
})
89 changes: 84 additions & 5 deletions test/close.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,99 @@ test('boot an app with a plugin', (t) => {
})

test('onClose arguments', (t) => {
t.plan(3)
t.plan(5)

const app = boot()

app.use(function (server, opts, done) {
app.onClose((instance, done) => {
app.use(function (server, opts, next) {
server.onClose((instance, done) => {
t.ok('called')
t.equal(app, instance)
t.equal(server, instance)
done()
})
done()
next()
})

app.use(function (server, opts, next) {
server.onClose((instance) => {
t.ok('called')
t.equal(server, instance)
})
next()
})

app.on('start', () => {
app.close(() => {
t.pass('Closed in the correct order')
})
})
})

test('onClose arguments - fastify encapsulation test case', (t) => {
t.plan(5)

const server = { my: 'server' }
const app = boot(server)

app.override = function (s, fn, opts) {
s = Object.create(s)
return s
}

app.use(function (instance, opts, next) {
instance.test = true
instance.onClose((i, done) => {
t.ok(i.test)
done()
})
next()
})

app.use(function (instance, opts, next) {
t.notOk(instance.test)
instance.onClose((i) => {
t.notOk(i.test)
})
next()
})

app.on('start', () => {
t.notOk(app.test)
app.close(() => {
t.pass('Closed in the correct order')
})
})
})

test('onClose arguments - encapsulation test case no server', (t) => {
t.plan(5)

const app = boot()

app.override = function (s, fn, opts) {
s = Object.create(s)
return s
}

app.use(function (instance, opts, next) {
instance.test = true
instance.onClose((i, done) => {
t.notOk(i.test)
done()
})
next()
})

app.use(function (instance, opts, next) {
t.notOk(instance.test)
instance.onClose((i) => {
t.notOk(i.test)
})
next()
})

app.on('start', () => {
t.notOk(app.test)
app.close(() => {
t.pass('Closed in the correct order')
})
Expand Down

0 comments on commit 49c8873

Please sign in to comment.