From 1ee38eb874fb66b9c7cf842e6a009952d86c44f5 Mon Sep 17 00:00:00 2001 From: Roman Reiss Date: Fri, 16 Dec 2016 21:20:15 +0100 Subject: [PATCH] util: add %i and %f formatting specifiers This change brings formatting specifiers available in `util.format` and consequently, `console.*` closer to what is supported in all major browsers. - `%i` is introduced to format integer values. - `%f` is introduced to format floating point values. Fixes: https://github.com/nodejs/node/issues/10292 PR-URL: https://github.com/nodejs/node/pull/10308 Reviewed-By: James M Snell --- doc/api/util.md | 4 ++- lib/util.js | 16 +++++++++++ test/parallel/test-util-format.js | 46 +++++++++++++++++++++++++------ 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/doc/api/util.md b/doc/api/util.md index bb1bbd529a4ccb..357811cc0fcdeb 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -103,7 +103,9 @@ Each placeholder token is replaced with the converted value from the corresponding argument. Supported placeholders are: * `%s` - String. -* `%d` - Number (both integer and float). +* `%d` - Number (integer or floating point value). +* `%i` - Integer. +* `%f` - Floating point value. * `%j` - JSON. Replaced with the string `'[Circular]'` if the argument contains circular references. * `%%` - single percent sign (`'%'`). This does not consume an argument. diff --git a/lib/util.js b/lib/util.js index 3378109b6126ed..ce99ecfae6d2cf 100644 --- a/lib/util.js +++ b/lib/util.js @@ -89,6 +89,22 @@ exports.format = function(f) { str += Number(arguments[a++]); lastPos = i = i + 2; continue; + case 105: // 'i' + if (a >= argLen) + break; + if (lastPos < i) + str += f.slice(lastPos, i); + str += parseInt(arguments[a++]); + lastPos = i = i + 2; + continue; + case 102: // 'f' + if (a >= argLen) + break; + if (lastPos < i) + str += f.slice(lastPos, i); + str += parseFloat(arguments[a++]); + lastPos = i = i + 2; + continue; case 106: // 'j' if (a >= argLen) break; diff --git a/test/parallel/test-util-format.js b/test/parallel/test-util-format.js index 71265e4b6a37f8..5e326dd516896c 100644 --- a/test/parallel/test-util-format.js +++ b/test/parallel/test-util-format.js @@ -27,21 +27,51 @@ assert.throws(function() { util.format('%d', symbol); }, TypeError); +// Number format specifier +assert.strictEqual(util.format('%d'), '%d'); assert.strictEqual(util.format('%d', 42.0), '42'); assert.strictEqual(util.format('%d', 42), '42'); -assert.strictEqual(util.format('%s', 42), '42'); -assert.strictEqual(util.format('%j', 42), '42'); - -assert.strictEqual(util.format('%d', '42.0'), '42'); assert.strictEqual(util.format('%d', '42'), '42'); -assert.strictEqual(util.format('%s', '42'), '42'); -assert.strictEqual(util.format('%j', '42'), '"42"'); +assert.strictEqual(util.format('%d', '42.0'), '42'); +assert.strictEqual(util.format('%d', 1.5), '1.5'); +assert.strictEqual(util.format('%d', -0.5), '-0.5'); +assert.strictEqual(util.format('%d', ''), '0'); -assert.strictEqual(util.format('%%s%s', 'foo'), '%sfoo'); +// Integer format specifier +assert.strictEqual(util.format('%i'), '%i'); +assert.strictEqual(util.format('%i', 42.0), '42'); +assert.strictEqual(util.format('%i', 42), '42'); +assert.strictEqual(util.format('%i', '42'), '42'); +assert.strictEqual(util.format('%i', '42.0'), '42'); +assert.strictEqual(util.format('%i', 1.5), '1'); +assert.strictEqual(util.format('%i', -0.5), '0'); +assert.strictEqual(util.format('%i', ''), 'NaN'); + +// Float format specifier +assert.strictEqual(util.format('%f'), '%f'); +assert.strictEqual(util.format('%f', 42.0), '42'); +assert.strictEqual(util.format('%f', 42), '42'); +assert.strictEqual(util.format('%f', '42'), '42'); +assert.strictEqual(util.format('%f', '42.0'), '42'); +assert.strictEqual(util.format('%f', 1.5), '1.5'); +assert.strictEqual(util.format('%f', -0.5), '-0.5'); +assert.strictEqual(util.format('%f', Math.PI), '3.141592653589793'); +assert.strictEqual(util.format('%f', ''), 'NaN'); +// String format specifier assert.strictEqual(util.format('%s'), '%s'); assert.strictEqual(util.format('%s', undefined), 'undefined'); assert.strictEqual(util.format('%s', 'foo'), 'foo'); +assert.strictEqual(util.format('%s', 42), '42'); +assert.strictEqual(util.format('%s', '42'), '42'); + +// JSON format specifier +assert.strictEqual(util.format('%j'), '%j'); +assert.strictEqual(util.format('%j', 42), '42'); +assert.strictEqual(util.format('%j', '42'), '"42"'); + +// Various format specifiers +assert.strictEqual(util.format('%%s%s', 'foo'), '%sfoo'); assert.strictEqual(util.format('%s:%s'), '%s:%s'); assert.strictEqual(util.format('%s:%s', undefined), 'undefined:%s'); assert.strictEqual(util.format('%s:%s', 'foo'), 'foo:%s'); @@ -50,11 +80,9 @@ assert.strictEqual(util.format('%s:%s', 'foo', 'bar', 'baz'), 'foo:bar baz'); assert.strictEqual(util.format('%%%s%%', 'hi'), '%hi%'); assert.strictEqual(util.format('%%%s%%%%', 'hi'), '%hi%%'); assert.strictEqual(util.format('%sbc%%def', 'a'), 'abc%def'); - assert.strictEqual(util.format('%d:%d', 12, 30), '12:30'); assert.strictEqual(util.format('%d:%d', 12), '12:%d'); assert.strictEqual(util.format('%d:%d'), '%d:%d'); - assert.strictEqual(util.format('o: %j, a: %j', {}, []), 'o: {}, a: []'); assert.strictEqual(util.format('o: %j, a: %j', {}), 'o: {}, a: %j'); assert.strictEqual(util.format('o: %j, a: %j'), 'o: %j, a: %j');