aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorST-DDT <[email protected]>2023-01-13 21:30:46 +0100
committerGitHub <[email protected]>2023-01-13 21:30:46 +0100
commit788fce048f0233552df47f3407c06d8f83c32b0c (patch)
tree2d26f017fd1c9b3b7ac1acd272dd280c37bd482a
parent47b2cfc76b790647e398bf9883368a10b2ff5a68 (diff)
downloadfaker-788fce048f0233552df47f3407c06d8f83c32b0c.tar.xz
faker-788fce048f0233552df47f3407c06d8f83c32b0c.zip
feat(locales): add mergeLocales utility (#1707)
-rw-r--r--src/utils/merge-locales.ts37
-rw-r--r--test/utils/merge-locales.spec.ts59
2 files changed, 96 insertions, 0 deletions
diff --git a/src/utils/merge-locales.ts b/src/utils/merge-locales.ts
new file mode 100644
index 00000000..f5149306
--- /dev/null
+++ b/src/utils/merge-locales.ts
@@ -0,0 +1,37 @@
+import type { LocaleDefinition } from '..';
+
+/**
+ * Merges the given locales into one locale.
+ * The locales are merged in the order they are given.
+ * The first locale that provides an entry for a category will be used for that.
+ * Mutating the category entries in the returned locale will also mutate the entries in the respective source locale.
+ *
+ * @param locales The locales to merge.
+ * @returns The newly merged locale.
+ *
+ * @example
+ * const de_CH_with_fallbacks = mergeLocales([ de_CH, de, en ]);
+ */
+export function mergeLocales(locales: LocaleDefinition[]): LocaleDefinition {
+ const merged: LocaleDefinition = {} as LocaleDefinition;
+
+ for (const locale of locales) {
+ for (const key in locale) {
+ if (merged[key] === undefined) {
+ if (typeof locale[key] === 'object') {
+ merged[key] = { ...locale[key] };
+ } else {
+ merged[key] = locale[key];
+ }
+ } else {
+ if (typeof locale[key] === 'object') {
+ merged[key] = { ...locale[key], ...merged[key] };
+ } else {
+ // Primitive values cannot be merged
+ }
+ }
+ }
+ }
+
+ return merged;
+}
diff --git a/test/utils/merge-locales.spec.ts b/test/utils/merge-locales.spec.ts
new file mode 100644
index 00000000..0dcd3ab8
--- /dev/null
+++ b/test/utils/merge-locales.spec.ts
@@ -0,0 +1,59 @@
+import { describe, expect, it } from 'vitest';
+import type { LocaleDefinition } from '../../src';
+import { mergeLocales } from '../../src/utils/merge-locales';
+
+describe('mergeLocales', () => {
+ it('should not overwrite entries', () => {
+ const locale1: LocaleDefinition = {
+ title: 'a',
+ person: { firstName: ['a'] },
+ finance: { credit_card: { visa: ['a'] } },
+ };
+ const locale2: LocaleDefinition = {
+ title: 'b',
+ person: { firstName: ['b'] },
+ finance: { credit_card: { mastercard: ['b'] } },
+ };
+ const locale3: LocaleDefinition = {
+ title: 'c',
+ person: { firstName: ['c'] },
+ finance: { credit_card: {} },
+ };
+
+ const merged = mergeLocales([locale1, locale2, locale3]);
+
+ expect(merged).toEqual({
+ title: 'a',
+ person: { firstName: ['a'] },
+ finance: { credit_card: { visa: ['a'] } },
+ });
+ });
+
+ it('should extend categories', () => {
+ const locale1: LocaleDefinition = {
+ title: 'a',
+ location: { city: ['a'] },
+ person: { first_name: ['a'] },
+ };
+ const locale2: LocaleDefinition = {
+ title: 'b',
+ animal: { cat: ['b'] },
+ person: { last_name: ['b'] },
+ };
+ const locale3: LocaleDefinition = {
+ title: 'c',
+ color: { human: ['c'] },
+ person: {},
+ };
+
+ const merged = mergeLocales([locale1, locale2, locale3]);
+
+ expect(merged).toEqual({
+ title: 'a',
+ animal: { cat: ['b'] },
+ color: { human: ['c'] },
+ location: { city: ['a'] },
+ person: { first_name: ['a'], last_name: ['b'] },
+ });
+ });
+});