Skip to content

Commit 208ed6e

Browse files
committed
Shim String.repeat
1 parent 80cf08a commit 208ed6e

File tree

4 files changed

+84
-7
lines changed

4 files changed

+84
-7
lines changed

internal/assert/assertion_error.js

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,44 @@ function endsWith(str, search, this_len) {
1616
return str.substring(this_len - search.length, this_len) === search;
1717
}
1818

19+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat
20+
function repeat(str, count) {
21+
if (str == null)
22+
throw new TypeError('can\'t convert ' + this + ' to object');
23+
24+
str = '' + str;
25+
// To convert string to integer.
26+
count = +count;
27+
// Check NaN
28+
if (count != count)
29+
count = 0;
30+
31+
if (count < 0)
32+
throw new RangeError('repeat count must be non-negative');
33+
34+
if (count == Infinity)
35+
throw new RangeError('repeat count must be less than infinity');
36+
37+
count = Math.floor(count);
38+
if (str.length == 0 || count == 0)
39+
return '';
40+
41+
// Ensuring count is a 31-bit integer allows us to heavily optimize the
42+
// main part. But anyway, most current (August 2014) browsers can't handle
43+
// strings 1 << 28 chars or longer, so:
44+
if (str.length * count >= 1 << 28)
45+
throw new RangeError('repeat count must not overflow maximum string size');
46+
47+
var maxCount = str.length * count;
48+
count = Math.floor(Math.log(count) / Math.log(2));
49+
while (count) {
50+
str += str;
51+
count--;
52+
}
53+
str += str.substring(0, maxCount - str.length);
54+
return str;
55+
}
56+
1957
let blue = '';
2058
let green = '';
2159
let red = '';
@@ -128,7 +166,7 @@ function createErrDiff(actual, expected, operator) {
128166
if (i > 2) {
129167
// Add position indicator for the first mismatch in case it is a
130168
// single line and the input length is less than the column length.
131-
indicator = `\n ${' '.repeat(i)}^`;
169+
indicator = `\n ${repeat(' ', i)}^`;
132170
i = 0;
133171
}
134172
}

test/common/index.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,44 @@ const getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors
44
? Object.getOwnPropertyDescriptors
55
: require('object.getownpropertydescriptors');
66

7+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat
8+
function repeat(str, count) {
9+
if (str == null)
10+
throw new TypeError('can\'t convert ' + this + ' to object');
11+
12+
str = '' + str;
13+
// To convert string to integer.
14+
count = +count;
15+
// Check NaN
16+
if (count != count)
17+
count = 0;
18+
19+
if (count < 0)
20+
throw new RangeError('repeat count must be non-negative');
21+
22+
if (count == Infinity)
23+
throw new RangeError('repeat count must be less than infinity');
24+
25+
count = Math.floor(count);
26+
if (str.length == 0 || count == 0)
27+
return '';
28+
29+
// Ensuring count is a 31-bit integer allows us to heavily optimize the
30+
// main part. But anyway, most current (August 2014) browsers can't handle
31+
// strings 1 << 28 chars or longer, so:
32+
if (str.length * count >= 1 << 28)
33+
throw new RangeError('repeat count must not overflow maximum string size');
34+
35+
var maxCount = str.length * count;
36+
count = Math.floor(Math.log(count) / Math.log(2));
37+
while (count) {
38+
str += str;
39+
count--;
40+
}
41+
str += str.substring(0, maxCount - str.length);
42+
return str;
43+
}
44+
745
const isBrowser = typeof window !== 'undefined';
846

947
const bigIntSupported = typeof BigInt !== 'undefined';
@@ -234,6 +272,7 @@ process.on('unhandledRejection', crashOnUnhandledRejection);
234272

235273
module.exports = {
236274
getOwnPropertyDescriptors,
275+
repeat,
237276
isBrowser,
238277
bigIntSupported,
239278
symbolToStringTagSupported,

test/parallel/test-assert-deep.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,7 @@ assert.throws(
676676
);
677677

678678
assert.throws(
679-
() => { assert.notDeepEqual('a'.repeat(1024), 'a'.repeat(1024)); },
679+
() => { assert.notDeepEqual(common.repeat('a', 1024), common.repeat('a', 1024)); },
680680
AssertionError,
681681
'notDeepEqual("a".repeat(1024), "a".repeat(1024))'
682682
);

test/parallel/test-assert.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ assert.throws(
8282
);
8383

8484
assert.throws(
85-
() => a.notStrictEqual('a '.repeat(30), 'a '.repeat(30)),
85+
() => a.notStrictEqual(common.repeat('a ', 30), common.repeat('a ', 30)),
8686
{
8787
// message: 'Expected "actual" to be strictly unequal to: ' +
8888
// `'${'a '.repeat(30)}'`,
@@ -393,7 +393,7 @@ assert.throws(() => { throw new Error(); }, (err) => err instanceof Error);
393393

394394
// Long values should be truncated for display.
395395
assert.throws(() => {
396-
assert.strictEqual('A'.repeat(1000), '');
396+
assert.strictEqual(common.repeat('A', 1000), '');
397397
}, {
398398
code: 'ERR_ASSERTION',
399399
// message: `${strictEqualMessageStart}+ actual - expected\n\n` +
@@ -595,9 +595,9 @@ assert.throws(
595595
`${actExp} ... Lines skipped\n` +
596596
'\n' +
597597
' [\n' +
598-
'+ 1,\n'.repeat(10) +
598+
common.repeat('+ 1,\n', 10) +
599599
'...\n' +
600-
'- 2,\n'.repeat(10) +
600+
common.repeat('- 2,\n', 10) +
601601
'...';
602602
assert.throws(
603603
() => assert.deepEqual(Array(12).fill(1), Array(12).fill(2)),
@@ -632,7 +632,7 @@ assert.throws(
632632
);
633633

634634
message = 'Expected "actual" not to be strictly deep-equal to:' +
635-
`\n\n[${'\n 1,'.repeat(25)}\n...\n`;
635+
`\n\n[${common.repeat('\n 1,', 25)}\n...\n`;
636636
const data = Array(31).fill(1);
637637
assert.throws(
638638
() => assert.notDeepEqual(data, data),

0 commit comments

Comments
 (0)