Skip to content

Commit 7e02fbd

Browse files
perf(util): optimise styleText
1 parent 067a779 commit 7e02fbd

File tree

3 files changed

+100
-99
lines changed

3 files changed

+100
-99
lines changed

benchmark/util/style-text.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ const bench = common.createBenchmark(main, {
99
messageType: ['string', 'number', 'boolean', 'invalid'],
1010
format: ['red', 'italic', 'invalid'],
1111
validateStream: [1, 0],
12+
noColors: [1, 0],
1213
n: [1e3],
1314
});
1415

15-
function main({ messageType, format, validateStream, n }) {
16+
function main({ messageType, format, validateStream, noColors, n }) {
1617
let str;
1718
switch (messageType) {
1819
case 'string':
@@ -29,6 +30,8 @@ function main({ messageType, format, validateStream, n }) {
2930
break;
3031
}
3132

33+
process.env.NO_COLORS = noColors ? true : false;
34+
3235
bench.start();
3336
for (let i = 0; i < n; i++) {
3437
let colored = '';

lib/util.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ function styleText(format, text, { validateStream = true, stream = process.stdou
119119
validateString(text, 'text');
120120
validateBoolean(validateStream, 'options.validateStream');
121121

122-
let skipColorize;
123122
if (validateStream) {
124123
if (
125124
!isReadableStream(stream) &&
@@ -129,8 +128,9 @@ function styleText(format, text, { validateStream = true, stream = process.stdou
129128
throw new ERR_INVALID_ARG_TYPE('stream', ['ReadableStream', 'WritableStream', 'Stream'], stream);
130129
}
131130

132-
// If the stream is falsy or should not be colorized, set skipColorize to true
133-
skipColorize = !lazyUtilColors().shouldColorize(stream);
131+
if (!lazyUtilColors().shouldColorize(stream)) {
132+
return text;
133+
};
134134
}
135135

136136
// If the format is not an array, convert it to an array
@@ -144,12 +144,12 @@ function styleText(format, text, { validateStream = true, stream = process.stdou
144144
if (formatCodes == null) {
145145
validateOneOf(key, 'format', ObjectKeys(inspect.colors));
146146
}
147-
if (skipColorize) continue;
147+
148148
left += escapeStyleCode(formatCodes[0]);
149149
right = `${escapeStyleCode(formatCodes[1])}${right}`;
150150
}
151151

152-
return skipColorize ? text : `${left}${text}${right}`;
152+
return `${left}${text}${right}`;
153153
}
154154

155155
/**

test/parallel/test-util-styletext.js

Lines changed: 91 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -8,104 +8,102 @@ const { WriteStream } = require('node:tty');
88
const styled = '\u001b[31mtest\u001b[39m';
99
const noChange = 'test';
1010

11-
[
12-
undefined,
13-
null,
14-
false,
15-
5n,
16-
5,
17-
Symbol(),
18-
() => {},
19-
{},
20-
].forEach((invalidOption) => {
21-
assert.throws(() => {
22-
util.styleText(invalidOption, 'test');
23-
}, {
24-
code: 'ERR_INVALID_ARG_VALUE',
25-
});
26-
assert.throws(() => {
27-
util.styleText('red', invalidOption);
28-
}, {
29-
code: 'ERR_INVALID_ARG_TYPE'
30-
});
31-
});
11+
[
12+
undefined,
13+
null,
14+
false,
15+
5n,
16+
5,
17+
Symbol(),
18+
() => {},
19+
{},
20+
].forEach((invalidOption) => {
21+
assert.throws(() => {
22+
util.styleText(invalidOption, 'test');
23+
}, {
24+
code: 'ERR_INVALID_ARG_VALUE',
25+
});
26+
assert.throws(() => {
27+
util.styleText('red', invalidOption);
28+
}, {
29+
code: 'ERR_INVALID_ARG_TYPE'
30+
});
31+
});
3232

33-
assert.throws(() => {
34-
util.styleText('invalid', 'text');
35-
}, {
36-
code: 'ERR_INVALID_ARG_VALUE',
37-
});
33+
assert.throws(() => {
34+
util.styleText('invalid', 'text');
35+
}, {
36+
code: 'ERR_INVALID_ARG_VALUE',
37+
});
38+
assert.throws(() => {
39+
util.styleText(['invalid'], 'text');
40+
}, {
41+
code: 'ERR_INVALID_ARG_VALUE',
42+
});
3843

39-
assert.strictEqual(
40-
util.styleText('red', 'test', { validateStream: false }),
41-
'\u001b[31mtest\u001b[39m',
42-
);
44+
assert.strictEqual(
45+
util.styleText('red', 'test', { validateStream: false }),
46+
'\u001b[31mtest\u001b[39m',
47+
);
48+
assert.strictEqual(
49+
util.styleText(['bold', 'red'], 'test', { validateStream: false }),
50+
'\u001b[1m\u001b[31mtest\u001b[39m\u001b[22m',
51+
);
4352

44-
assert.strictEqual(
45-
util.styleText(['bold', 'red'], 'test', { validateStream: false }),
46-
'\u001b[1m\u001b[31mtest\u001b[39m\u001b[22m',
47-
);
53+
assert.strictEqual(
54+
util.styleText(['bold', 'red'], 'test', { validateStream: false }),
55+
util.styleText(
56+
'bold',
57+
util.styleText('red', 'test', { validateStream: false }),
58+
{ validateStream: false },
59+
),
60+
);
4861

49-
assert.strictEqual(
50-
util.styleText(['bold', 'red'], 'test', { validateStream: false }),
51-
util.styleText(
52-
'bold',
53-
util.styleText('red', 'test', { validateStream: false }),
54-
{ validateStream: false },
55-
),
56-
);
62+
assert.throws(() => {
63+
util.styleText('red', 'text', { stream: {} });
64+
}, {
65+
code: 'ERR_INVALID_ARG_TYPE',
66+
});
5767

58-
assert.throws(() => {
59-
util.styleText(['invalid'], 'text');
60-
}, {
61-
code: 'ERR_INVALID_ARG_VALUE',
62-
});
68+
assert.doesNotThrow(() => {
69+
util.styleText('red', 'text', { stream: {}, validateStream: false });
70+
});
71+
assert.strictEqual(
72+
util.styleText('red', 'test', { validateStream: false }),
73+
styled,
74+
);
6375

64-
assert.throws(() => {
65-
util.styleText('red', 'text', { stream: {} });
66-
}, {
67-
code: 'ERR_INVALID_ARG_TYPE',
68-
});
76+
const fd = common.getTTYfd();
77+
if (fd !== -1) {
78+
const writeStream = new WriteStream(fd);
6979

70-
// does not throw
71-
util.styleText('red', 'text', { stream: {}, validateStream: false });
72-
73-
assert.strictEqual(
74-
util.styleText('red', 'test', { validateStream: false }),
75-
styled,
76-
);
77-
78-
const fd = common.getTTYfd();
79-
if (fd !== -1) {
80-
const writeStream = new WriteStream(fd);
81-
82-
const originalEnv = process.env;
83-
[
84-
{ isTTY: true, env: {}, expected: styled },
85-
{ isTTY: false, env: {}, expected: noChange },
86-
{ isTTY: true, env: { NODE_DISABLE_COLORS: '1' }, expected: noChange },
87-
{ isTTY: true, env: { NO_COLOR: '1' }, expected: noChange },
88-
{ isTTY: true, env: { FORCE_COLOR: '1' }, expected: styled },
89-
{ isTTY: true, env: { FORCE_COLOR: '1', NODE_DISABLE_COLORS: '1' }, expected: styled },
90-
{ isTTY: false, env: { FORCE_COLOR: '1', NO_COLOR: '1', NODE_DISABLE_COLORS: '1' }, expected: styled },
91-
{ isTTY: true, env: { FORCE_COLOR: '1', NO_COLOR: '1', NODE_DISABLE_COLORS: '1' }, expected: styled },
92-
].forEach((testCase) => {
93-
writeStream.isTTY = testCase.isTTY;
94-
process.env = {
95-
...process.env,
96-
...testCase.env
97-
};
98-
{
99-
const output = util.styleText('red', 'test', { stream: writeStream });
100-
assert.strictEqual(output, testCase.expected);
101-
}
102-
{
103-
// Check that when passing an array of styles, the output behaves the same
104-
const output = util.styleText(['red'], 'test', { stream: writeStream });
105-
assert.strictEqual(output, testCase.expected);
80+
const originalEnv = process.env;
81+
[
82+
{ isTTY: true, env: {}, expected: styled },
83+
{ isTTY: false, env: {}, expected: noChange },
84+
{ isTTY: true, env: { NODE_DISABLE_COLORS: '1' }, expected: noChange },
85+
{ isTTY: true, env: { NO_COLOR: '1' }, expected: noChange },
86+
{ isTTY: true, env: { FORCE_COLOR: '1' }, expected: styled },
87+
{ isTTY: true, env: { FORCE_COLOR: '1', NODE_DISABLE_COLORS: '1' }, expected: styled },
88+
{ isTTY: false, env: { FORCE_COLOR: '1', NO_COLOR: '1', NODE_DISABLE_COLORS: '1' }, expected: styled },
89+
{ isTTY: true, env: { FORCE_COLOR: '1', NO_COLOR: '1', NODE_DISABLE_COLORS: '1' }, expected: styled },
90+
].forEach((testCase) => {
91+
writeStream.isTTY = testCase.isTTY;
92+
process.env = {
93+
...process.env,
94+
...testCase.env
95+
};
96+
{
97+
const output = util.styleText('red', 'test', { stream: writeStream });
98+
assert.strictEqual(output, testCase.expected);
99+
}
100+
{
101+
// Check that when passing an array of styles, the output behaves the same
102+
const output = util.styleText(['red'], 'test', { stream: writeStream });
103+
assert.strictEqual(output, testCase.expected);
104+
}
105+
process.env = originalEnv;
106+
});
107+
} else {
108+
common.skip('Could not create TTY fd');
106109
}
107-
process.env = originalEnv;
108-
});
109-
} else {
110-
common.skip('Could not create TTY fd');
111-
}

0 commit comments

Comments
 (0)