Skip to content

Commit c00f7be

Browse files
committed
chore: merge next
2 parents 66c7799 + 47b2cfc commit c00f7be

File tree

6 files changed

+207
-86
lines changed

6 files changed

+207
-86
lines changed

docs/.vitepress/config.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,7 @@ const config = defineConfig({
112112

113113
socialLinks: [
114114
{ icon: 'discord', link: 'https://chat.fakerjs.dev' },
115-
{
116-
icon: {
117-
svg: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 417.8 512"><path d="M417.8 179.1c0-97.2-63.7-125.7-63.7-125.7-62.5-28.7-228.5-28.4-290.4 0 0 0-63.7 28.5-63.7 125.7 0 115.7-6.6 259.4 105.6 289.1 40.5 10.7 75.3 13 103.3 11.4 50.8-2.8 79.3-18.1 79.3-18.1l-1.7-36.9s-36.3 11.4-77.1 10.1c-40.4-1.4-83-4.4-89.6-54-.6-4.4-.9-9-.9-13.9 85.6 20.9 158.6 9.1 178.7 6.7 56.1-6.7 105-41.3 111.2-72.9 9.8-49.8 9-121.5 9-121.5zm-75.1 125.2h-46.6V190.1c0-49.7-64-51.6-64 6.9v62.5h-46.3V197c0-58.5-64-56.6-64-6.9v114.2H75.1c0-122.1-5.2-147.9 18.4-175 25.9-28.9 79.8-30.8 103.8 6.1l11.6 19.5 11.6-19.5c24.1-37.1 78.1-34.8 103.8-6.1 23.7 27.3 18.4 53 18.4 175z"/></svg>',
118-
},
119-
link: 'https://fosstodon.org/@faker_js',
120-
},
115+
{ icon: 'mastodon', link: 'https://fosstodon.org/@faker_js' },
121116
{ icon: 'twitter', link: 'https://twitter.com/faker_js' },
122117
{ icon: 'github', link: 'https://github.com/faker-js/faker' },
123118
],

src/modules/string/index.ts

Lines changed: 65 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,49 @@ export class StringModule {
9696
}
9797
}
9898

99+
/**
100+
* Generates a string from the given characters.
101+
*
102+
* @param characters The characters to use for the string. Can be a string or an array of characters.
103+
* If it is an array, then each element is treated as a single character even if it is a string with multiple characters.
104+
* @param length The length of the string to generate. Defaults to `1`.
105+
* @param length.min The minimum length of the string to generate.
106+
* @param length.max The maximum length of the string to generate.
107+
*
108+
* @example
109+
* faker.string.fromCharacters('abc') // 'c'
110+
* faker.string.fromCharacters(['a', 'b', 'c']) // 'a'
111+
* faker.string.fromCharacters('abc', 10) // 'cbbbacbacb'
112+
* faker.string.fromCharacters('abc', { min: 5, max: 10 }) // 'abcaaaba'
113+
*
114+
* @since 8.0.0
115+
*/
116+
fromCharacters(
117+
characters: string | ReadonlyArray<string>,
118+
length: number | { min: number; max: number } = 1
119+
): string {
120+
length = this.faker.helpers.rangeToNumber(length);
121+
if (length <= 0) {
122+
return '';
123+
}
124+
125+
if (typeof characters === 'string') {
126+
characters = characters.split('');
127+
}
128+
129+
if (characters.length === 0) {
130+
throw new FakerError(
131+
'Unable to generate string: No characters to select from.'
132+
);
133+
}
134+
135+
return this.faker.helpers
136+
.multiple(() => this.faker.helpers.arrayElement(characters as string[]), {
137+
count: length,
138+
})
139+
.join('');
140+
}
141+
99142
/**
100143
* Generating a string consisting of letters in the English alphabet.
101144
*
@@ -157,15 +200,7 @@ export class StringModule {
157200

158201
charsArray = charsArray.filter((elem) => !exclude.includes(elem));
159202

160-
if (charsArray.length === 0) {
161-
throw new FakerError(
162-
'Unable to generate string, because all possible characters are excluded.'
163-
);
164-
}
165-
166-
return Array.from({ length }, () =>
167-
this.faker.helpers.arrayElement(charsArray)
168-
).join('');
203+
return this.fromCharacters(charsArray, length);
169204
}
170205

171206
/**
@@ -230,15 +265,7 @@ export class StringModule {
230265

231266
charsArray = charsArray.filter((elem) => !exclude.includes(elem));
232267

233-
if (charsArray.length === 0) {
234-
throw new FakerError(
235-
'Unable to generate string, because all possible characters are excluded.'
236-
);
237-
}
238-
239-
return Array.from({ length }, () =>
240-
this.faker.helpers.arrayElement(charsArray)
241-
).join('');
268+
return this.fromCharacters(charsArray, length);
242269
}
243270

244271
/**
@@ -266,18 +293,10 @@ export class StringModule {
266293
} = {}
267294
): string {
268295
const { prefix = '0b' } = options;
269-
const length = this.faker.helpers.rangeToNumber(options.length ?? 1);
270-
if (length <= 0) {
271-
return prefix;
272-
}
273-
274-
let binaryString = '';
275296

276-
for (let i = 0; i < length; i++) {
277-
binaryString += this.faker.helpers.arrayElement(['0', '1']);
278-
}
279-
280-
return `${prefix}${binaryString}`;
297+
let result = prefix;
298+
result += this.fromCharacters(['0', '1'], options.length ?? 1);
299+
return result;
281300
}
282301

283302
/**
@@ -305,27 +324,13 @@ export class StringModule {
305324
} = {}
306325
): string {
307326
const { prefix = '0o' } = options;
308-
const length = this.faker.helpers.rangeToNumber(options.length ?? 1);
309-
if (length <= 0) {
310-
return prefix;
311-
}
312327

313-
let octalString = '';
314-
315-
for (let i = 0; i < length; i++) {
316-
octalString += this.faker.helpers.arrayElement([
317-
'0',
318-
'1',
319-
'2',
320-
'3',
321-
'4',
322-
'5',
323-
'6',
324-
'7',
325-
]);
326-
}
327-
328-
return `${prefix}${octalString}`;
328+
let result = prefix;
329+
result += this.fromCharacters(
330+
['0', '1', '2', '3', '4', '5', '6', '7'],
331+
options.length ?? 1
332+
);
333+
return result;
329334
}
330335

331336
/**
@@ -362,10 +367,8 @@ export class StringModule {
362367
return prefix;
363368
}
364369

365-
let wholeString = '';
366-
367-
for (let i = 0; i < length; i++) {
368-
wholeString += this.faker.helpers.arrayElement([
370+
let wholeString = this.fromCharacters(
371+
[
369372
'0',
370373
'1',
371374
'2',
@@ -388,8 +391,9 @@ export class StringModule {
388391
'D',
389392
'E',
390393
'F',
391-
]);
392-
}
394+
],
395+
length
396+
);
393397

394398
if (casing === 'upper') {
395399
wholeString = wholeString.toUpperCase();
@@ -470,9 +474,7 @@ export class StringModule {
470474
);
471475
}
472476

473-
while (result.length < length) {
474-
result += this.faker.helpers.arrayElement(allowedDigits);
475-
}
477+
result += this.fromCharacters(allowedDigits, length - result.length);
476478

477479
return result;
478480
}
@@ -589,14 +591,8 @@ export class StringModule {
589591
* @since 8.0.0
590592
*/
591593
special(length: number | { min: number; max: number } = 1): string {
592-
length = this.faker.helpers.rangeToNumber(length);
593-
if (length <= 0) {
594-
return '';
595-
}
596-
597-
let specialString = '';
598-
for (let i = 0; i < length; i++) {
599-
specialString += this.faker.helpers.arrayElement([
594+
return this.fromCharacters(
595+
[
600596
'!',
601597
'"',
602598
'#',
@@ -629,9 +625,8 @@ export class StringModule {
629625
'|',
630626
'}',
631627
'~',
632-
]);
633-
}
634-
635-
return specialString;
628+
],
629+
length
630+
);
636631
}
637632
}

test/__snapshots__/string.spec.ts.snap

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@ exports[`string > 42 > binary > with length and empty prefix 1`] = `"0110111"`;
6262

6363
exports[`string > 42 > binary > with length range 1`] = `"0b11011110000001"`;
6464

65+
exports[`string > 42 > fromCharacters > with string characters 1`] = `"o"`;
66+
67+
exports[`string > 42 > fromCharacters > with string characters and length 1`] = `"oaroa"`;
68+
69+
exports[`string > 42 > fromCharacters > with string characters and length range 1`] = `"aroaabbfofffor"`;
70+
71+
exports[`string > 42 > fromCharacters > with string[] characters 1`] = `"o"`;
72+
73+
exports[`string > 42 > fromCharacters > with string[] characters and length 1`] = `"oaroa"`;
74+
75+
exports[`string > 42 > fromCharacters > with string[] characters and length range 1`] = `"aroaabbfofffor"`;
76+
6577
exports[`string > 42 > hexadecimal > noArgs 1`] = `"0x8"`;
6678

6779
exports[`string > 42 > hexadecimal > with casing = lower 1`] = `"0x8"`;
@@ -224,6 +236,18 @@ exports[`string > 1211 > binary > with length and empty prefix 1`] = `"1011001"`
224236
225237
exports[`string > 1211 > binary > with length range 1`] = `"0b01100101010100011101"`;
226238
239+
exports[`string > 1211 > fromCharacters > with string characters 1`] = `"r"`;
240+
241+
exports[`string > 1211 > fromCharacters > with string characters and length 1`] = `"rorao"`;
242+
243+
exports[`string > 1211 > fromCharacters > with string characters and length range 1`] = `"oraofrfafaoaoofaaafa"`;
244+
245+
exports[`string > 1211 > fromCharacters > with string[] characters 1`] = `"r"`;
246+
247+
exports[`string > 1211 > fromCharacters > with string[] characters and length 1`] = `"rorao"`;
248+
249+
exports[`string > 1211 > fromCharacters > with string[] characters and length range 1`] = `"oraofrfafaoaoofaaafa"`;
250+
227251
exports[`string > 1211 > hexadecimal > noArgs 1`] = `"0xE"`;
228252
229253
exports[`string > 1211 > hexadecimal > with casing = lower 1`] = `"0xe"`;
@@ -386,6 +410,18 @@ exports[`string > 1337 > binary > with length and empty prefix 1`] = `"0100010"`
386410
387411
exports[`string > 1337 > binary > with length range 1`] = `"0b100010000110"`;
388412
413+
exports[`string > 1337 > fromCharacters > with string characters 1`] = `"o"`;
414+
415+
exports[`string > 1337 > fromCharacters > with string characters and length 1`] = `"obfoo"`;
416+
417+
exports[`string > 1337 > fromCharacters > with string characters and length range 1`] = `"bfoobofoobbo"`;
418+
419+
exports[`string > 1337 > fromCharacters > with string[] characters 1`] = `"o"`;
420+
421+
exports[`string > 1337 > fromCharacters > with string[] characters and length 1`] = `"obfoo"`;
422+
423+
exports[`string > 1337 > fromCharacters > with string[] characters and length range 1`] = `"bfoobofoobbo"`;
424+
389425
exports[`string > 1337 > hexadecimal > noArgs 1`] = `"0x5"`;
390426
391427
exports[`string > 1337 > hexadecimal > with casing = lower 1`] = `"0x5"`;

test/all_functional.spec.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ const BROKEN_LOCALE_METHODS = {
2929
state: ['az', 'cz', 'nb_NO', 'sk'],
3030
stateAbbr: ['cz', 'sk'],
3131
},
32+
string: {
33+
fromCharacters: '*',
34+
},
3235
person: {
3336
prefix: ['az', 'id_ID', 'ru', 'zh_CN', 'zh_TW'],
3437
suffix: ['az', 'it', 'mk', 'pt_PT', 'ru'],

test/random.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ describe('random', () => {
213213
})
214214
).toThrowError(
215215
new FakerError(
216-
'Unable to generate string, because all possible characters are excluded.'
216+
'Unable to generate string: No characters to select from.'
217217
)
218218
);
219219
});
@@ -332,7 +332,7 @@ describe('random', () => {
332332
})
333333
).toThrowError(
334334
new FakerError(
335-
'Unable to generate string, because all possible characters are excluded.'
335+
'Unable to generate string: No characters to select from.'
336336
)
337337
);
338338
});

0 commit comments

Comments
 (0)