Skip to content

Commit

Permalink
feat(string): generate string from characters (#1717)
Browse files Browse the repository at this point in the history
  • Loading branch information
ST-DDT committed Jan 11, 2023
1 parent f4615e1 commit 47b2cfc
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 80 deletions.
135 changes: 65 additions & 70 deletions src/modules/string/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,49 @@ export class StringModule {
}
}

/**
* Generates a string from the given characters.
*
* @param characters The characters to use for the string. Can be a string or an array of characters.
* If it is an array, then each element is treated as a single character even if it is a string with multiple characters.
* @param length The length of the string to generate. Defaults to `1`.
* @param length.min The minimum length of the string to generate.
* @param length.max The maximum length of the string to generate.
*
* @example
* faker.string.fromCharacters('abc') // 'c'
* faker.string.fromCharacters(['a', 'b', 'c']) // 'a'
* faker.string.fromCharacters('abc', 10) // 'cbbbacbacb'
* faker.string.fromCharacters('abc', { min: 5, max: 10 }) // 'abcaaaba'
*
* @since 8.0.0
*/
fromCharacters(
characters: string | ReadonlyArray<string>,
length: number | { min: number; max: number } = 1
): string {
length = this.faker.helpers.rangeToNumber(length);
if (length <= 0) {
return '';
}

if (typeof characters === 'string') {
characters = characters.split('');
}

if (characters.length === 0) {
throw new FakerError(
'Unable to generate string: No characters to select from.'
);
}

return this.faker.helpers
.multiple(() => this.faker.helpers.arrayElement(characters as string[]), {
count: length,
})
.join('');
}

/**
* Generating a string consisting of letters in the English alphabet.
*
Expand Down Expand Up @@ -157,15 +200,7 @@ export class StringModule {

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

if (charsArray.length === 0) {
throw new FakerError(
'Unable to generate string, because all possible characters are excluded.'
);
}

return Array.from({ length }, () =>
this.faker.helpers.arrayElement(charsArray)
).join('');
return this.fromCharacters(charsArray, length);
}

/**
Expand Down Expand Up @@ -230,15 +265,7 @@ export class StringModule {

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

if (charsArray.length === 0) {
throw new FakerError(
'Unable to generate string, because all possible characters are excluded.'
);
}

return Array.from({ length }, () =>
this.faker.helpers.arrayElement(charsArray)
).join('');
return this.fromCharacters(charsArray, length);
}

/**
Expand Down Expand Up @@ -266,18 +293,10 @@ export class StringModule {
} = {}
): string {
const { prefix = '0b' } = options;
const length = this.faker.helpers.rangeToNumber(options.length ?? 1);
if (length <= 0) {
return prefix;
}

let binaryString = '';

for (let i = 0; i < length; i++) {
binaryString += this.faker.helpers.arrayElement(['0', '1']);
}

return `${prefix}${binaryString}`;
let result = prefix;
result += this.fromCharacters(['0', '1'], options.length ?? 1);
return result;
}

/**
Expand Down Expand Up @@ -305,27 +324,13 @@ export class StringModule {
} = {}
): string {
const { prefix = '0o' } = options;
const length = this.faker.helpers.rangeToNumber(options.length ?? 1);
if (length <= 0) {
return prefix;
}

let octalString = '';

for (let i = 0; i < length; i++) {
octalString += this.faker.helpers.arrayElement([
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
]);
}

return `${prefix}${octalString}`;
let result = prefix;
result += this.fromCharacters(
['0', '1', '2', '3', '4', '5', '6', '7'],
options.length ?? 1
);
return result;
}

/**
Expand Down Expand Up @@ -362,10 +367,8 @@ export class StringModule {
return prefix;
}

let wholeString = '';

for (let i = 0; i < length; i++) {
wholeString += this.faker.helpers.arrayElement([
let wholeString = this.fromCharacters(
[
'0',
'1',
'2',
Expand All @@ -388,8 +391,9 @@ export class StringModule {
'D',
'E',
'F',
]);
}
],
length
);

if (casing === 'upper') {
wholeString = wholeString.toUpperCase();
Expand Down Expand Up @@ -470,9 +474,7 @@ export class StringModule {
);
}

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

return result;
}
Expand Down Expand Up @@ -589,14 +591,8 @@ export class StringModule {
* @since 8.0.0
*/
special(length: number | { min: number; max: number } = 1): string {
length = this.faker.helpers.rangeToNumber(length);
if (length <= 0) {
return '';
}

let specialString = '';
for (let i = 0; i < length; i++) {
specialString += this.faker.helpers.arrayElement([
return this.fromCharacters(
[
'!',
'"',
'#',
Expand Down Expand Up @@ -629,9 +625,8 @@ export class StringModule {
'|',
'}',
'~',
]);
}

return specialString;
],
length
);
}
}
36 changes: 36 additions & 0 deletions test/__snapshots__/string.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@ exports[`string > 42 > binary > with length and empty prefix 1`] = `"0110111"`;

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

exports[`string > 42 > fromCharacters > with string characters 1`] = `"o"`;

exports[`string > 42 > fromCharacters > with string characters and length 1`] = `"oaroa"`;

exports[`string > 42 > fromCharacters > with string characters and length range 1`] = `"aroaabbfofffor"`;

exports[`string > 42 > fromCharacters > with string[] characters 1`] = `"o"`;

exports[`string > 42 > fromCharacters > with string[] characters and length 1`] = `"oaroa"`;

exports[`string > 42 > fromCharacters > with string[] characters and length range 1`] = `"aroaabbfofffor"`;

exports[`string > 42 > hexadecimal > noArgs 1`] = `"0x8"`;

exports[`string > 42 > hexadecimal > with casing = lower 1`] = `"0x8"`;
Expand Down Expand Up @@ -224,6 +236,18 @@ exports[`string > 1211 > binary > with length and empty prefix 1`] = `"1011001"`
exports[`string > 1211 > binary > with length range 1`] = `"0b01100101010100011101"`;
exports[`string > 1211 > fromCharacters > with string characters 1`] = `"r"`;
exports[`string > 1211 > fromCharacters > with string characters and length 1`] = `"rorao"`;
exports[`string > 1211 > fromCharacters > with string characters and length range 1`] = `"oraofrfafaoaoofaaafa"`;
exports[`string > 1211 > fromCharacters > with string[] characters 1`] = `"r"`;
exports[`string > 1211 > fromCharacters > with string[] characters and length 1`] = `"rorao"`;
exports[`string > 1211 > fromCharacters > with string[] characters and length range 1`] = `"oraofrfafaoaoofaaafa"`;
exports[`string > 1211 > hexadecimal > noArgs 1`] = `"0xE"`;
exports[`string > 1211 > hexadecimal > with casing = lower 1`] = `"0xe"`;
Expand Down Expand Up @@ -386,6 +410,18 @@ exports[`string > 1337 > binary > with length and empty prefix 1`] = `"0100010"`
exports[`string > 1337 > binary > with length range 1`] = `"0b100010000110"`;
exports[`string > 1337 > fromCharacters > with string characters 1`] = `"o"`;
exports[`string > 1337 > fromCharacters > with string characters and length 1`] = `"obfoo"`;
exports[`string > 1337 > fromCharacters > with string characters and length range 1`] = `"bfoobofoobbo"`;
exports[`string > 1337 > fromCharacters > with string[] characters 1`] = `"o"`;
exports[`string > 1337 > fromCharacters > with string[] characters and length 1`] = `"obfoo"`;
exports[`string > 1337 > fromCharacters > with string[] characters and length range 1`] = `"bfoobofoobbo"`;
exports[`string > 1337 > hexadecimal > noArgs 1`] = `"0x5"`;
exports[`string > 1337 > hexadecimal > with casing = lower 1`] = `"0x5"`;
Expand Down
3 changes: 3 additions & 0 deletions test/all_functional.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ const BROKEN_LOCALE_METHODS = {
state: ['az', 'cz', 'nb_NO', 'sk'],
stateAbbr: ['cz', 'sk'],
},
string: {
fromCharacters: '*',
},
person: {
prefix: ['az', 'id_ID', 'ru', 'zh_CN', 'zh_TW'],
suffix: ['az', 'it', 'mk', 'pt_PT', 'ru'],
Expand Down
4 changes: 2 additions & 2 deletions test/random.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ describe('random', () => {
})
).toThrowError(
new FakerError(
'Unable to generate string, because all possible characters are excluded.'
'Unable to generate string: No characters to select from.'
)
);
});
Expand Down Expand Up @@ -332,7 +332,7 @@ describe('random', () => {
})
).toThrowError(
new FakerError(
'Unable to generate string, because all possible characters are excluded.'
'Unable to generate string: No characters to select from.'
)
);
});
Expand Down
Loading

0 comments on commit 47b2cfc

Please sign in to comment.