Skip to content

Commit 6944066

Browse files
committed
feat: add casing option
1 parent c3250c3 commit 6944066

File tree

2 files changed

+98
-93
lines changed

2 files changed

+98
-93
lines changed

src/modules/random/index.ts

Lines changed: 92 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import type { Faker } from '../..';
22
import { FakerError } from '../../errors/faker-error';
3+
import { deprecated } from '../../internal/deprecated';
4+
5+
export type Casing = 'upper' | 'lower' | 'mixed';
6+
7+
const UPPER_CHARS: readonly string[] = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
8+
const LOWER_CHARS: readonly string[] = 'abcdefghijklmnopqrstuvwxyz'.split('');
9+
const DIGIT_CHARS: readonly string[] = '0123456789'.split('');
310

411
/**
512
* Method to reduce array of characters.
@@ -141,25 +148,30 @@ export class Random {
141148
}
142149

143150
/**
144-
* Generating a string consisting of lower/upper alpha characters based on count and upcase options.
151+
* Generating a string consisting of alpha characters.
145152
*
146-
* @param options Either the number of characters or an options instance. Defaults to `{ count: 1, upcase: false, bannedChars: [] }`.
153+
* @param options Either the number of characters or an options instance. Defaults to `{ count: 1, casing: 'lower', bannedChars: [] }`.
147154
* @param options.count The number of characters to generate. Defaults to `1`.
148-
* @param options.upcase If true, the result will be uppercase. If false, it will be lowercase. Defaults to `false`.
155+
* @param options.casing The casing of the characters. Defaults to `'lower'`.
156+
* @param options.upcase Deprecated, use `casing: 'upper'` instead.
149157
* @param options.bannedChars An array with characters to exclude. Defaults to `[]`.
150158
*
151159
* @example
152160
* faker.random.alpha() // 'b'
153161
* faker.random.alpha(10) // 'qccrabobaf'
154-
* faker.random.alpha({ count: 5, upcase: true, bannedChars: ['a'] }) // 'DTCIC'
162+
* faker.random.alpha({ count: 5, casing: 'upper', bannedChars: ['A'] }) // 'DTCIC'
155163
*/
156164
// TODO @Shinigami92 2022-02-14: Tests covered `(count, options)`, but they were never typed like that
157165
alpha(
158166
options:
159167
| number
160168
| {
161169
count?: number;
170+
/**
171+
* @deprecated Use `casing` instead.
172+
*/
162173
upcase?: boolean;
174+
casing?: Casing;
163175
bannedChars?: readonly string[];
164176
} = {}
165177
): string {
@@ -168,52 +180,59 @@ export class Random {
168180
count: options,
169181
};
170182
}
171-
const { count = 1, upcase = false, bannedChars = [] } = options;
172-
173-
let charsArray = [
174-
'a',
175-
'b',
176-
'c',
177-
'd',
178-
'e',
179-
'f',
180-
'g',
181-
'h',
182-
'i',
183-
'j',
184-
'k',
185-
'l',
186-
'm',
187-
'n',
188-
'o',
189-
'p',
190-
'q',
191-
'r',
192-
's',
193-
't',
194-
'u',
195-
'v',
196-
'w',
197-
'x',
198-
'y',
199-
'z',
200-
];
183+
const { count = 1, upcase, bannedChars = [] } = options;
184+
185+
if (count <= 0) {
186+
return '';
187+
}
188+
189+
const {
190+
// Switch to 'mixed' with v8.0
191+
casing = upcase ? 'upper' : 'lower',
192+
} = options;
193+
194+
if (upcase != null) {
195+
deprecated({
196+
deprecated: 'faker.random.alpha({ upcase: true })',
197+
proposed: "faker.random.alpha({ casing: 'upper' })",
198+
since: 'v7.0',
199+
until: 'v8.0',
200+
});
201+
}
202+
203+
let charsArray: string[];
204+
switch (casing) {
205+
case 'upper':
206+
charsArray = [...UPPER_CHARS];
207+
break;
208+
case 'lower':
209+
charsArray = [...LOWER_CHARS];
210+
break;
211+
case 'mixed':
212+
default:
213+
charsArray = [...LOWER_CHARS, ...UPPER_CHARS];
214+
break;
215+
}
201216

202217
charsArray = arrayRemove(charsArray, bannedChars);
203218

204-
let wholeString = '';
205-
for (let i = 0; i < count; i++) {
206-
wholeString += this.faker.helpers.arrayElement(charsArray);
219+
if (charsArray.length === 0) {
220+
throw new FakerError(
221+
'Unable to generate string, because all possible characters are banned.'
222+
);
207223
}
208224

209-
return upcase ? wholeString.toUpperCase() : wholeString;
225+
return Array.from({ length: count }, () =>
226+
this.faker.helpers.arrayElement(charsArray)
227+
).join('');
210228
}
211229

212230
/**
213-
* Generating a string consisting of lower/upper alpha characters and digits based on count and upcase options.
231+
* Generating a string consisting of alpha characters and digits.
214232
*
215233
* @param count The number of characters and digits to generate. Defaults to `1`.
216234
* @param options The options to use. Defaults to `{ bannedChars: [] }`.
235+
* @param options.casing The casing of the characters. Defaults to `'lower'`.
217236
* @param options.bannedChars An array of characters and digits which should be banned in the generated string. Defaults to `[]`.
218237
*
219238
* @example
@@ -223,48 +242,35 @@ export class Random {
223242
*/
224243
alphaNumeric(
225244
count: number = 1,
226-
options: { bannedChars?: readonly string[] } = {}
245+
options: {
246+
casing?: Casing;
247+
bannedChars?: readonly string[];
248+
} = {}
227249
): string {
228-
const { bannedChars = [] } = options;
229-
230-
let charsArray = [
231-
'0',
232-
'1',
233-
'2',
234-
'3',
235-
'4',
236-
'5',
237-
'6',
238-
'7',
239-
'8',
240-
'9',
241-
'a',
242-
'b',
243-
'c',
244-
'd',
245-
'e',
246-
'f',
247-
'g',
248-
'h',
249-
'i',
250-
'j',
251-
'k',
252-
'l',
253-
'm',
254-
'n',
255-
'o',
256-
'p',
257-
'q',
258-
'r',
259-
's',
260-
't',
261-
'u',
262-
'v',
263-
'w',
264-
'x',
265-
'y',
266-
'z',
267-
];
250+
if (count <= 0) {
251+
return '';
252+
}
253+
254+
const {
255+
// Switch to 'mixed' with v8.0
256+
casing = 'lower',
257+
bannedChars = [],
258+
} = options;
259+
260+
let charsArray = [...DIGIT_CHARS];
261+
262+
switch (casing) {
263+
case 'upper':
264+
charsArray.push(...UPPER_CHARS);
265+
break;
266+
case 'lower':
267+
charsArray.push(...LOWER_CHARS);
268+
break;
269+
case 'mixed':
270+
default:
271+
charsArray.push(...LOWER_CHARS, ...UPPER_CHARS);
272+
break;
273+
}
268274

269275
charsArray = arrayRemove(charsArray, bannedChars);
270276

@@ -274,12 +280,9 @@ export class Random {
274280
);
275281
}
276282

277-
let wholeString = '';
278-
for (let i = 0; i < count; i++) {
279-
wholeString += this.faker.helpers.arrayElement(charsArray);
280-
}
281-
282-
return wholeString;
283+
return Array.from({ length: count }, () =>
284+
this.faker.helpers.arrayElement(charsArray)
285+
).join('');
283286
}
284287

285288
/**
@@ -310,9 +313,9 @@ export class Random {
310313

311314
const { allowLeadingZeros = false, bannedDigits = [] } = options;
312315

313-
const allowedDigits = '0123456789'
314-
.split('')
315-
.filter((digit) => !bannedDigits.includes(digit));
316+
const allowedDigits = DIGIT_CHARS.filter(
317+
(digit) => !bannedDigits.includes(digit)
318+
);
316319

317320
if (
318321
allowedDigits.length === 0 ||

src/modules/vehicle/index.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,16 @@ export class Vehicle {
7575
* faker.vehicle.vin() // 'YV1MH682762184654'
7676
*/
7777
vin(): string {
78-
const bannedChars = ['o', 'i', 'q'];
78+
const bannedChars = ['o', 'i', 'q', 'O', 'I', 'Q'];
7979
return `${this.faker.random.alphaNumeric(10, {
80+
casing: 'upper',
8081
bannedChars,
8182
})}${this.faker.random.alpha({
8283
count: 1,
83-
upcase: true,
84+
casing: 'upper',
8485
bannedChars,
8586
})}${this.faker.random.alphaNumeric(1, {
87+
casing: 'upper',
8688
bannedChars,
8789
})}${this.faker.datatype.number({ min: 10000, max: 99999 })}` // return five digit #
8890
.toUpperCase();
@@ -107,14 +109,14 @@ export class Vehicle {
107109
vrm(): string {
108110
return `${this.faker.random.alpha({
109111
count: 2,
110-
upcase: true,
112+
casing: 'upper',
111113
})}${this.faker.datatype.number({
112114
min: 0,
113115
max: 9,
114116
})}${this.faker.datatype.number({
115117
min: 0,
116118
max: 9,
117-
})}${this.faker.random.alpha({ count: 3, upcase: true })}`.toUpperCase();
119+
})}${this.faker.random.alpha({ count: 3, casing: 'upper' })}`.toUpperCase();
118120
}
119121

120122
/**

0 commit comments

Comments
 (0)