Skip to content

Commit

Permalink
Configurable logger functions and additional unit testing. #9
Browse files Browse the repository at this point in the history
  • Loading branch information
James Calfee committed May 9, 2018
1 parent a8085ec commit f96a1d5
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 15 deletions.
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,32 @@ testnet.getBlock({block_num_or_id: 1}).then(result => console.log(result))
```js
api = require('eosjs-api') // Or api = require('./src')

// optional
// everything is optional
options = {
httpEndpoint: 'http://127.0.0.1:8888', // default
debug: false,
debug: false, // API logging
logger: { // Default logging functions
log: console.log,
error: console.error,
debug: console.debug
},
fetchConfiguration: {}
}

testnet = api.Localnet(options)
```
### options.logging example

During testing, an error may be expected and checked as follows:

```js
options.logger = {
error: err => {
assert.equal(err, 'expected error')
}
}
```

### options.fetchConfiguration example

```js
Expand Down
41 changes: 29 additions & 12 deletions src/apigen.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,21 @@ module.exports = apiGen

const configDefaults = {
httpEndpoint: 'http://127.0.0.1:8888',
debug: false
debug: false, // debug logging
logger: {
log: console.log,
error: console.error,
debug: console.debug
}
}

function apiGen (version, definitions, config) {
config = Object.assign({}, configDefaults, config)
Object.assign(configDefaults.logger, config.logger)

const api = {}
const {httpEndpoint} = config

for (const apiGroup in definitions) {
for (const apiMethod in definitions[apiGroup]) {
const methodName = camelCase(apiMethod)
Expand All @@ -29,11 +37,13 @@ function apiGen (version, definitions, config) {
}

function fetchMethod (methodName, url, definition, config) {
const {debug, apiLog} = config
const {debug, apiLog, logger} = config

return function (...args) {
if (args.length === 0) {
console.error(usage(methodName, definition))
if(logger.log) {
logger.log(usage(methodName, definition))
}
return
}

Expand All @@ -50,20 +60,22 @@ function fetchMethod (methodName, url, definition, config) {

if(apiLog) {
// wrap the callback with the logger

const superCallback = callback
callback = (error, tr) => {
if(error) {
apiLog(error, methodName)
} else {
// TODO apiLog(error, methodName, result)
apiLog(null, tr, methodName)
}
superCallback(error, tr)
}
}

const body = JSON.stringify(params)
if (debug) {
console.error('api >', url, body)
if (debug && logger.debug) {
logger.debug('api >', url, body)
}
const fetchConfiguration = {body, method: 'POST'}
Object.assign(fetchConfiguration, config.fetchConfiguration)
Expand All @@ -80,13 +92,15 @@ function fetchMethod (methodName, url, definition, config) {
})
}
}).then(objectResp => {
if (debug) {
console.error('api <', objectResp)
if (debug && logger.debug) {
logger.debug('api <', objectResp)
}
try {
callback(null, objectResp)
} catch(callbackError) {
console.error(callbackError)
if(logger.error) {
logger.error(callbackError)
}
}
})
.catch(error => {
Expand All @@ -96,15 +110,18 @@ function fetchMethod (methodName, url, definition, config) {
message = JSON.parse(error.message).error.details[0]
} catch(e2) {}

console.error('api error =>', message, url, body)
console.error(error)
if(logger.error) {
logger.error('api error =>', message, url, body)
logger.error(error)
}

try {
callback(error)
} catch(callbackError) {
console.error(callbackError)
if(logger.error) {
logger.error(callbackError)
}
}

})

return returnPromise
Expand Down
71 changes: 70 additions & 1 deletion src/appgen.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,76 @@ const apiVersions = {
v1: require(`./api/v1`)
}

describe('API Generator', function () {
describe('API Generator', function() {
it('usage', function (done) {
const api = apiGen('v1', apiVersions.v1, {logger: {log: usage => {
if(/USAGE/.test(usage)) {
done()
}
}}})
api.getInfo() // no args triggers usage
})

it('optionsFormatter', function () {
const api = apiGen('v1', apiVersions.v1)
api.getInfo(true)
})

it('logging', function (done) {
let debugLog, apiLog
const config = {
debug: true, // enables verbose debug logger
logger: {
debug: () => {
debugLog = true
},
error: (err) => {
assert.equal(err, 'unexpected callback error')
done()
}
},
apiLog: () => {
apiLog = true
}
}

const api = apiGen('v1', apiVersions.v1, config)

api.getBlock(1, () => {
assert(debugLog, 'debugLog')
assert(apiLog, 'apiLog')
throw 'unexpected callback error'
})
})

it('api promise error', function () {
let errorLog, apiLog
const config = {
logger: {error: e => {
errorLog = true
}},
apiLog: (error) => {
apiLog = true
}
}
const api = apiGen('v1', apiVersions.v1, config)
return api.getBlock('a').catch(e => {
assert(errorLog, 'errorLog')
assert(apiLog, 'apiLog')
})
})

it('api callback error', function () {
let errorLog
const config = {logger: {error: e => {
errorLog = true
}}}
const api = apiGen('v1', apiVersions.v1, config)
return api.getBlock('a', error => {
throw new Error('callback error')
})
})

for (const version in apiVersions) {
describe(version, function () {
const definitions = apiVersions[version]
Expand Down

0 comments on commit f96a1d5

Please sign in to comment.