Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: fake with multiple parameters #1459

Merged
merged 13 commits into from
Oct 23, 2022
28 changes: 16 additions & 12 deletions src/modules/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -487,10 +487,14 @@ export class HelpersModule {
* and if that isn't possible, we will fall back to string:
*
* ```js
* const message = faker.helpers.fake(`You can call me at {{phone.number(+!# !## #### #####!)}}.')
* const message = faker.helpers.fake('You can call me at {{phone.number(+!# !## #### #####!)}}.')
* ```
*
* Currently it is not possible to set more than a single parameter.
* It is also possible to use multiple parameters (comma separated).
*
* ```js
* const message = faker.helpers.fake('Your pin is {{random.numeric(4, {allowLeadingZeros: true})}}.')
* ```
*
* It is also NOT possible to use any non-faker methods or plain javascript in such templates.
*
Expand All @@ -505,6 +509,7 @@ export class HelpersModule {
* faker.helpers.fake('Good Morning {{name.firstName}}!') // 'Good Morning Estelle!'
* faker.helpers.fake('You can call me at {{phone.number(!## ### #####!)}}.') // 'You can call me at 202 555 973722.'
* faker.helpers.fake('I flipped the coin and got: {{helpers.arrayElement(["heads", "tails"])}}') // 'I flipped the coin and got: tails'
* faker.helpers.fake('I rolled the dice and got: {{random.numeric(1, {"allowLeadingZeros": true})}}') // 'I rolled the dice and got: 6'
*
* @since 7.4.0
*/
Expand Down Expand Up @@ -550,7 +555,7 @@ export class HelpersModule {
}

// Make method executable
let fn: (args?: unknown) => unknown;
let fn: (...args: unknown[]) => unknown;
if (typeof currentModuleOrMethod === 'function') {
fn = currentModuleOrMethod as (args?: unknown) => unknown;
} else if (Array.isArray(currentDefinitions)) {
Expand All @@ -568,22 +573,21 @@ export class HelpersModule {
// If parameters are populated here, they are always going to be of string type
// since we might actually be dealing with an object or array,
// we always attempt to the parse the incoming parameters into JSON
let params: unknown;
let params: unknown[];
// Note: we experience a small performance hit here due to JSON.parse try / catch
// If anyone actually needs to optimize this specific code path, please open a support issue on github
try {
params = JSON.parse(parameters);
params = JSON.parse(`[${parameters}]`);
} catch (err) {
// since JSON.parse threw an error, assume parameters was actually a string
params = parameters;
if (parameters.length === 0) {
params = [];
ST-DDT marked this conversation as resolved.
Show resolved Hide resolved
} else {
params = [parameters];
}
}

let result: string;
if (typeof params === 'string' && params.length === 0) {
result = String(fn());
} else {
result = String(fn(params));
}
const result = String(fn(...params));

// Replace the found tag with the returned fake value
// We cannot use string.replace here because the result might contain evaluated characters
Expand Down
7 changes: 7 additions & 0 deletions test/helpers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,13 @@ describe('helpers', () => {
expect(arr).toContain(random);
});

it('replaces a token with a random value for a method with multiple parameters', () => {
const random = faker.helpers.fake(
'{{random.numeric(1, {allowLeadingZeros: true})}}'
);
expect(random).toMatch(/^\d$/);
});

it('does not allow undefined parameters', () => {
expect(() =>
// @ts-expect-error: The parameter is required
Expand Down