Skip to content

Commit

Permalink
fix parameter detection
Browse files Browse the repository at this point in the history
fix Proxy that is detected as a Thenable object
  • Loading branch information
feugy committed Jul 26, 2016
1 parent 26d9e6a commit 7ba152d
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 42 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ Copyright [Damien Simonin Feugas][feugy] and other contributors, licensed under

## Changelog

### 1.2.2
- fix parameter detection
- fix Proxy that is detected as a Thenable object

### 1.2.1
- fix issue related to parameter name extraction when using arrow functions

Expand Down
16 changes: 13 additions & 3 deletions lib/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ const {version} = require('../package.json')
const {getLogger} = require('./utils')
const {registerLocal, registerFromServer} = require('./utils/register')

const reserved = ['then', 'catch', 'finally']

class Client {

// client's version
Expand Down Expand Up @@ -40,9 +42,17 @@ class Client {

return remote ? new Proxy(this, {
get(target, propKey) {
// use first defined properties
if (propKey in target) {
return target[propKey]
}
// reserved keyword that aren't defined must be undefined (thenable false-positive)
if (reserved.includes(propKey)) {
/* eslint no-undefined: 0 */
return undefined
}
// creates a function that will get exposed API from remote server
// but only if the function isn't defined yet
return target[propKey] || ((...args) => {
return (...args) => {
logger.debug(`during ${propKey}, connect to ${remote} to get exposed apis`)
return registerFromServer(target, remote, logger)
.then(() => {
Expand All @@ -53,7 +63,7 @@ class Client {
}
return target[propKey](...args)
})
})
}
}
}) : this
}
Expand Down
12 changes: 6 additions & 6 deletions lib/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@ exports.getLogger = () => {
*/
exports.getParamNames = fn => {
const declaration = (fn || '').toString()
if (/^[^(]*\(/.test(declaration)) {
if (/^\s*[^\(]+?\s*=>/.test(declaration)) {
// covers the following cases: "name =>",
return [declaration.match(/^\s*(\S+)\s*=>/)[1]]
}
if (/^[^(]*?\(/.test(declaration)) {
// covers the following cases: "function ()", "() =>", "name () {", "function name () {" {},
const params = declaration.match(/^[^(]*\(((?:[^,]+, )*[^\)]*)\)/)[1].split(', ')
const params = declaration.match(/^[^(]*\(((?:.+?, )*.*?)\)/)[1].split(', ')
// remove empty false-positives
.filter(p => p)
// remove default values
Expand All @@ -46,10 +50,6 @@ exports.getParamNames = fn => {
}
return params
}
if (/^\s*\S+\s*=>/.test(declaration)) {
// covers the following cases: "name =>",
return [declaration.match(/^\s*(\S+)\s*=>/)[1]]
}
throw new Error(`unsupported function ${fn}`)
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mini-service",
"version": "1.2.1",
"version": "1.2.2",
"description": "Micro services done simply. Choose to run them locally or remotely",
"repository": {
"type": "git",
Expand Down
5 changes: 5 additions & 0 deletions test/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@ describe('service\'s client', () => {
done()
})

it('should not be detected as a Promise', () =>
// This will check the existence of then method on the Proxy
Promise.resolve(remote)
)

it('should handle communication error', () =>
remote.ping() // no server available
.then(res => {
Expand Down
98 changes: 66 additions & 32 deletions test/utils/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ describe('Utilities', () => {

describe('getParamNames', () => {

/* eslint no-empty-function: 0 */
const noop = () => {}

it('should fails on null', done => {
assert.throws(() => utils.getParamNames(null), /unsupported function null/)
done()
Expand Down Expand Up @@ -40,102 +43,133 @@ describe('Utilities', () => {
})

it('should handle empty function declaration', done => {
/* eslint prefer-arrow-callback: 0, no-empty-function: 0 */
function declared() {}
/* eslint prefer-arrow-callback: 0 */
function declared() {
noop()
}
assert.deepEqual(utils.getParamNames(declared), [])
done()
})

it('should handle empty anonymous function', done => {
/* eslint prefer-arrow-callback: 0, no-empty-function: 0 */
assert.deepEqual(utils.getParamNames(function() {}), [])
/* eslint prefer-arrow-callback: 0 */
assert.deepEqual(utils.getParamNames(function() {
noop()
}), [])
done()
})

it('should handle named function', done => {
/* eslint prefer-arrow-callback: 0, no-empty-function: 0 */
assert.deepEqual(utils.getParamNames(function named() {}), [])
/* eslint prefer-arrow-callback: 0 */
assert.deepEqual(utils.getParamNames(function named() {
noop()
}), [])
done()
})

it('should handle empty arrow function', done => {
/* eslint no-empty-function: 0 */
assert.deepEqual(utils.getParamNames(() => {}), [])
assert.deepEqual(utils.getParamNames(() => {
noop()
}), [])
done()
})

it('should handle function declaration with single parameter', done => {
/* eslint prefer-arrow-callback: 0, no-empty-function: 0 */
function declared(a) {}
/* eslint prefer-arrow-callback: 0 */
function declared(a) {
noop()
}
assert.deepEqual(utils.getParamNames(declared), ['a'])
done()
})

it('should handle anonymous function with single parameter', done => {
/* eslint prefer-arrow-callback: 0, no-empty-function: 0, no-unused-vars:0 */
assert.deepEqual(utils.getParamNames(function(a) {}), ['a'])
/* eslint prefer-arrow-callback: 0, no-unused-vars:0 */
assert.deepEqual(utils.getParamNames(function(a) {
noop()
}), ['a'])
done()
})

it('should handle named function with single parameter', done => {
/* eslint prefer-arrow-callback: 0, no-empty-function: 0, no-unused-vars:0 */
assert.deepEqual(utils.getParamNames(function named(a) {}), ['a'])
/* eslint prefer-arrow-callback: 0, no-unused-vars:0 */
assert.deepEqual(utils.getParamNames(function named(a) {
noop()
}), ['a'])
done()
})

it('should handle empty arrow function with single parameter', done => {
/* eslint no-empty-function: 0, no-unused-vars:0 */
assert.deepEqual(utils.getParamNames(a => {}), ['a'])
/* eslint no-unused-vars:0 */
assert.deepEqual(utils.getParamNames(a => {
noop()
}), ['a'])
done()
})

it('should handle function declaration with multiple parameter', done => {
/* eslint prefer-arrow-callback: 0, no-empty-function: 0 */
function declared(a, b, c) {}
/* eslint prefer-arrow-callback: 0 */
function declared(a, b, c) {
noop()
}
assert.deepEqual(utils.getParamNames(declared), ['a', 'b', 'c'])
done()
})

it('should handle anonymous function with multiple parameters', done => {
/* eslint prefer-arrow-callback: 0, no-empty-function: 0, no-unused-vars:0 */
assert.deepEqual(utils.getParamNames(function(a, b, c) {}), ['a', 'b', 'c'])
/* eslint prefer-arrow-callback: 0, no-unused-vars:0 */
assert.deepEqual(utils.getParamNames(function(a, b, c) {
noop()
}), ['a', 'b', 'c'])
done()
})

it('should handle named function with multiple parameters', done => {
/* eslint prefer-arrow-callback: 0, no-empty-function: 0, no-unused-vars:0 */
assert.deepEqual(utils.getParamNames(function named(a, b, c) {}), ['a', 'b', 'c'])
/* eslint prefer-arrow-callback: 0, no-unused-vars:0 */
assert.deepEqual(utils.getParamNames(function named(a, b, c) {
noop()
}), ['a', 'b', 'c'])
done()
})

it('should handle empty arrow function with multiple parameters', done => {
/* eslint no-empty-function: 0, no-unused-vars:0 */
assert.deepEqual(utils.getParamNames((a, b, c) => {}), ['a', 'b', 'c'])
/* eslint no-unused-vars:0 */
assert.deepEqual(utils.getParamNames((a, b, c) => {
noop()
}), ['a', 'b', 'c'])
done()
})

it('should handle function declaration with default values', done => {
/* eslint prefer-arrow-callback: 0, no-empty-function: 0 */
function declared(a, b, c = false) {}
/* eslint prefer-arrow-callback: 0 */
function declared(a, b, c = false) {
noop()
}
assert.deepEqual(utils.getParamNames(declared), ['a', 'b', 'c'])
done()
})

it('should handle anonymous function with default values', done => {
/* eslint prefer-arrow-callback: 0, no-empty-function: 0, no-unused-vars:0 */
assert.deepEqual(utils.getParamNames(function(a, b, c = 10) {}), ['a', 'b', 'c'])
/* eslint prefer-arrow-callback: 0, no-unused-vars:0 */
assert.deepEqual(utils.getParamNames(function(a, b, c = 10) {
noop()
}), ['a', 'b', 'c'])
done()
})

it('should handle named function with default values', done => {
/* eslint prefer-arrow-callback: 0, no-empty-function: 0, no-unused-vars:0 */
assert.deepEqual(utils.getParamNames(function named(a, b, c = null) {}), ['a', 'b', 'c'])
/* eslint prefer-arrow-callback: 0, no-unused-vars:0 */
assert.deepEqual(utils.getParamNames(function named(a, b, c = null) {
noop()
}), ['a', 'b', 'c'])
done()
})

it('should handle empty arrow function with default values', done => {
/* eslint no-empty-function: 0, no-unused-vars:0 */
assert.deepEqual(utils.getParamNames((a, b, c = []) => {}), ['a', 'b', 'c'])
/* eslint no-unused-vars:0 */
assert.deepEqual(utils.getParamNames((a, b, c = []) => {
noop()
}), ['a', 'b', 'c'])
done()
})
})
Expand Down

0 comments on commit 7ba152d

Please sign in to comment.