Skip to content

Commit 8e91e44

Browse files
committed
add timed sections
1 parent 13e1d06 commit 8e91e44

File tree

4 files changed

+123
-12
lines changed

4 files changed

+123
-12
lines changed

src/browser.js

+33-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ exports.formatArgs = formatArgs;
1010
exports.save = save;
1111
exports.load = load;
1212
exports.useColors = useColors;
13+
exports.hrtime = hrtimeInit();
1314
exports.storage = 'undefined' != typeof chrome
1415
&& 'undefined' != typeof chrome.storage
1516
? chrome.storage.local
@@ -80,20 +81,28 @@ exports.formatters.j = function(v) {
8081
* @api public
8182
*/
8283

83-
function formatArgs(args) {
84+
function formatArgs(args, section) {
8485
var useColors = this.useColors;
8586

8687
args[0] = (useColors ? '%c' : '')
8788
+ this.namespace
8889
+ (useColors ? ' %c' : ' ')
90+
+ (section ? (section.title + (useColors ? ' %c' : ' ')) : '')
8991
+ args[0]
9092
+ (useColors ? '%c ' : ' ')
91-
+ '+' + exports.humanize(this.diff);
93+
+ '+' + exports.humanize(this.diff)
94+
+ (section && section.complete ? ('%c (delta ' + (useColors ? '%c+' : '+') + exports.humanize(section.deltaTime) + (useColors ? '%c)' : ')')) : '');
9295

9396
if (!useColors) return;
9497

9598
var c = 'color: ' + this.color;
96-
args.splice(1, 0, c, 'color: inherit')
99+
var inherit = 'color: inherit';
100+
101+
if (section) {
102+
args.splice(1, 0, c, inherit + '; font-weight: bold', 'font-weight: normal');
103+
} else {
104+
args.splice(1, 0, c, inherit);
105+
}
97106

98107
// the final "%c" is somewhat tricky, because there could be other
99108
// arguments passed either before or after the %c, so we need to
@@ -110,7 +119,11 @@ function formatArgs(args) {
110119
}
111120
});
112121

113-
args.splice(lastC, 0, c);
122+
if (section && section.complete) {
123+
args.splice(lastC - 2, 0, c, inherit, c, inherit);
124+
} else {
125+
args.splice(lastC, 0, c);
126+
}
114127
}
115128

116129
/**
@@ -166,6 +179,22 @@ function load() {
166179
return r;
167180
}
168181

182+
/**
183+
* Browser implementation of hrtime().
184+
*
185+
* Follows the spec outlined in debug.begin() (see debug.js).
186+
*
187+
* If the browser has support for `window.performance.now()`,
188+
* then it is used. Otherwise, it falls back to `Date.now()`.
189+
*/
190+
function hrtimeInit() {
191+
var nowfn = window && window.performance && window.performance.now ? window.performance.now.bind(window.performance) : Date.now;
192+
return function (prev) {
193+
var now = nowfn();
194+
return prev ? (now - prev) : now;
195+
};
196+
}
197+
169198
/**
170199
* Enable namespaces listed in `localStorage.debug` initially.
171200
*/

src/debug.js

+44-5
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ exports.instances = [];
2121
/**
2222
* The currently active debug mode names, and names to skip.
2323
*/
24-
2524
exports.names = [];
2625
exports.skips = [];
2726

@@ -63,7 +62,7 @@ function createDebug(namespace) {
6362

6463
var prevTime;
6564

66-
function debug() {
65+
function debugHandle(rawArgs, section) {
6766
// disabled?
6867
if (!debug.enabled) return;
6968

@@ -78,9 +77,9 @@ function createDebug(namespace) {
7877
prevTime = curr;
7978

8079
// turn the `arguments` into a proper Array
81-
var args = new Array(arguments.length);
80+
var args = new Array(rawArgs.length);
8281
for (var i = 0; i < args.length; i++) {
83-
args[i] = arguments[i];
82+
args[i] = rawArgs[i];
8483
}
8584

8685
args[0] = exports.coerce(args[0]);
@@ -109,18 +108,58 @@ function createDebug(namespace) {
109108
});
110109

111110
// apply env-specific formatting (colors, etc.)
112-
exports.formatArgs.call(self, args);
111+
exports.formatArgs.call(self, args, section);
113112

114113
var logFn = debug.log || exports.log || console.log.bind(console);
115114
logFn.apply(self, args);
116115
}
117116

117+
function debug() {
118+
debugHandle(arguments);
119+
}
120+
118121
debug.namespace = namespace;
119122
debug.enabled = exports.enabled(namespace);
120123
debug.useColors = exports.useColors();
121124
debug.color = selectColor(namespace);
122125
debug.destroy = destroy;
123126

127+
debug.begin = function () {
128+
// hrtime() can return whatever it wants with no arguments;
129+
// however, it must return a float when called with a second parameter;
130+
// that float must be the delta time in milliseconds.
131+
var args = arguments;
132+
var beginTime = exports.hrtime();
133+
134+
var mark = function (title, extraArgs) {
135+
section.title = title;
136+
section.deltaTime = exports.hrtime(beginTime);
137+
if (extraArgs.length) {
138+
var newArgParams = [].slice.call(args, 1).concat([].slice.call(extraArgs, 1))
139+
var newArgs = [(args[0] ? args[0] + ' :: ' : '') + (extraArgs[0] || '')].concat(newArgParams);
140+
debugHandle(newArgs, section);
141+
} else {
142+
debugHandle(args, section);
143+
}
144+
return section;
145+
}
146+
147+
var section = {
148+
title: '[begin]',
149+
end: function () {
150+
return mark('[end]', arguments);
151+
},
152+
mark: function () {
153+
return mark('[mark]', arguments);
154+
}
155+
};
156+
157+
debugHandle(args, section);
158+
section.complete = true;
159+
160+
return section;
161+
};
162+
124163
// env-specific initialization logic for debug instances
125164
if ('function' === typeof exports.init) {
126165
exports.init(debug);

src/node.js

+26-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ exports.formatArgs = formatArgs;
1818
exports.save = save;
1919
exports.load = load;
2020
exports.useColors = useColors;
21+
exports.hrtime = hrtime;
2122

2223
/**
2324
* Colors.
@@ -101,17 +102,22 @@ exports.formatters.O = function(v) {
101102
* @api public
102103
*/
103104

104-
function formatArgs(args) {
105+
function formatArgs(args, section) {
105106
var name = this.namespace;
106107
var useColors = this.useColors;
107108

108109
if (useColors) {
109110
var c = this.color;
110111
var colorCode = '\u001b[3' + (c < 8 ? c : '8;5;' + c);
111-
var prefix = ' ' + colorCode + ';1m' + name + ' ' + '\u001b[0m';
112+
var prefix = ' ' + colorCode + ';1m' + name + '\u001b[0m ';
113+
var sectionPrefix = section ? ('\u001b[1m' + section.title + '\u001b[0m ') : '';
112114

113-
args[0] = prefix + args[0].split('\n').join('\n' + prefix);
115+
args[0] = prefix + sectionPrefix + args[0].split('\n').join('\n' + prefix);
114116
args.push(colorCode + 'm+' + exports.humanize(this.diff) + '\u001b[0m');
117+
118+
if (section && section.complete) {
119+
args.push('(delta ' + colorCode + 'm+' + exports.humanize(section.deltaTime) + '\u001b[0m)');
120+
}
115121
} else {
116122
args[0] = new Date().toISOString()
117123
+ ' ' + name + ' ' + args[0];
@@ -170,6 +176,23 @@ function init (debug) {
170176
}
171177
}
172178

179+
/**
180+
* Wrapper around Node's process.hrtime().
181+
*
182+
* As per the spec defined by debug.begin() (see debug.js),
183+
* this function returns normally when there is no argument,
184+
* but returns a delta float in the event that there is.
185+
*/
186+
187+
function hrtime(prev) {
188+
if (prev) {
189+
var delta = process.hrtime(prev);
190+
return (delta[0] * 1000) + (delta[1] / 1e6);
191+
}
192+
193+
return process.hrtime();
194+
}
195+
173196
/**
174197
* Enable namespaces listed in `process.env.DEBUG` initially.
175198
*/

test/debug_spec.js

+20
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,24 @@ describe('debug', function () {
6464
});
6565
});
6666

67+
describe('timed sections', function () {
68+
var log;
69+
70+
beforeEach(function () {
71+
debug.enable('test');
72+
log = debug('test');
73+
});
74+
75+
context('with log function', function () {
76+
it('times a critical section', function () {
77+
log.log = sinon.spy();
78+
79+
var section = log.begin('a critical section');
80+
log('something inside the section');
81+
section.end();
82+
83+
expect(log.log).to.have.been.calledThrice;
84+
});
85+
});
86+
});
6787
});

0 commit comments

Comments
 (0)