@prosopo/locale 3.2.8 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build$colon$cjs.log +10 -9
- package/.turbo/turbo-build$colon$tsc.log +5 -5
- package/.turbo/turbo-build.log +11 -10
- package/CHANGELOG.md +36 -0
- package/dist/cjs/i18SharedOptions.cjs +1 -1
- package/dist/cjs/i18nBackend.cjs +4 -1
- package/dist/cjs/i18nFrontend.cjs +4 -1
- package/dist/cjs/loadI18next.cjs +41 -14
- package/dist/cjs/locales/en/translation.cjs +1 -0
- package/dist/cjs/process.cjs +17 -0
- package/dist/cjs/translationKey.cjs +2 -0
- package/dist/i18SharedOptions.js +2 -1
- package/dist/i18SharedOptions.js.map +1 -1
- package/dist/i18nBackend.d.ts.map +1 -1
- package/dist/i18nBackend.js +4 -1
- package/dist/i18nBackend.js.map +1 -1
- package/dist/i18nFrontend.d.ts.map +1 -1
- package/dist/i18nFrontend.js +4 -1
- package/dist/i18nFrontend.js.map +1 -1
- package/dist/loadI18next.d.ts +1 -0
- package/dist/loadI18next.d.ts.map +1 -1
- package/dist/loadI18next.js +41 -15
- package/dist/loadI18next.js.map +1 -1
- package/dist/locales/ar/translation.json +1 -0
- package/dist/locales/az/translation.json +1 -0
- package/dist/locales/cs/translation.json +1 -0
- package/dist/locales/de/translation.json +1 -0
- package/dist/locales/el/translation.json +1 -0
- package/dist/locales/en/translation.js +1 -0
- package/dist/locales/en/translation.json +1 -0
- package/dist/locales/es/translation.json +1 -0
- package/dist/locales/fi/translation.json +1 -0
- package/dist/locales/fr/translation.json +1 -0
- package/dist/locales/hi/translation.json +1 -0
- package/dist/locales/hu/translation.json +1 -0
- package/dist/locales/id/translation.json +1 -0
- package/dist/locales/it/translation.json +1 -0
- package/dist/locales/ja/translation.json +1 -0
- package/dist/locales/jv/translation.json +1 -0
- package/dist/locales/ko/translation.json +1 -0
- package/dist/locales/ml/translation.json +1 -0
- package/dist/locales/ms/translation.json +1 -0
- package/dist/locales/nl/translation.json +1 -0
- package/dist/locales/no/translation.json +1 -0
- package/dist/locales/pl/translation.json +1 -0
- package/dist/locales/pt/translation.json +1 -0
- package/dist/locales/pt-BR/translation.json +1 -0
- package/dist/locales/ro/translation.json +1 -0
- package/dist/locales/ru/translation.json +1 -0
- package/dist/locales/sr/translation.json +1 -0
- package/dist/locales/sv/translation.json +1 -0
- package/dist/locales/th/translation.json +1 -0
- package/dist/locales/tr/translation.json +1 -0
- package/dist/locales/uk/translation.json +1 -0
- package/dist/locales/vi/translation.json +1 -0
- package/dist/locales/zh-CN/translation.json +1 -0
- package/dist/process.d.ts +2 -0
- package/dist/process.d.ts.map +1 -0
- package/dist/process.js +17 -0
- package/dist/process.js.map +1 -0
- package/dist/tests/i18SharedOptions.unit.test.d.ts +2 -0
- package/dist/tests/i18SharedOptions.unit.test.d.ts.map +1 -0
- package/dist/tests/i18SharedOptions.unit.test.js +91 -0
- package/dist/tests/i18SharedOptions.unit.test.js.map +1 -0
- package/dist/tests/i18nBackend.unit.test.d.ts +2 -0
- package/dist/tests/i18nBackend.unit.test.d.ts.map +1 -0
- package/dist/tests/i18nBackend.unit.test.js +153 -0
- package/dist/tests/i18nBackend.unit.test.js.map +1 -0
- package/dist/tests/i18nFrontend.unit.test.d.ts +2 -0
- package/dist/tests/i18nFrontend.unit.test.d.ts.map +1 -0
- package/dist/tests/i18nFrontend.unit.test.js +199 -0
- package/dist/tests/i18nFrontend.unit.test.js.map +1 -0
- package/dist/tests/i18nMiddleware.unit.test.d.ts +2 -0
- package/dist/tests/i18nMiddleware.unit.test.d.ts.map +1 -0
- package/dist/tests/i18nMiddleware.unit.test.js +80 -0
- package/dist/tests/i18nMiddleware.unit.test.js.map +1 -0
- package/dist/tests/loadI18next.unit.test.d.ts +2 -0
- package/dist/tests/loadI18next.unit.test.d.ts.map +1 -0
- package/dist/tests/loadI18next.unit.test.js +270 -0
- package/dist/tests/loadI18next.unit.test.js.map +1 -0
- package/dist/tests/locale.test-d.d.ts +2 -0
- package/dist/tests/locale.test-d.d.ts.map +1 -0
- package/dist/tests/locale.test-d.js +88 -0
- package/dist/tests/locale.test-d.js.map +1 -0
- package/dist/tests/process.unit.test.d.ts +2 -0
- package/dist/tests/process.unit.test.d.ts.map +1 -0
- package/dist/tests/process.unit.test.js +14 -0
- package/dist/tests/process.unit.test.js.map +1 -0
- package/dist/tests/translationKey.unit.test.d.ts +2 -0
- package/dist/tests/translationKey.unit.test.d.ts.map +1 -0
- package/dist/tests/translationKey.unit.test.js +108 -0
- package/dist/tests/translationKey.unit.test.js.map +1 -0
- package/dist/tests/translations.unit.test.d.ts +2 -0
- package/dist/tests/translations.unit.test.d.ts.map +1 -0
- package/dist/tests/translations.unit.test.js +74 -0
- package/dist/tests/translations.unit.test.js.map +1 -0
- package/dist/tests/useTranslation.unit.test.d.ts +2 -0
- package/dist/tests/useTranslation.unit.test.d.ts.map +1 -0
- package/dist/tests/useTranslation.unit.test.js +81 -0
- package/dist/tests/useTranslation.unit.test.js.map +1 -0
- package/dist/tests/util.unit.test.d.ts +2 -0
- package/dist/tests/util.unit.test.d.ts.map +1 -0
- package/dist/tests/util.unit.test.js +66 -0
- package/dist/tests/util.unit.test.js.map +1 -0
- package/dist/translationKey.d.ts +4 -0
- package/dist/translationKey.d.ts.map +1 -1
- package/dist/translationKey.js +2 -1
- package/dist/translationKey.js.map +1 -1
- package/package.json +2 -2
- package/src/i18SharedOptions.ts +4 -4
- package/src/i18nBackend.ts +16 -0
- package/src/i18nFrontend.ts +16 -0
- package/src/loadI18next.ts +83 -15
- package/src/locales/ar/translation.json +1 -0
- package/src/locales/az/translation.json +1 -0
- package/src/locales/cs/translation.json +1 -0
- package/src/locales/de/translation.json +1 -0
- package/src/locales/el/translation.json +1 -0
- package/src/locales/en/translation.json +1 -0
- package/src/locales/es/translation.json +1 -0
- package/src/locales/fi/translation.json +1 -0
- package/src/locales/fr/translation.json +1 -0
- package/src/locales/hi/translation.json +1 -0
- package/src/locales/hu/translation.json +1 -0
- package/src/locales/id/translation.json +1 -0
- package/src/locales/it/translation.json +1 -0
- package/src/locales/ja/translation.json +1 -0
- package/src/locales/jv/translation.json +1 -0
- package/src/locales/ko/translation.json +1 -0
- package/src/locales/ml/translation.json +1 -0
- package/src/locales/ms/translation.json +1 -0
- package/src/locales/nl/translation.json +1 -0
- package/src/locales/no/translation.json +1 -0
- package/src/locales/pl/translation.json +1 -0
- package/src/locales/pt/translation.json +1 -0
- package/src/locales/pt-BR/translation.json +1 -0
- package/src/locales/ro/translation.json +1 -0
- package/src/locales/ru/translation.json +1 -0
- package/src/locales/sr/translation.json +1 -0
- package/src/locales/sv/translation.json +1 -0
- package/src/locales/th/translation.json +1 -0
- package/src/locales/tr/translation.json +1 -0
- package/src/locales/uk/translation.json +1 -0
- package/src/locales/vi/translation.json +1 -0
- package/src/locales/zh-CN/translation.json +1 -0
- package/src/process.ts +29 -0
- package/src/tests/i18SharedOptions.unit.test.ts +139 -0
- package/src/tests/i18nBackend.unit.test.ts +241 -0
- package/src/tests/i18nFrontend.unit.test.ts +302 -0
- package/src/tests/i18nMiddleware.unit.test.ts +140 -0
- package/src/tests/loadI18next.unit.test.ts +443 -0
- package/src/tests/locale.test-d.ts +156 -0
- package/src/tests/process.unit.test.ts +33 -0
- package/src/tests/translationKey.unit.test.ts +166 -0
- package/src/tests/translations.unit.test.ts +110 -0
- package/src/tests/useTranslation.unit.test.ts +134 -0
- package/src/tests/util.unit.test.ts +102 -0
- package/src/translationKey.ts +18 -3
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { afterEach, describe, expect, test, vi } from "vitest";
|
|
2
|
+
const load = async (isInitialized = false) => {
|
|
3
|
+
vi.resetModules();
|
|
4
|
+
const plugins = [];
|
|
5
|
+
const initOptions = [];
|
|
6
|
+
const resourceLoaders = [];
|
|
7
|
+
const detectorOptions = [];
|
|
8
|
+
const listeners = new Map();
|
|
9
|
+
const fake = {
|
|
10
|
+
isInitialized,
|
|
11
|
+
use: (plugin) => {
|
|
12
|
+
plugins.push(plugin);
|
|
13
|
+
return fake;
|
|
14
|
+
},
|
|
15
|
+
init: (options) => {
|
|
16
|
+
initOptions.push(options);
|
|
17
|
+
return fake;
|
|
18
|
+
},
|
|
19
|
+
on: (event, listener) => {
|
|
20
|
+
listeners.set(event, [...(listeners.get(event) ?? []), listener]);
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
const harness = {
|
|
24
|
+
fake,
|
|
25
|
+
plugins,
|
|
26
|
+
initOptions,
|
|
27
|
+
resourceLoaders,
|
|
28
|
+
detectorOptions,
|
|
29
|
+
emit: (event) => {
|
|
30
|
+
for (const listener of listeners.get(event) ?? []) {
|
|
31
|
+
listener();
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
vi.doMock("i18next", () => ({ default: fake }));
|
|
36
|
+
vi.doMock("i18next-chained-backend", () => ({ default: "ChainedBackend" }));
|
|
37
|
+
vi.doMock("i18next-http-backend", () => ({ default: "HttpBackend" }));
|
|
38
|
+
vi.doMock("i18next-browser-languagedetector", () => ({
|
|
39
|
+
default: class {
|
|
40
|
+
constructor(_services, opts) {
|
|
41
|
+
detectorOptions.push(opts);
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
}));
|
|
45
|
+
vi.doMock("i18next-resources-to-backend", () => ({
|
|
46
|
+
default: (loader) => {
|
|
47
|
+
resourceLoaders.push(loader);
|
|
48
|
+
return "InMemoryBackend";
|
|
49
|
+
},
|
|
50
|
+
}));
|
|
51
|
+
vi.doMock("react-i18next", () => ({ initReactI18next: "initReactI18next" }));
|
|
52
|
+
const imported = await import("../i18nFrontend.js");
|
|
53
|
+
return { initializeI18n: imported.default, harness };
|
|
54
|
+
};
|
|
55
|
+
const backendOf = (options) => (options?.backend ?? {});
|
|
56
|
+
afterEach(() => {
|
|
57
|
+
vi.resetModules();
|
|
58
|
+
for (const module of [
|
|
59
|
+
"i18next",
|
|
60
|
+
"i18next-chained-backend",
|
|
61
|
+
"i18next-http-backend",
|
|
62
|
+
"i18next-browser-languagedetector",
|
|
63
|
+
"i18next-resources-to-backend",
|
|
64
|
+
"react-i18next",
|
|
65
|
+
]) {
|
|
66
|
+
vi.doUnmock(module);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
describe("i18nFrontend, first initialisation", () => {
|
|
70
|
+
test("initialises i18next exactly once", async () => {
|
|
71
|
+
const { initializeI18n, harness } = await load();
|
|
72
|
+
initializeI18n();
|
|
73
|
+
expect(harness.initOptions).toHaveLength(1);
|
|
74
|
+
});
|
|
75
|
+
test("registers the chained backend, the detector and the react binding", async () => {
|
|
76
|
+
const { initializeI18n, harness } = await load();
|
|
77
|
+
initializeI18n();
|
|
78
|
+
expect(harness.plugins).toHaveLength(3);
|
|
79
|
+
expect(harness.plugins[0]).toBe("ChainedBackend");
|
|
80
|
+
expect(harness.plugins[2]).toBe("initReactI18next");
|
|
81
|
+
});
|
|
82
|
+
test("carries the shared options through to init", async () => {
|
|
83
|
+
const { initializeI18n, harness } = await load();
|
|
84
|
+
initializeI18n();
|
|
85
|
+
const options = harness.initOptions[0];
|
|
86
|
+
expect(options?.fallbackLng).toBe("en");
|
|
87
|
+
expect(options?.nonExplicitSupportedLngs).toBe(false);
|
|
88
|
+
expect(options?.supportedLngs).toContain("en");
|
|
89
|
+
});
|
|
90
|
+
test("returns the i18next instance", async () => {
|
|
91
|
+
const { initializeI18n, harness } = await load();
|
|
92
|
+
expect(initializeI18n()).toBe(harness.fake);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
describe("i18nFrontend language selection", () => {
|
|
96
|
+
test("pins lng when the site owner supplied one", async () => {
|
|
97
|
+
const { initializeI18n, harness } = await load();
|
|
98
|
+
initializeI18n(undefined, "fr");
|
|
99
|
+
expect(harness.initOptions[0]?.lng).toBe("fr");
|
|
100
|
+
});
|
|
101
|
+
test("omits lng entirely when none was supplied, leaving detection on", async () => {
|
|
102
|
+
const { initializeI18n, harness } = await load();
|
|
103
|
+
initializeI18n();
|
|
104
|
+
expect(harness.initOptions[0]).not.toHaveProperty("lng");
|
|
105
|
+
});
|
|
106
|
+
test("treats the empty string as no language rather than pinning it", async () => {
|
|
107
|
+
const { initializeI18n, harness } = await load();
|
|
108
|
+
initializeI18n(undefined, "");
|
|
109
|
+
expect(harness.initOptions[0]).not.toHaveProperty("lng");
|
|
110
|
+
});
|
|
111
|
+
test("configures the detector to prefer a stored choice over the browser", async () => {
|
|
112
|
+
const { initializeI18n, harness } = await load();
|
|
113
|
+
initializeI18n();
|
|
114
|
+
expect(harness.detectorOptions[0]).toMatchObject({
|
|
115
|
+
order: ["cookie", "localStorage", "navigator"],
|
|
116
|
+
lookupQuerystring: "lng",
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
test("persists the detected language to localStorage and a cookie", async () => {
|
|
120
|
+
const { initializeI18n, harness } = await load();
|
|
121
|
+
initializeI18n();
|
|
122
|
+
expect(harness.detectorOptions[0]).toMatchObject({
|
|
123
|
+
caches: ["localStorage", "cookie"],
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
describe("i18nFrontend resource loading", () => {
|
|
128
|
+
test("chains an in-memory fallback behind the http backend", async () => {
|
|
129
|
+
const { initializeI18n, harness } = await load();
|
|
130
|
+
initializeI18n();
|
|
131
|
+
const backend = backendOf(harness.initOptions[0]);
|
|
132
|
+
expect(backend.backends).toEqual(["HttpBackend", "InMemoryBackend"]);
|
|
133
|
+
});
|
|
134
|
+
test("gives the http backend a templated load path", async () => {
|
|
135
|
+
const { initializeI18n, harness } = await load();
|
|
136
|
+
initializeI18n();
|
|
137
|
+
const backend = backendOf(harness.initOptions[0]);
|
|
138
|
+
const loadPath = backend.backendOptions?.[0]?.loadPath;
|
|
139
|
+
expect(loadPath).toContain("/locales/{{lng}}/{{ns}}.json");
|
|
140
|
+
});
|
|
141
|
+
test("derives the load path from the module URL, not the page URL", async () => {
|
|
142
|
+
const { initializeI18n, harness } = await load();
|
|
143
|
+
initializeI18n();
|
|
144
|
+
const loadPath = backendOf(harness.initOptions[0]).backendOptions?.[0]
|
|
145
|
+
?.loadPath;
|
|
146
|
+
expect(loadPath).toMatch(/^[a-z]+:\/\//);
|
|
147
|
+
expect(loadPath).not.toContain("i18nFrontend");
|
|
148
|
+
});
|
|
149
|
+
test("hands resourcesToBackend a loader that resolves a language and namespace", async () => {
|
|
150
|
+
const { initializeI18n, harness } = await load();
|
|
151
|
+
initializeI18n();
|
|
152
|
+
const loader = harness.resourceLoaders[0];
|
|
153
|
+
expect(loader).toBeTypeOf("function");
|
|
154
|
+
await expect(Promise.resolve(loader?.("en", "translation")).catch(() => undefined)).resolves.not.toThrow();
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
describe("i18nFrontend callback", () => {
|
|
158
|
+
test("defers the callback until resources have loaded", async () => {
|
|
159
|
+
const callback = vi.fn();
|
|
160
|
+
const { initializeI18n, harness } = await load();
|
|
161
|
+
initializeI18n(callback);
|
|
162
|
+
expect(callback).not.toHaveBeenCalled();
|
|
163
|
+
harness.emit("loaded");
|
|
164
|
+
expect(callback).toHaveBeenCalledWith(harness.fake);
|
|
165
|
+
});
|
|
166
|
+
test("fires the callback once, however often `loaded` is emitted", async () => {
|
|
167
|
+
const callback = vi.fn();
|
|
168
|
+
const { initializeI18n, harness } = await load();
|
|
169
|
+
initializeI18n(callback);
|
|
170
|
+
harness.emit("loaded");
|
|
171
|
+
harness.emit("loaded");
|
|
172
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
173
|
+
});
|
|
174
|
+
test("tolerates being called with no callback", async () => {
|
|
175
|
+
const { initializeI18n, harness } = await load();
|
|
176
|
+
initializeI18n();
|
|
177
|
+
expect(() => harness.emit("loaded")).not.toThrow();
|
|
178
|
+
});
|
|
179
|
+
test("fires the callback immediately when i18next is already initialised", async () => {
|
|
180
|
+
const callback = vi.fn();
|
|
181
|
+
const { initializeI18n, harness } = await load(true);
|
|
182
|
+
const returned = initializeI18n(callback);
|
|
183
|
+
expect(harness.initOptions).toHaveLength(0);
|
|
184
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
185
|
+
expect(callback).toHaveBeenCalledWith(harness.fake);
|
|
186
|
+
expect(returned).toBe(harness.fake);
|
|
187
|
+
});
|
|
188
|
+
test("registers no plugins when already initialised", async () => {
|
|
189
|
+
const { initializeI18n, harness } = await load(true);
|
|
190
|
+
initializeI18n();
|
|
191
|
+
expect(harness.plugins).toHaveLength(0);
|
|
192
|
+
});
|
|
193
|
+
test("ignores lng when already initialised — the caller reconciles instead", async () => {
|
|
194
|
+
const { initializeI18n, harness } = await load(true);
|
|
195
|
+
initializeI18n(undefined, "fr");
|
|
196
|
+
expect(harness.initOptions).toHaveLength(0);
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
//# sourceMappingURL=i18nFrontend.unit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18nFrontend.unit.test.js","sourceRoot":"","sources":["../../src/tests/i18nFrontend.unit.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18nMiddleware.unit.test.d.ts","sourceRoot":"","sources":["../../src/tests/i18nMiddleware.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { afterEach, describe, expect, test, vi } from "vitest";
|
|
2
|
+
const asI18n = (value) => value;
|
|
3
|
+
const load = async (options) => {
|
|
4
|
+
vi.resetModules();
|
|
5
|
+
const instance = asI18n({ name: "the singleton" });
|
|
6
|
+
const handleCalls = [];
|
|
7
|
+
const handler = (() => { });
|
|
8
|
+
vi.doMock("i18next-http-middleware", () => ({
|
|
9
|
+
handle: (i18next, opts) => {
|
|
10
|
+
handleCalls.push([i18next, opts]);
|
|
11
|
+
return handler;
|
|
12
|
+
},
|
|
13
|
+
}));
|
|
14
|
+
vi.doMock("../loadI18next.js", () => ({
|
|
15
|
+
default: async () => {
|
|
16
|
+
if (options.loadRejects) {
|
|
17
|
+
throw new Error("i18n failed to load");
|
|
18
|
+
}
|
|
19
|
+
return instance;
|
|
20
|
+
},
|
|
21
|
+
}));
|
|
22
|
+
const imported = await import("../i18nMiddleware.js");
|
|
23
|
+
return {
|
|
24
|
+
i18nMiddleware: imported.default,
|
|
25
|
+
harness: { instance, handleCalls, handler },
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
vi.resetModules();
|
|
30
|
+
vi.doUnmock("i18next-http-middleware");
|
|
31
|
+
vi.doUnmock("../loadI18next.js");
|
|
32
|
+
});
|
|
33
|
+
describe("i18nMiddleware", () => {
|
|
34
|
+
test("builds the handler from the loaded i18next instance", async () => {
|
|
35
|
+
const { i18nMiddleware, harness } = await load({});
|
|
36
|
+
const handler = await i18nMiddleware({});
|
|
37
|
+
expect(harness.handleCalls).toHaveLength(1);
|
|
38
|
+
expect(harness.handleCalls[0]?.[0]).toBe(harness.instance);
|
|
39
|
+
expect(handler).toBe(harness.handler);
|
|
40
|
+
});
|
|
41
|
+
test("forwards the caller's options", async () => {
|
|
42
|
+
const { i18nMiddleware, harness } = await load({});
|
|
43
|
+
const options = { ignoreRoutes: ["/healthz"] };
|
|
44
|
+
await i18nMiddleware(options);
|
|
45
|
+
expect(harness.handleCalls[0]?.[1]).toEqual({ ignoreRoutes: ["/healthz"] });
|
|
46
|
+
});
|
|
47
|
+
test("copies the options rather than passing the caller's object through", async () => {
|
|
48
|
+
const { i18nMiddleware, harness } = await load({});
|
|
49
|
+
const options = { ignoreRoutes: ["/healthz"] };
|
|
50
|
+
await i18nMiddleware(options);
|
|
51
|
+
expect(harness.handleCalls[0]?.[1]).not.toBe(options);
|
|
52
|
+
});
|
|
53
|
+
test("accepts an empty options object", async () => {
|
|
54
|
+
const { i18nMiddleware, harness } = await load({});
|
|
55
|
+
await i18nMiddleware({});
|
|
56
|
+
expect(harness.handleCalls[0]?.[1]).toEqual({});
|
|
57
|
+
});
|
|
58
|
+
test("always requests the backend instance", async () => {
|
|
59
|
+
const loadSpy = vi.fn(async () => asI18n({}));
|
|
60
|
+
vi.resetModules();
|
|
61
|
+
vi.doMock("i18next-http-middleware", () => ({
|
|
62
|
+
handle: () => (() => { }),
|
|
63
|
+
}));
|
|
64
|
+
vi.doMock("../loadI18next.js", () => ({ default: loadSpy }));
|
|
65
|
+
const imported = await import("../i18nMiddleware.js");
|
|
66
|
+
await imported.default({});
|
|
67
|
+
expect(loadSpy).toHaveBeenCalledWith(true);
|
|
68
|
+
});
|
|
69
|
+
test("propagates a failure to load i18next instead of returning a broken handler", async () => {
|
|
70
|
+
const { i18nMiddleware } = await load({ loadRejects: true });
|
|
71
|
+
await expect(i18nMiddleware({})).rejects.toThrow("i18n failed to load");
|
|
72
|
+
});
|
|
73
|
+
test("returns a fresh handler per call", async () => {
|
|
74
|
+
const { i18nMiddleware, harness } = await load({});
|
|
75
|
+
await i18nMiddleware({});
|
|
76
|
+
await i18nMiddleware({ ignoreRoutes: ["/x"] });
|
|
77
|
+
expect(harness.handleCalls).toHaveLength(2);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
//# sourceMappingURL=i18nMiddleware.unit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18nMiddleware.unit.test.js","sourceRoot":"","sources":["../../src/tests/i18nMiddleware.unit.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadI18next.unit.test.d.ts","sourceRoot":"","sources":["../../src/tests/loadI18next.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { afterEach, describe, expect, test, vi } from "vitest";
|
|
2
|
+
const asI18n = (fake) => fake;
|
|
3
|
+
const install = (module, options = {}) => {
|
|
4
|
+
const instance = {
|
|
5
|
+
language: options.language ?? "en",
|
|
6
|
+
changeLanguage: options.changeLanguage ??
|
|
7
|
+
(async (lng) => {
|
|
8
|
+
instance.language = lng;
|
|
9
|
+
return undefined;
|
|
10
|
+
}),
|
|
11
|
+
};
|
|
12
|
+
const initialize = vi.fn((callback) => {
|
|
13
|
+
const fire = options.fire ?? "async";
|
|
14
|
+
if (fire === "sync") {
|
|
15
|
+
callback?.(asI18n(instance));
|
|
16
|
+
}
|
|
17
|
+
else if (fire === "async") {
|
|
18
|
+
queueMicrotask(() => callback?.(asI18n(instance)));
|
|
19
|
+
}
|
|
20
|
+
return asI18n(instance);
|
|
21
|
+
});
|
|
22
|
+
vi.doMock(module, () => ({ default: initialize }));
|
|
23
|
+
return { instance, initialize };
|
|
24
|
+
};
|
|
25
|
+
const loadModule = async () => {
|
|
26
|
+
const imported = await import("../loadI18next.js");
|
|
27
|
+
return imported.default;
|
|
28
|
+
};
|
|
29
|
+
afterEach(() => {
|
|
30
|
+
vi.useRealTimers();
|
|
31
|
+
vi.resetModules();
|
|
32
|
+
vi.doUnmock("../i18nBackend.js");
|
|
33
|
+
vi.doUnmock("../i18nFrontend.js");
|
|
34
|
+
vi.restoreAllMocks();
|
|
35
|
+
});
|
|
36
|
+
describe("loadI18next, backend", () => {
|
|
37
|
+
test("initialises once and resolves with the instance", async () => {
|
|
38
|
+
const { instance, initialize } = install("../i18nBackend.js");
|
|
39
|
+
const loadI18next = await loadModule();
|
|
40
|
+
const resolved = await loadI18next(true);
|
|
41
|
+
expect(initialize).toHaveBeenCalledTimes(1);
|
|
42
|
+
expect(resolved).toBe(asI18n(instance));
|
|
43
|
+
});
|
|
44
|
+
test("resolves from the callback, not from the return value", async () => {
|
|
45
|
+
const { initialize } = install("../i18nBackend.js", { fire: "never" });
|
|
46
|
+
const loadI18next = await loadModule();
|
|
47
|
+
let settled = false;
|
|
48
|
+
void loadI18next(true).then(() => {
|
|
49
|
+
settled = true;
|
|
50
|
+
});
|
|
51
|
+
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
52
|
+
expect(initialize).toHaveBeenCalledTimes(1);
|
|
53
|
+
expect(settled).toBe(false);
|
|
54
|
+
});
|
|
55
|
+
test("reuses the singleton on a second call without re-initialising", async () => {
|
|
56
|
+
const { instance, initialize } = install("../i18nBackend.js");
|
|
57
|
+
const loadI18next = await loadModule();
|
|
58
|
+
const first = await loadI18next(true);
|
|
59
|
+
const second = await loadI18next(true);
|
|
60
|
+
expect(initialize).toHaveBeenCalledTimes(1);
|
|
61
|
+
expect(second).toBe(first);
|
|
62
|
+
expect(second).toBe(asI18n(instance));
|
|
63
|
+
});
|
|
64
|
+
test("ignores lng on the backend path — the server detects per request", async () => {
|
|
65
|
+
const { instance, initialize } = install("../i18nBackend.js", {
|
|
66
|
+
language: "en",
|
|
67
|
+
});
|
|
68
|
+
const loadI18next = await loadModule();
|
|
69
|
+
await loadI18next(true, "fr");
|
|
70
|
+
expect(initialize.mock.calls[0]?.[1]).toBeUndefined();
|
|
71
|
+
expect(instance.language).toBe("en");
|
|
72
|
+
});
|
|
73
|
+
test("rejects, rather than hanging, when the module fails to load", async () => {
|
|
74
|
+
vi.doMock("../i18nBackend.js", () => {
|
|
75
|
+
throw new Error("backend module blew up");
|
|
76
|
+
});
|
|
77
|
+
const loadI18next = await loadModule();
|
|
78
|
+
await expect(loadI18next(true)).rejects.toThrow();
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
describe("loadI18next, frontend", () => {
|
|
82
|
+
test("initialises once and resolves with the instance", async () => {
|
|
83
|
+
const { instance, initialize } = install("../i18nFrontend.js");
|
|
84
|
+
const loadI18next = await loadModule();
|
|
85
|
+
const resolved = await loadI18next(false);
|
|
86
|
+
expect(initialize).toHaveBeenCalledTimes(1);
|
|
87
|
+
expect(resolved).toBe(asI18n(instance));
|
|
88
|
+
});
|
|
89
|
+
test("passes lng straight into init so browser detection is skipped", async () => {
|
|
90
|
+
const { initialize } = install("../i18nFrontend.js", { language: "fr" });
|
|
91
|
+
const loadI18next = await loadModule();
|
|
92
|
+
await loadI18next(false, "fr");
|
|
93
|
+
expect(initialize.mock.calls[0]?.[1]).toBe("fr");
|
|
94
|
+
});
|
|
95
|
+
test("does not call changeLanguage when init already produced the target", async () => {
|
|
96
|
+
const changeLanguage = vi.fn(async () => undefined);
|
|
97
|
+
install("../i18nFrontend.js", { language: "fr", changeLanguage });
|
|
98
|
+
const loadI18next = await loadModule();
|
|
99
|
+
await loadI18next(false, "fr");
|
|
100
|
+
expect(changeLanguage).not.toHaveBeenCalled();
|
|
101
|
+
});
|
|
102
|
+
test("does not call changeLanguage when no language was requested", async () => {
|
|
103
|
+
const changeLanguage = vi.fn(async () => undefined);
|
|
104
|
+
install("../i18nFrontend.js", { language: "de", changeLanguage });
|
|
105
|
+
const loadI18next = await loadModule();
|
|
106
|
+
await loadI18next(false);
|
|
107
|
+
expect(changeLanguage).not.toHaveBeenCalled();
|
|
108
|
+
});
|
|
109
|
+
test("reconciles when init settled on a different language", async () => {
|
|
110
|
+
const changeLanguage = vi.fn(async () => undefined);
|
|
111
|
+
install("../i18nFrontend.js", { language: "en", changeLanguage });
|
|
112
|
+
const loadI18next = await loadModule();
|
|
113
|
+
await loadI18next(false, "fr");
|
|
114
|
+
expect(changeLanguage).toHaveBeenCalledWith("fr");
|
|
115
|
+
});
|
|
116
|
+
test("reconciles a pre-existing singleton before resolving", async () => {
|
|
117
|
+
const { instance, initialize } = install("../i18nFrontend.js", {
|
|
118
|
+
language: "en",
|
|
119
|
+
});
|
|
120
|
+
const loadI18next = await loadModule();
|
|
121
|
+
await loadI18next(false);
|
|
122
|
+
const second = await loadI18next(false, "fr");
|
|
123
|
+
expect(initialize).toHaveBeenCalledTimes(1);
|
|
124
|
+
expect(instance.language).toBe("fr");
|
|
125
|
+
expect(second).toBe(asI18n(instance));
|
|
126
|
+
});
|
|
127
|
+
test("resolves the cached singleton unchanged when lng is omitted", async () => {
|
|
128
|
+
const changeLanguage = vi.fn(async () => undefined);
|
|
129
|
+
install("../i18nFrontend.js", { language: "de", changeLanguage });
|
|
130
|
+
const loadI18next = await loadModule();
|
|
131
|
+
await loadI18next(false);
|
|
132
|
+
await loadI18next(false);
|
|
133
|
+
expect(changeLanguage).not.toHaveBeenCalled();
|
|
134
|
+
});
|
|
135
|
+
test("rejects, rather than hanging, when the module fails to load", async () => {
|
|
136
|
+
vi.doMock("../i18nFrontend.js", () => {
|
|
137
|
+
throw new Error("frontend module blew up");
|
|
138
|
+
});
|
|
139
|
+
const loadI18next = await loadModule();
|
|
140
|
+
await expect(loadI18next(false)).rejects.toThrow();
|
|
141
|
+
});
|
|
142
|
+
test("rejects when changeLanguage fails during first-load reconciliation", async () => {
|
|
143
|
+
install("../i18nFrontend.js", {
|
|
144
|
+
language: "en",
|
|
145
|
+
changeLanguage: async () => {
|
|
146
|
+
throw new Error("resource fetch failed");
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
const loadI18next = await loadModule();
|
|
150
|
+
await expect(loadI18next(false, "fr")).rejects.toThrow("resource fetch failed");
|
|
151
|
+
});
|
|
152
|
+
test("rejects when changeLanguage fails while reconciling the singleton", async () => {
|
|
153
|
+
let failing = false;
|
|
154
|
+
install("../i18nFrontend.js", {
|
|
155
|
+
language: "en",
|
|
156
|
+
changeLanguage: async () => {
|
|
157
|
+
if (failing) {
|
|
158
|
+
throw new Error("resource fetch failed");
|
|
159
|
+
}
|
|
160
|
+
return undefined;
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
const loadI18next = await loadModule();
|
|
164
|
+
await loadI18next(false);
|
|
165
|
+
failing = true;
|
|
166
|
+
await expect(loadI18next(false, "fr")).rejects.toThrow("resource fetch failed");
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
describe("loadI18next, timeout", () => {
|
|
170
|
+
test("resolves with the degraded instance when `loaded` never fires", async () => {
|
|
171
|
+
vi.useFakeTimers();
|
|
172
|
+
const { instance } = install("../i18nBackend.js", { fire: "never" });
|
|
173
|
+
const loadI18next = await loadModule();
|
|
174
|
+
const { I18N_LOAD_TIMEOUT_MS } = await import("../loadI18next.js");
|
|
175
|
+
const pending = loadI18next(true);
|
|
176
|
+
await vi.advanceTimersByTimeAsync(I18N_LOAD_TIMEOUT_MS);
|
|
177
|
+
await expect(pending).resolves.toBe(asI18n(instance));
|
|
178
|
+
});
|
|
179
|
+
test("does not fire early — the instance is not handed back before the deadline", async () => {
|
|
180
|
+
vi.useFakeTimers();
|
|
181
|
+
install("../i18nBackend.js", { fire: "never" });
|
|
182
|
+
const loadI18next = await loadModule();
|
|
183
|
+
const { I18N_LOAD_TIMEOUT_MS } = await import("../loadI18next.js");
|
|
184
|
+
let settled = false;
|
|
185
|
+
void loadI18next(true).then(() => {
|
|
186
|
+
settled = true;
|
|
187
|
+
});
|
|
188
|
+
await vi.advanceTimersByTimeAsync(I18N_LOAD_TIMEOUT_MS - 1);
|
|
189
|
+
expect(settled).toBe(false);
|
|
190
|
+
});
|
|
191
|
+
test("rejects on timeout when no instance was ever created", async () => {
|
|
192
|
+
vi.useFakeTimers();
|
|
193
|
+
vi.doMock("../i18nBackend.js", () => new Promise(() => undefined));
|
|
194
|
+
const loadI18next = await loadModule();
|
|
195
|
+
const { I18N_LOAD_TIMEOUT_MS } = await import("../loadI18next.js");
|
|
196
|
+
const assertion = expect(loadI18next(true)).rejects.toThrow(/did not load within/);
|
|
197
|
+
await vi.advanceTimersByTimeAsync(I18N_LOAD_TIMEOUT_MS);
|
|
198
|
+
await assertion;
|
|
199
|
+
});
|
|
200
|
+
test("a normal load clears the timer, so a late event cannot re-settle it", async () => {
|
|
201
|
+
vi.useFakeTimers();
|
|
202
|
+
let fire;
|
|
203
|
+
const instance = {
|
|
204
|
+
language: "en",
|
|
205
|
+
changeLanguage: async () => undefined,
|
|
206
|
+
};
|
|
207
|
+
const initialize = vi.fn((callback) => {
|
|
208
|
+
fire = callback;
|
|
209
|
+
return asI18n(instance);
|
|
210
|
+
});
|
|
211
|
+
vi.doMock("../i18nBackend.js", () => ({ default: initialize }));
|
|
212
|
+
const loadI18next = await loadModule();
|
|
213
|
+
const { I18N_LOAD_TIMEOUT_MS } = await import("../loadI18next.js");
|
|
214
|
+
const pending = loadI18next(true);
|
|
215
|
+
await vi.advanceTimersByTimeAsync(0);
|
|
216
|
+
fire?.(asI18n(instance));
|
|
217
|
+
await expect(pending).resolves.toBe(asI18n(instance));
|
|
218
|
+
fire?.(asI18n(instance));
|
|
219
|
+
await vi.advanceTimersByTimeAsync(I18N_LOAD_TIMEOUT_MS * 2);
|
|
220
|
+
await expect(pending).resolves.toBe(asI18n(instance));
|
|
221
|
+
});
|
|
222
|
+
test("a failure arriving after the timeout cannot turn a resolved promise into a rejection", async () => {
|
|
223
|
+
vi.useFakeTimers();
|
|
224
|
+
let fire;
|
|
225
|
+
const instance = {
|
|
226
|
+
language: "en",
|
|
227
|
+
changeLanguage: async () => {
|
|
228
|
+
throw new Error("resource fetch failed");
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
const initialize = vi.fn((callback) => {
|
|
232
|
+
fire = callback;
|
|
233
|
+
return asI18n(instance);
|
|
234
|
+
});
|
|
235
|
+
vi.doMock("../i18nFrontend.js", () => ({ default: initialize }));
|
|
236
|
+
const loadI18next = await loadModule();
|
|
237
|
+
const { I18N_LOAD_TIMEOUT_MS } = await import("../loadI18next.js");
|
|
238
|
+
const pending = loadI18next(false, "fr");
|
|
239
|
+
await vi.advanceTimersByTimeAsync(I18N_LOAD_TIMEOUT_MS);
|
|
240
|
+
await expect(pending).resolves.toBe(asI18n(instance));
|
|
241
|
+
fire?.(asI18n(instance));
|
|
242
|
+
await vi.advanceTimersByTimeAsync(0);
|
|
243
|
+
await expect(pending).resolves.toBe(asI18n(instance));
|
|
244
|
+
});
|
|
245
|
+
test("the deadline is long enough not to trip a healthy cold start", async () => {
|
|
246
|
+
const { I18N_LOAD_TIMEOUT_MS } = await import("../loadI18next.js");
|
|
247
|
+
expect(I18N_LOAD_TIMEOUT_MS).toBeGreaterThanOrEqual(5_000);
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
describe("loadI18next, singleton shared across both paths", () => {
|
|
251
|
+
test("a frontend call after a backend call reuses the backend instance", async () => {
|
|
252
|
+
const backend = install("../i18nBackend.js", { language: "en" });
|
|
253
|
+
const frontend = install("../i18nFrontend.js", { language: "de" });
|
|
254
|
+
const loadI18next = await loadModule();
|
|
255
|
+
const first = await loadI18next(true);
|
|
256
|
+
const second = await loadI18next(false);
|
|
257
|
+
expect(backend.initialize).toHaveBeenCalledTimes(1);
|
|
258
|
+
expect(frontend.initialize).not.toHaveBeenCalled();
|
|
259
|
+
expect(second).toBe(first);
|
|
260
|
+
});
|
|
261
|
+
test("the later caller's language still wins via reconciliation", async () => {
|
|
262
|
+
const backend = install("../i18nBackend.js", { language: "en" });
|
|
263
|
+
install("../i18nFrontend.js");
|
|
264
|
+
const loadI18next = await loadModule();
|
|
265
|
+
await loadI18next(true);
|
|
266
|
+
await loadI18next(false, "fr");
|
|
267
|
+
expect(backend.instance.language).toBe("fr");
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
//# sourceMappingURL=loadI18next.unit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadI18next.unit.test.js","sourceRoot":"","sources":["../../src/tests/loadI18next.unit.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locale.test-d.d.ts","sourceRoot":"","sources":["../../src/tests/locale.test-d.ts"],"names":[],"mappings":""}
|