From 4c0e41831f8d2fad92f85cea647cbd0873fd842e Mon Sep 17 00:00:00 2001 From: Shinigami Date: Sat, 21 May 2022 16:30:33 +0200 Subject: feat: add casing option (#955) Co-authored-by: Eric Cheng --- src/modules/random/index.ts | 181 ++++++++++++++++++++++---------------------- 1 file changed, 92 insertions(+), 89 deletions(-) (limited to 'src/modules/random') diff --git a/src/modules/random/index.ts b/src/modules/random/index.ts index e3e36ec4..a95b44ab 100644 --- a/src/modules/random/index.ts +++ b/src/modules/random/index.ts @@ -1,5 +1,12 @@ import type { Faker } from '../..'; import { FakerError } from '../../errors/faker-error'; +import { deprecated } from '../../internal/deprecated'; + +export type Casing = 'upper' | 'lower' | 'mixed'; + +const UPPER_CHARS: readonly string[] = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''); +const LOWER_CHARS: readonly string[] = 'abcdefghijklmnopqrstuvwxyz'.split(''); +const DIGIT_CHARS: readonly string[] = '0123456789'.split(''); /** * Method to reduce array of characters. @@ -141,17 +148,18 @@ export class Random { } /** - * Generating a string consisting of lower/upper alpha characters based on count and upcase options. + * Generating a string consisting of letters in the English alphabet. * - * @param options Either the number of characters or an options instance. Defaults to `{ count: 1, upcase: false, bannedChars: [] }`. + * @param options Either the number of characters or an options instance. Defaults to `{ count: 1, casing: 'lower', bannedChars: [] }`. * @param options.count The number of characters to generate. Defaults to `1`. - * @param options.upcase If true, the result will be uppercase. If false, it will be lowercase. Defaults to `false`. + * @param options.casing The casing of the characters. Defaults to `'lower'`. + * @param options.upcase Deprecated, use `casing: 'upper'` instead. * @param options.bannedChars An array with characters to exclude. Defaults to `[]`. * * @example * faker.random.alpha() // 'b' * faker.random.alpha(10) // 'qccrabobaf' - * faker.random.alpha({ count: 5, upcase: true, bannedChars: ['a'] }) // 'DTCIC' + * faker.random.alpha({ count: 5, casing: 'upper', bannedChars: ['A'] }) // 'DTCIC' */ // TODO @Shinigami92 2022-02-14: Tests covered `(count, options)`, but they were never typed like that alpha( @@ -159,7 +167,11 @@ export class Random { | number | { count?: number; + /** + * @deprecated Use `casing` instead. + */ upcase?: boolean; + casing?: Casing; bannedChars?: readonly string[]; } = {} ): string { @@ -168,52 +180,59 @@ export class Random { count: options, }; } - const { count = 1, upcase = false, bannedChars = [] } = options; - - let charsArray = [ - 'a', - 'b', - 'c', - 'd', - 'e', - 'f', - 'g', - 'h', - 'i', - 'j', - 'k', - 'l', - 'm', - 'n', - 'o', - 'p', - 'q', - 'r', - 's', - 't', - 'u', - 'v', - 'w', - 'x', - 'y', - 'z', - ]; + const { count = 1, upcase, bannedChars = [] } = options; + + if (count <= 0) { + return ''; + } + + const { + // Switch to 'mixed' with v8.0 + casing = upcase ? 'upper' : 'lower', + } = options; + + if (upcase != null) { + deprecated({ + deprecated: 'faker.random.alpha({ upcase: true })', + proposed: "faker.random.alpha({ casing: 'upper' })", + since: 'v7.0', + until: 'v8.0', + }); + } + + let charsArray: string[]; + switch (casing) { + case 'upper': + charsArray = [...UPPER_CHARS]; + break; + case 'lower': + charsArray = [...LOWER_CHARS]; + break; + case 'mixed': + default: + charsArray = [...LOWER_CHARS, ...UPPER_CHARS]; + break; + } charsArray = arrayRemove(charsArray, bannedChars); - let wholeString = ''; - for (let i = 0; i < count; i++) { - wholeString += this.faker.helpers.arrayElement(charsArray); + if (charsArray.length === 0) { + throw new FakerError( + 'Unable to generate string, because all possible characters are banned.' + ); } - return upcase ? wholeString.toUpperCase() : wholeString; + return Array.from({ length: count }, () => + this.faker.helpers.arrayElement(charsArray) + ).join(''); } /** - * Generating a string consisting of lower/upper alpha characters and digits based on count and upcase options. + * Generating a string consisting of alpha characters and digits. * * @param count The number of characters and digits to generate. Defaults to `1`. * @param options The options to use. Defaults to `{ bannedChars: [] }`. + * @param options.casing The casing of the characters. Defaults to `'lower'`. * @param options.bannedChars An array of characters and digits which should be banned in the generated string. Defaults to `[]`. * * @example @@ -223,48 +242,35 @@ export class Random { */ alphaNumeric( count: number = 1, - options: { bannedChars?: readonly string[] } = {} + options: { + casing?: Casing; + bannedChars?: readonly string[]; + } = {} ): string { - const { bannedChars = [] } = options; - - let charsArray = [ - '0', - '1', - '2', - '3', - '4', - '5', - '6', - '7', - '8', - '9', - 'a', - 'b', - 'c', - 'd', - 'e', - 'f', - 'g', - 'h', - 'i', - 'j', - 'k', - 'l', - 'm', - 'n', - 'o', - 'p', - 'q', - 'r', - 's', - 't', - 'u', - 'v', - 'w', - 'x', - 'y', - 'z', - ]; + if (count <= 0) { + return ''; + } + + const { + // Switch to 'mixed' with v8.0 + casing = 'lower', + bannedChars = [], + } = options; + + let charsArray = [...DIGIT_CHARS]; + + switch (casing) { + case 'upper': + charsArray.push(...UPPER_CHARS); + break; + case 'lower': + charsArray.push(...LOWER_CHARS); + break; + case 'mixed': + default: + charsArray.push(...LOWER_CHARS, ...UPPER_CHARS); + break; + } charsArray = arrayRemove(charsArray, bannedChars); @@ -274,12 +280,9 @@ export class Random { ); } - let wholeString = ''; - for (let i = 0; i < count; i++) { - wholeString += this.faker.helpers.arrayElement(charsArray); - } - - return wholeString; + return Array.from({ length: count }, () => + this.faker.helpers.arrayElement(charsArray) + ).join(''); } /** @@ -310,9 +313,9 @@ export class Random { const { allowLeadingZeros = false, bannedDigits = [] } = options; - const allowedDigits = '0123456789' - .split('') - .filter((digit) => !bannedDigits.includes(digit)); + const allowedDigits = DIGIT_CHARS.filter( + (digit) => !bannedDigits.includes(digit) + ); if ( allowedDigits.length === 0 || -- cgit v1.2.3