Skip to content

Commit 2eb2537

Browse files
authored
feat: fake with multiple parameters (#1459)
1 parent f4907a1 commit 2eb2537

2 files changed

Lines changed: 47 additions & 27 deletions

File tree

src/modules/helpers/index.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -487,10 +487,14 @@ export class HelpersModule {
487487
* and if that isn't possible, we will fall back to string:
488488
*
489489
* ```js
490-
* const message = faker.helpers.fake(`You can call me at {{phone.number(+!# !## #### #####!)}}.')
490+
* const message = faker.helpers.fake('You can call me at {{phone.number(+!# !## #### #####!)}}.')
491491
* ```
492492
*
493-
* Currently it is not possible to set more than a single parameter.
493+
* It is also possible to use multiple parameters (comma separated).
494+
*
495+
* ```js
496+
* const message = faker.helpers.fake('Your pin is {{string.numeric(4, {"allowLeadingZeros": true})}}.')
497+
* ```
494498
*
495499
* It is also NOT possible to use any non-faker methods or plain javascript in such templates.
496500
*
@@ -505,6 +509,7 @@ export class HelpersModule {
505509
* faker.helpers.fake('Good Morning {{person.firstName}}!') // 'Good Morning Estelle!'
506510
* faker.helpers.fake('You can call me at {{phone.number(!## ### #####!)}}.') // 'You can call me at 202 555 973722.'
507511
* faker.helpers.fake('I flipped the coin and got: {{helpers.arrayElement(["heads", "tails"])}}') // 'I flipped the coin and got: tails'
512+
* faker.helpers.fake('I rolled the dice and got: {{string.numeric(1, {"allowLeadingZeros": true})}}') // 'I rolled the dice and got: 6'
508513
*
509514
* @since 7.4.0
510515
*/
@@ -529,7 +534,7 @@ export class HelpersModule {
529534
let method = token.replace('}}', '').replace('{{', '');
530535

531536
// extract method parameters
532-
const regExp = /\(([^)]+)\)/;
537+
const regExp = /\(([^)]*)\)/;
533538
const matches = regExp.exec(method);
534539
let parameters = '';
535540
if (matches) {
@@ -550,7 +555,7 @@ export class HelpersModule {
550555
}
551556

552557
// Make method executable
553-
let fn: (args?: unknown) => unknown;
558+
let fn: (...args: unknown[]) => unknown;
554559
if (typeof currentModuleOrMethod === 'function') {
555560
fn = currentModuleOrMethod as (args?: unknown) => unknown;
556561
} else if (Array.isArray(currentDefinitions)) {
@@ -568,22 +573,17 @@ export class HelpersModule {
568573
// If parameters are populated here, they are always going to be of string type
569574
// since we might actually be dealing with an object or array,
570575
// we always attempt to the parse the incoming parameters into JSON
571-
let params: unknown;
576+
let params: unknown[];
572577
// Note: we experience a small performance hit here due to JSON.parse try / catch
573578
// If anyone actually needs to optimize this specific code path, please open a support issue on github
574579
try {
575-
params = JSON.parse(parameters);
580+
params = JSON.parse(`[${parameters}]`);
576581
} catch (err) {
577582
// since JSON.parse threw an error, assume parameters was actually a string
578-
params = parameters;
583+
params = [parameters];
579584
}
580585

581-
let result: string;
582-
if (typeof params === 'string' && params.length === 0) {
583-
result = String(fn());
584-
} else {
585-
result = String(fn(params));
586-
}
586+
const result = String(fn(...params));
587587

588588
// Replace the found tag with the returned fake value
589589
// We cannot use string.replace here because the result might contain evaluated characters

test/helpers.spec.ts

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -488,31 +488,51 @@ describe('helpers', () => {
488488
});
489489

490490
describe('fake()', () => {
491-
it('replaces a token with a random value for a method with no parameters', () => {
492-
const name = faker.helpers.fake('{{phone.number}}');
493-
expect(name).toMatch(/\d/);
491+
it('replaces a token with a random value for a method without parentheses', () => {
492+
const actual = faker.helpers.fake('{{string.numeric}}');
493+
expect(actual).toMatch(/^\d$/);
494494
});
495495

496-
it('replaces multiple tokens with random values for methods with no parameters', () => {
497-
const name = faker.helpers.fake(
498-
'{{helpers.arrayElement}}{{helpers.arrayElement}}{{helpers.arrayElement}}'
496+
it('replaces multiple tokens with random values for methods without parentheses', () => {
497+
const actual = faker.helpers.fake(
498+
'{{string.numeric}}{{string.numeric}}{{string.numeric}}'
499499
);
500-
expect(name).toMatch(/[abc]{3}/);
500+
expect(actual).toMatch(/^\d{3}$/);
501501
});
502502

503-
it('replaces a token with a random value for a methods with a simple parameter', () => {
504-
const random = faker.helpers.fake(
505-
'{{helpers.slugify("Will This Work")}}'
506-
);
507-
expect(random).toBe('Will-This-Work');
503+
it('replaces a token with a random value for a method with empty parentheses', () => {
504+
const actual = faker.helpers.fake('{{string.numeric()}}');
505+
expect(actual).toMatch(/^\d$/);
506+
});
507+
508+
it('replaces a token with a random value for a method with an unquoted parameter', () => {
509+
const random = faker.helpers.fake('{{helpers.slugify(This Works)}}');
510+
expect(random).toBe('This-Works');
511+
});
512+
513+
it('replaces a token with a random value for a method with a simple parameter', () => {
514+
const actual = faker.helpers.fake('{{string.numeric(3)}}');
515+
expect(actual).toMatch(/^\d{3}$/);
508516
});
509517

510518
it('replaces a token with a random value for a method with an array parameter', () => {
511519
const arr = ['one', 'two', 'three'];
512-
const random = faker.helpers.fake(
520+
const actual = faker.helpers.fake(
513521
'{{helpers.arrayElement(["one", "two", "three"])}}'
514522
);
515-
expect(arr).toContain(random);
523+
expect(arr).toContain(actual);
524+
});
525+
526+
it('replaces a token with a random value for a method with an object parameter', () => {
527+
const actual = faker.helpers.fake('{{random.alpha({"count": 3})}}');
528+
expect(actual).toMatch(/^[a-z]{3}$/i);
529+
});
530+
531+
it('replaces a token with a random value for a method with multiple parameters', () => {
532+
const actual = faker.helpers.fake(
533+
'{{string.numeric(5, {"allowLeadingZeros": true})}}'
534+
);
535+
expect(actual).toMatch(/^\d{5}$/);
516536
});
517537

518538
it('does not allow undefined parameters', () => {

0 commit comments

Comments
 (0)