console: allow Object.prototype fields as labels
authorcjihrig <cjihrig@gmail.com>
Fri, 23 Jan 2015 01:16:36 +0000 (20:16 -0500)
committercjihrig <cjihrig@gmail.com>
Tue, 27 Jan 2015 23:28:09 +0000 (18:28 -0500)
Console.prototype.timeEnd() returns NaN if the timer label
corresponds to a property on Object.prototype. This commit
uses a Map to construct the _times object.

Fixes: https://github.com/joyent/node/issues/9069
PR-URL: https://github.com/iojs/io.js/pull/563
Reviewed-By: Vladimir Kurchatkin <vladimir.kurchatkin@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
Reviewed-By: Rod Vagg <rod@vagg.org>
lib/console.js
test/parallel/test-console.js

index 4163cfe..323d233 100644 (file)
@@ -21,7 +21,7 @@ function Console(stdout, stderr) {
   Object.defineProperty(this, '_stdout', prop);
   prop.value = stderr;
   Object.defineProperty(this, '_stderr', prop);
-  prop.value = {};
+  prop.value = new Map();
   Object.defineProperty(this, '_times', prop);
 
   // bind the prototype functions to this Console instance
@@ -56,12 +56,12 @@ Console.prototype.dir = function(object, options) {
 
 
 Console.prototype.time = function(label) {
-  this._times[label] = Date.now();
+  this._times.set(label, Date.now());
 };
 
 
 Console.prototype.timeEnd = function(label) {
-  var time = this._times[label];
+  var time = this._times.get(label);
   if (!time) {
     throw new Error('No such label: ' + label);
   }
index 202ec6e..2e5060f 100644 (file)
@@ -7,6 +7,15 @@ assert.ok(process.stderr.writable);
 assert.equal('number', typeof process.stdout.fd);
 assert.equal('number', typeof process.stderr.fd);
 
+assert.throws(function () {
+  console.timeEnd('no such label');
+});
+
+assert.doesNotThrow(function () {
+  console.time('label');
+  console.timeEnd('label');
+});
+
 // an Object with a custom .inspect() function
 var custom_inspect = { foo: 'bar', inspect: function () { return 'inspect'; } };
 
@@ -33,6 +42,17 @@ console.dir({ foo : { bar : { baz : true } } }, { depth: 1 });
 // test console.trace()
 console.trace('This is a %j %d', { formatted: 'trace' }, 10, 'foo');
 
+// test console.time() and console.timeEnd() output
+console.time('label');
+console.timeEnd('label');
+
+// verify that Object.prototype properties can be used as labels
+console.time('__proto__');
+console.timeEnd('__proto__');
+console.time('constructor');
+console.timeEnd('constructor');
+console.time('hasOwnProperty');
+console.timeEnd('hasOwnProperty');
 
 global.process.stdout.write = stdout_write;
 
@@ -47,12 +67,8 @@ assert.notEqual(-1, strings.shift().indexOf('foo: [Object]'));
 assert.equal(-1, strings.shift().indexOf('baz'));
 assert.equal('Trace: This is a {"formatted":"trace"} 10 foo',
              strings.shift().split('\n').shift());
-
-assert.throws(function () {
-  console.timeEnd('no such label');
-});
-
-assert.doesNotThrow(function () {
-  console.time('label');
-  console.timeEnd('label');
-});
+assert.ok(/^label: \d+ms$/.test(strings.shift().trim()));
+assert.ok(/^__proto__: \d+ms$/.test(strings.shift().trim()));
+assert.ok(/^constructor: \d+ms$/.test(strings.shift().trim()));
+assert.ok(/^hasOwnProperty: \d+ms$/.test(strings.shift().trim()));
+assert.equal(strings.length, 0);