Skip to content

Commit 27c71a9

Browse files
authored
feat!: Highlight timestamp as util.inspect hightlights Dates (#23)
chore: Fix flakey tests in CI
1 parent 74ccbb7 commit 27c71a9

File tree

4 files changed

+90
-42
lines changed

4 files changed

+90
-42
lines changed

README.md

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,27 +27,39 @@ log.error('oh no!');
2727
### `log(msg...)`
2828

2929
Logs the message as if you called `console.log` but prefixes the output with the
30-
current time in HH:MM:ss format.
30+
current time in HH:mm:ss format.
3131

3232
### `log.error(msg...)`
3333

3434
Logs the message as if you called `console.error` but prefixes the output with the
35-
current time in HH:MM:ss format.
35+
current time in HH:mm:ss format.
3636

3737
### `log.warn(msg...)`
3838

3939
Logs the message as if you called `console.warn` but prefixes the output with the
40-
current time in HH:MM:ss format.
40+
current time in HH:mm:ss format.
4141

4242
### `log.info(msg...)`
4343

4444
Logs the message as if you called `console.info` but prefixes the output with the
45-
current time in HH:MM:ss format.
45+
current time in HH:mm:ss format.
4646

4747
### `log.dir(msg...)`
4848

4949
Logs the message as if you called `console.dir` but prefixes the output with the
50-
current time in HH:MM:ss format.
50+
current time in HH:mm:ss format.
51+
52+
## Styling
53+
54+
If the terminal that you are logging to supports colors, the timestamp will be formatted as though it were a `Date` being formatted by `util.inspect()`. This means that it will be formatted as magenta by default but can be adjusted following node's [Customizing util.inspect colors](https://nodejs.org/dist/latest-v10.x/docs/api/util.html#util_customizing_util_inspect_colors) documentation.
55+
56+
For example, this will cause the logged timestamps (and other dates) to display in red:
57+
58+
```js
59+
var util = require('util');
60+
61+
util.inspect.styles.date = 'red';
62+
```
5163

5264
## License
5365

index.js

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
'use strict';
22

3+
var util = require('util');
34
var Console = require('console').Console;
4-
var gray = require('ansi-gray');
5-
var timestamp = require('time-stamp');
65
var supportsColor = require('color-support');
76

87
var console = new Console({
@@ -15,24 +14,33 @@ function hasFlag(flag) {
1514
return process.argv.indexOf('--' + flag) !== -1;
1615
}
1716

18-
function addColor(str) {
17+
function hasColors() {
1918
if (hasFlag('no-color')) {
20-
return str;
19+
return false;
2120
}
2221

2322
if (hasFlag('color')) {
24-
return gray(str);
23+
return true;
2524
}
2625

2726
if (supportsColor()) {
28-
return gray(str);
27+
return true;
2928
}
3029

31-
return str;
30+
return false;
31+
}
32+
33+
function Timestamp() {
34+
this.now = new Date();
35+
}
36+
37+
Timestamp.prototype[util.inspect.custom] = function (depth, opts) {
38+
var timestamp = this.now.toLocaleTimeString('en', { hour12: false });
39+
return '[' + opts.stylize(timestamp, 'date') + ']';
3240
}
3341

3442
function getTimestamp() {
35-
return '[' + addColor(timestamp('HH:mm:ss')) + ']';
43+
return util.inspect(new Timestamp(), { colors: hasColors() });
3644
}
3745

3846
function log() {

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@
2323
"test": "nyc mocha --async-only"
2424
},
2525
"dependencies": {
26-
"ansi-gray": "^0.1.1",
27-
"color-support": "^1.1.3",
28-
"time-stamp": "^2.2.0"
26+
"color-support": "^1.1.3"
2927
},
3028
"devDependencies": {
3129
"eslint": "^7.32.0",

test/index.js

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,60 @@ var nodeVersion = require('parse-node-version')(process.version);
1313
var isLessThanNode12 = nodeVersion.major < 12;
1414

1515
var util = require('util');
16+
var inspect = util.inspect;
1617

1718
var expect = require('expect');
1819
var sinon = require('sinon');
19-
var gray = require('ansi-gray');
20-
var timestamp = require('time-stamp');
20+
21+
/* eslint-disable node/no-unsupported-features/es-syntax */
22+
// Reference: https://github.com/nodejs/node/blob/4e2ceba/lib/internal/util/inspect.js#L267-L274
23+
function stylizeWithColor(str, styleType) {
24+
const style = inspect.styles[styleType];
25+
if (style !== undefined) {
26+
const color = inspect.colors[style];
27+
28+
return `\u001b[${color[0]}m${str}\u001b[${color[1]}m`;
29+
}
30+
return str;
31+
}
32+
/* eslint-enable node/no-unsupported-features/es-syntax */
33+
34+
function withColor(str) {
35+
return stylizeWithColor(str, 'date');
36+
}
2137

2238
var log = require('../');
2339

2440
var stdoutSpy = sinon.spy(process.stdout, 'write');
2541
var stderrSpy = sinon.spy(process.stderr, 'write');
2642

43+
function expectCloseTo(arg, needsColor) {
44+
var now = new Date();
45+
var time;
46+
var maxAttempts = 5;
47+
for (var attempts = 1; attempts < maxAttempts; attempts++) {
48+
try {
49+
time = now.toLocaleTimeString('en', { hour12: false });
50+
if (needsColor) {
51+
expect(arg).toEqual('[' + withColor(time) + '] ');
52+
} else {
53+
expect(arg).toEqual('[' + time + '] ');
54+
}
55+
// Return on a success
56+
return;
57+
} catch (err) {
58+
if (attempts === maxAttempts) {
59+
throw err;
60+
} else {
61+
now.setSeconds(now.getSeconds() - 1);
62+
}
63+
}
64+
}
65+
}
66+
2767
describe('log()', function () {
68+
this.timeout(5000);
69+
2870
var term = process.env.TERM;
2971
var colorterm = process.env.COLORTERM;
3072

@@ -35,8 +77,7 @@ describe('log()', function () {
3577

3678
it('should work i guess', function (done) {
3779
log(1, 2, 3, 4, 'five');
38-
var time = timestamp('HH:mm:ss');
39-
expect(stdoutSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
80+
expectCloseTo(stdoutSpy.args[0][0], true);
4081
if (isLessThanNode12) {
4182
expect(stdoutSpy.args[1][0]).toEqual("1 2 3 4 'five'\n");
4283
} else {
@@ -48,8 +89,7 @@ describe('log()', function () {
4889

4990
it('should accept formatting', function (done) {
5091
log('%s %d %j', 'something', 0.1, { key: 'value' });
51-
var time = timestamp('HH:mm:ss');
52-
expect(stdoutSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
92+
expectCloseTo(stdoutSpy.args[0][0], true);
5393
expect(stdoutSpy.args[1][0]).toEqual('something 0.1 {"key":"value"}\n');
5494

5595
done();
@@ -59,8 +99,7 @@ describe('log()', function () {
5999
process.argv.push('--no-color');
60100

61101
log(1, 2, 3, 4, 'five');
62-
var time = timestamp('HH:mm:ss');
63-
expect(stdoutSpy.args[0][0]).toEqual('[' + time + '] ');
102+
expectCloseTo(stdoutSpy.args[0][0], false);
64103
if (isLessThanNode12) {
65104
expect(stdoutSpy.args[1][0]).toEqual("1 2 3 4 'five'\n");
66105
} else {
@@ -76,8 +115,7 @@ describe('log()', function () {
76115
process.argv.push('--color');
77116

78117
log(1, 2, 3, 4, 'five');
79-
var time = timestamp('HH:mm:ss');
80-
expect(stdoutSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
118+
expectCloseTo(stdoutSpy.args[0][0], true);
81119
if (isLessThanNode12) {
82120
expect(stdoutSpy.args[1][0]).toEqual("1 2 3 4 'five'\n");
83121
} else {
@@ -94,8 +132,7 @@ describe('log()', function () {
94132
delete process.env.COLORTERM;
95133

96134
log(1, 2, 3, 4, 'five');
97-
var time = timestamp('HH:mm:ss');
98-
expect(stdoutSpy.args[0][0]).toEqual('[' + time + '] ');
135+
expectCloseTo(stdoutSpy.args[0][0], false);
99136
if (isLessThanNode12) {
100137
expect(stdoutSpy.args[1][0]).toEqual("1 2 3 4 'five'\n");
101138
} else {
@@ -117,8 +154,7 @@ describe('log.info()', function () {
117154

118155
it('should work i guess', function (done) {
119156
log.info(1, 2, 3, 4, 'five');
120-
var time = timestamp('HH:mm:ss');
121-
expect(stdoutSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
157+
expectCloseTo(stdoutSpy.args[0][0], true);
122158
if (isLessThanNode12) {
123159
expect(stdoutSpy.args[1][0]).toEqual("1 2 3 4 'five'\n");
124160
} else {
@@ -130,8 +166,7 @@ describe('log.info()', function () {
130166

131167
it('should accept formatting', function (done) {
132168
log.info('%s %d %j', 'something', 0.1, { key: 'value' });
133-
var time = timestamp('HH:mm:ss');
134-
expect(stdoutSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
169+
expectCloseTo(stdoutSpy.args[0][0], true);
135170
expect(stdoutSpy.args[1][0]).toEqual('something 0.1 {"key":"value"}\n');
136171

137172
done();
@@ -146,8 +181,7 @@ describe('log.dir()', function () {
146181

147182
it('should format an object with util.inspect', function (done) {
148183
log.dir({ key: 'value' });
149-
var time = timestamp('HH:mm:ss');
150-
expect(stdoutSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
184+
expectCloseTo(stdoutSpy.args[0][0], true);
151185
expect(stdoutSpy.args[1][0]).toEqual(util.inspect({ key: 'value' }) + '\n');
152186

153187
done();
@@ -162,8 +196,7 @@ describe('log.warn()', function () {
162196

163197
it('should work i guess', function (done) {
164198
log.warn(1, 2, 3, 4, 'five');
165-
var time = timestamp('HH:mm:ss');
166-
expect(stderrSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
199+
expectCloseTo(stdoutSpy.args[0][0], true);
167200
if (isLessThanNode12) {
168201
expect(stderrSpy.args[1][0]).toEqual("1 2 3 4 'five'\n");
169202
} else {
@@ -175,8 +208,7 @@ describe('log.warn()', function () {
175208

176209
it('should accept formatting', function (done) {
177210
log.warn('%s %d %j', 'something', 0.1, { key: 'value' });
178-
var time = timestamp('HH:mm:ss');
179-
expect(stderrSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
211+
expectCloseTo(stdoutSpy.args[0][0], true);
180212
expect(stderrSpy.args[1][0]).toEqual('something 0.1 {"key":"value"}\n');
181213

182214
done();
@@ -191,8 +223,7 @@ describe('log.error()', function () {
191223

192224
it('should work i guess', function (done) {
193225
log.error(1, 2, 3, 4, 'five');
194-
var time = timestamp('HH:mm:ss');
195-
expect(stderrSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
226+
expectCloseTo(stdoutSpy.args[0][0], true);
196227
if (isLessThanNode12) {
197228
expect(stderrSpy.args[1][0]).toEqual("1 2 3 4 'five'\n");
198229
} else {
@@ -204,8 +235,7 @@ describe('log.error()', function () {
204235

205236
it('should accept formatting', function (done) {
206237
log.error('%s %d %j', 'something', 0.1, { key: 'value' });
207-
var time = timestamp('HH:mm:ss');
208-
expect(stderrSpy.args[0][0]).toEqual('[' + gray(time) + '] ');
238+
expectCloseTo(stdoutSpy.args[0][0], true);
209239
expect(stderrSpy.args[1][0]).toEqual('something 0.1 {"key":"value"}\n');
210240

211241
done();

0 commit comments

Comments
 (0)