Skip to content

Commit a60d5e3

Browse files
authored
feat: support locale definitions directly from faker.fake (#884)
1 parent f2c3a39 commit a60d5e3

File tree

2 files changed

+52
-7
lines changed

2 files changed

+52
-7
lines changed

src/modules/fake/index.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,16 +88,29 @@ export class Fake {
8888
// split the method into module and function
8989
const parts = method.split('.');
9090

91-
if (this.faker[parts[0]] == null) {
92-
throw new FakerError(`Invalid module: ${parts[0]}`);
91+
let currentModuleOrMethod: unknown = this.faker;
92+
let currentDefinitions: unknown = this.faker.definitions;
93+
94+
// Search for the requested method or definition
95+
for (const part of parts) {
96+
currentModuleOrMethod = currentModuleOrMethod?.[part];
97+
currentDefinitions = currentDefinitions?.[part];
9398
}
9499

95-
if (this.faker[parts[0]][parts[1]] == null) {
96-
throw new FakerError(`Invalid method: ${parts[0]}.${parts[1]}`);
100+
// Make method executable
101+
let fn: (args?: unknown) => unknown;
102+
if (typeof currentModuleOrMethod === 'function') {
103+
fn = currentModuleOrMethod as (args?: unknown) => unknown;
104+
} else if (Array.isArray(currentDefinitions)) {
105+
fn = () =>
106+
this.faker.helpers.arrayElement(currentDefinitions as unknown[]);
107+
} else {
108+
throw new FakerError(`Invalid module method or definition: ${method}
109+
- faker.${method} is not a function
110+
- faker.definitions.${method} is not an array`);
97111
}
98112

99113
// assign the function from the module.function namespace
100-
let fn: (args?: unknown) => string = this.faker[parts[0]][parts[1]];
101114
fn = fn.bind(this);
102115

103116
// If parameters are populated here, they are always going to be of string type

test/fake.spec.ts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,52 @@ describe('fake', () => {
3838

3939
it('does not allow invalid module name', () => {
4040
expect(() => faker.fake('{{foo.bar}}')).toThrowError(
41-
new FakerError('Invalid module: foo')
41+
new FakerError(`Invalid module method or definition: foo.bar
42+
- faker.foo.bar is not a function
43+
- faker.definitions.foo.bar is not an array`)
44+
);
45+
});
46+
47+
it('does not allow missing method name', () => {
48+
expect(() => faker.fake('{{address}}')).toThrowError(
49+
new FakerError(`Invalid module method or definition: address
50+
- faker.address is not a function
51+
- faker.definitions.address is not an array`)
4252
);
4353
});
4454

4555
it('does not allow invalid method name', () => {
4656
expect(() => faker.fake('{{address.foo}}')).toThrowError(
47-
new FakerError('Invalid method: address.foo')
57+
new FakerError(`Invalid module method or definition: address.foo
58+
- faker.address.foo is not a function
59+
- faker.definitions.address.foo is not an array`)
60+
);
61+
});
62+
63+
it('does not allow invalid definitions data', () => {
64+
expect(() => faker.fake('{{finance.credit_card}}')).toThrowError(
65+
new FakerError(`Invalid module method or definition: finance.credit_card
66+
- faker.finance.credit_card is not a function
67+
- faker.definitions.finance.credit_card is not an array`)
4868
);
4969
});
5070

5171
it('should be able to return empty strings', () => {
5272
expect(faker.fake('{{helpers.repeatString}}')).toBe('');
5373
});
5474

75+
it('should be able to return locale definition strings', () => {
76+
expect(faker.definitions.cell_phone.formats).toContain(
77+
faker.fake('{{cell_phone.formats}}')
78+
);
79+
});
80+
81+
it('should be able to return locale definition strings that starts with the name of an existing module', () => {
82+
expect(faker.definitions.address.city_name).toContain(
83+
faker.fake('{{address.city_name}}')
84+
);
85+
});
86+
5587
it('should be able to handle only {{ brackets', () => {
5688
expect(faker.fake('{{hello')).toBe('{{hello');
5789
expect(faker.fake('hello{{')).toBe('hello{{');

0 commit comments

Comments
 (0)