Skip to content

Commit 94c96ba

Browse files
authored
chore: improve readability and type safety for loadDefinitions (#269)
1 parent 0f74908 commit 94c96ba

File tree

2 files changed

+44
-26
lines changed

2 files changed

+44
-26
lines changed

src/faker.ts

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -102,41 +102,38 @@ export class Faker {
102102
}
103103

104104
/**
105-
* Load the definitions contained in the locales file for the given types
105+
* Load the definitions contained in the locales file for the given types.
106+
*
107+
* Background: Certain localization sets contain less data then others.
108+
* In the case of a missing definition, use the localeFallback's values
109+
* to substitute the missing data.
106110
*/
107111
private loadDefinitions(): void {
108112
// TODO @Shinigami92 2022-01-11: Find a way to load this even more dynamically
109113
// In a way so that we don't accidentally miss a definition
110-
Object.entries(DEFINITIONS).forEach(([t, v]) => {
111-
if (this.definitions[t] == null) {
112-
this.definitions[t] = {};
114+
for (const [moduleName, entryNames] of Object.entries(DEFINITIONS)) {
115+
if (typeof entryNames === 'string') {
116+
// For 'title' and 'separator'
117+
Object.defineProperty(this.definitions, moduleName, {
118+
get: (): unknown /* string */ =>
119+
this.locales[this.locale][moduleName] ??
120+
this.locales[this.localeFallback][moduleName],
121+
});
122+
continue;
113123
}
114124

115-
if (typeof v === 'string') {
116-
this.definitions[t] = v;
117-
return;
125+
if (this.definitions[moduleName] == null) {
126+
this.definitions[moduleName] = {};
118127
}
119128

120-
v.forEach((p) => {
121-
Object.defineProperty(this.definitions[t], p, {
122-
get: () => {
123-
if (
124-
this.locales[this.locale][t] == null ||
125-
this.locales[this.locale][t][p] == null
126-
) {
127-
// certain localization sets contain less data then others.
128-
// in the case of a missing definition, use the default localeFallback
129-
// to substitute the missing set data
130-
// throw new Error('unknown property ' + d + p)
131-
return this.locales[this.localeFallback][t][p];
132-
} else {
133-
// return localized data
134-
return this.locales[this.locale][t][p];
135-
}
136-
},
129+
for (const entryName of entryNames) {
130+
Object.defineProperty(this.definitions[moduleName], entryName, {
131+
get: (): unknown =>
132+
this.locales[this.locale][moduleName]?.[entryName] ??
133+
this.locales[this.localeFallback][moduleName]?.[entryName],
137134
});
138-
});
139-
});
135+
}
136+
}
140137
}
141138

142139
seed(seed?: number | number[]): void {

test/faker.spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,27 @@ describe('faker', () => {
2828
);
2929
});
3030

31+
describe('title', () => {
32+
it.each(Object.keys(faker.locales))('title (%s)', (locale) => {
33+
faker.locale = locale;
34+
expect(faker.definitions.title).toBe(faker.locales[locale].title);
35+
});
36+
});
37+
38+
describe('separator', () => {
39+
it.each(Object.keys(faker.locales))('separator (%s)', (locale) => {
40+
faker.locale = locale;
41+
expect(faker.definitions.separator).toBeTypeOf('string');
42+
});
43+
44+
it('separator (with fallback)', () => {
45+
// Use a language that doesn't have a separator specified
46+
expect(faker.locales['en_US'].separator).toBeUndefined();
47+
// Check that the fallback works
48+
expect(faker.definitions.separator).toBe(faker.locales['en'].separator);
49+
});
50+
});
51+
3152
// This is only here for coverage
3253
// The actual test is in mersenne.spec.ts
3354
describe('seed()', () => {

0 commit comments

Comments
 (0)