aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/modules/random/index.ts181
-rw-r--r--src/modules/vehicle/index.ts10
-rw-r--r--test/random.spec.ts61
3 files changed, 153 insertions, 99 deletions
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 ||
diff --git a/src/modules/vehicle/index.ts b/src/modules/vehicle/index.ts
index ec010af9..fb5cd9f9 100644
--- a/src/modules/vehicle/index.ts
+++ b/src/modules/vehicle/index.ts
@@ -75,14 +75,16 @@ export class Vehicle {
* faker.vehicle.vin() // 'YV1MH682762184654'
*/
vin(): string {
- const bannedChars = ['o', 'i', 'q'];
+ const bannedChars = ['o', 'i', 'q', 'O', 'I', 'Q'];
return `${this.faker.random.alphaNumeric(10, {
+ casing: 'upper',
bannedChars,
})}${this.faker.random.alpha({
count: 1,
- upcase: true,
+ casing: 'upper',
bannedChars,
})}${this.faker.random.alphaNumeric(1, {
+ casing: 'upper',
bannedChars,
})}${this.faker.datatype.number({ min: 10000, max: 99999 })}` // return five digit #
.toUpperCase();
@@ -107,14 +109,14 @@ export class Vehicle {
vrm(): string {
return `${this.faker.random.alpha({
count: 2,
- upcase: true,
+ casing: 'upper',
})}${this.faker.datatype.number({
min: 0,
max: 9,
})}${this.faker.datatype.number({
min: 0,
max: 9,
- })}${this.faker.random.alpha({ count: 3, upcase: true })}`.toUpperCase();
+ })}${this.faker.random.alpha({ count: 3, casing: 'upper' })}`.toUpperCase();
}
/**
diff --git a/test/random.spec.ts b/test/random.spec.ts
index d6fe3da7..3ff24ff7 100644
--- a/test/random.spec.ts
+++ b/test/random.spec.ts
@@ -179,9 +179,13 @@ describe('random', () => {
expect(actual).toMatch(/^[a-z]$/);
});
- it('should return uppercase when upcase option is true', () => {
- const actual = faker.random.alpha({ upcase: true });
- expect(actual).toMatch(/^[A-Z]$/);
+ it.each([
+ ['upper', /^[A-Z]{250}$/],
+ ['lower', /^[a-z]{250}$/],
+ ['mixed', /^[a-zA-Z]{250}$/],
+ ] as const)('should return %s-case', (casing, pattern) => {
+ const actual = faker.random.alpha({ count: 250, casing });
+ expect(actual).toMatch(pattern);
});
it('should generate many random letters', () => {
@@ -190,6 +194,15 @@ describe('random', () => {
expect(actual).toHaveLength(5);
});
+ it.each([0, -1, -100])(
+ 'should return empty string when length is <= 0',
+ (length) => {
+ const actual = faker.random.alpha(length);
+
+ expect(actual).toBe('');
+ }
+ );
+
it('should be able to ban some characters', () => {
const actual = faker.random.alpha({
count: 5,
@@ -210,14 +223,28 @@ describe('random', () => {
expect(alphaText).toMatch(/^[b-oq-z]{5}$/);
});
+ it('should throw if all possible characters being banned', () => {
+ const bannedChars = 'abcdefghijklmnopqrstuvwxyz'.split('');
+ expect(() =>
+ faker.random.alpha({
+ count: 5,
+ bannedChars,
+ })
+ ).toThrowError(
+ new FakerError(
+ 'Unable to generate string, because all possible characters are banned.'
+ )
+ );
+ });
+
it('should not mutate the input object', () => {
const input: {
count: number;
- upcase: boolean;
+ casing: 'mixed';
bannedChars: string[];
} = Object.freeze({
count: 5,
- upcase: true,
+ casing: 'mixed',
bannedChars: ['a', '%'],
});
@@ -233,12 +260,30 @@ describe('random', () => {
expect(actual).toHaveLength(1);
});
+ it.each([
+ ['upper', /^[A-Z0-9]{250}$/],
+ ['lower', /^[a-z0-9]{250}$/],
+ ['mixed', /^[a-zA-Z0-9]{250}$/],
+ ] as const)('should return %s-case', (casing, pattern) => {
+ const actual = faker.random.alphaNumeric(250, { casing });
+ expect(actual).toMatch(pattern);
+ });
+
it('should generate many random characters', () => {
const actual = faker.random.alphaNumeric(5);
expect(actual).toHaveLength(5);
});
+ it.each([0, -1, -100])(
+ 'should return empty string when length is <= 0',
+ (length) => {
+ const actual = faker.random.alphaNumeric(length);
+
+ expect(actual).toBe('');
+ }
+ );
+
it('should be able to ban all alphabetic characters', () => {
const bannedChars = 'abcdefghijklmnopqrstuvwxyz'.split('');
const alphaText = faker.random.alphaNumeric(5, {
@@ -278,7 +323,11 @@ describe('random', () => {
faker.random.alphaNumeric(5, {
bannedChars,
})
- ).toThrowError();
+ ).toThrowError(
+ new FakerError(
+ 'Unable to generate string, because all possible characters are banned.'
+ )
+ );
});
it('should not mutate the input object', () => {