Repository: pinojs/pino (js)

Issue:
BUG: formatting breaks when 1st parameter is an object
### Scenario

create a logger. emit an entry with first parameter as a data object

```javascript
> const log = require('pino')();
undefined
> log.info({}, "foo %s", "bar");
```

### Expect
well formatted log entry
```
{"pid":25540,"hostname":"My-PC","name":"foo","level":30,"time":1480447139327,"msg":"foo bar"}
```

### Found
An Error is thrown
```
TypeError: s.indexOf is not a function
    at countInterp (C:\ws\nodejs\cwt-oapi-util\node_modules\cwt-logger\node_modules\pino\pino.js:378:13)
    at EventEmitter.LOG (C:\ws\nodejs\cwt-oapi-util\node_modules\cwt-logger\node_modules\pino\pino.js:409:11)
    at repl:1:7
    at sigintHandlersWrap (vm.js:22:35)
    at sigintHandlersWrap (vm.js:96:12)
    at ContextifyScript.Script.runInThisContext (vm.js:21:12)
    at REPLServer.defaultEval (repl.js:313:29)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.<anonymous> (repl.js:513:10)
```


### More info:
version `3.0.2`
does not reproduce with version `2.15.0` (regression)

Pull request description:
Fix #139
Fixes https://github.com/pinojs/pino/issues/139.

@osher please checks if it solves your issues.

Patch:
diff --git a/pino.js b/pino.js
index f4181b7..b6aedc8 100644
--- a/pino.js
+++ b/pino.js
@@ -406,8 +406,8 @@ function genLog (z) {
     }
     p = n.length = arguments.length - l
     if (p > 1) {
-      l = countInterp(a, '%j')
-      if (l && typeof a === 'string') {
+      l = typeof a === 'string' ? countInterp(a, '%j') : 0
+      if (l) {
         n.length = l + countInterp(a, '%d') + countInterp(a, '%s') + 1
         o = `${util.format.apply(null, n)}`
       } else {


Test patch:
diff --git a/test/basic.test.js b/test/basic.test.js
index 3502971..b1cea58 100644
--- a/test/basic.test.js
+++ b/test/basic.test.js
@@ -292,6 +292,42 @@ test('correctly escape msg strings', function (t) {
   instance.fatal('this contains "')
 })
 
+// https://github.com/pinojs/pino/issues/139
+test('object and format string', function (t) {
+  var instance = pino(sink(function (chunk, enc, cb) {
+    delete chunk.time
+    t.deepEqual(chunk, {
+      pid: pid,
+      hostname: hostname,
+      level: 30,
+      msg: 'foo bar',
+      v: 1
+    })
+    t.end()
+    cb()
+  }))
+
+  instance.info({}, 'foo %s', 'bar')
+})
+
+test('object and format string property', function (t) {
+  var instance = pino(sink(function (chunk, enc, cb) {
+    delete chunk.time
+    t.deepEqual(chunk, {
+      pid: pid,
+      hostname: hostname,
+      level: 30,
+      msg: 'foo bar',
+      answer: 42,
+      v: 1
+    })
+    t.end()
+    cb()
+  }))
+
+  instance.info({ answer: 42 }, 'foo %s', 'bar')
+})
+
 test('correctly strip undefined when returned from toJSON', function (t) {
   t.plan(1)