Skip to content

Commit e46b4e3

Browse files
authored
fallback to existing DEFAULT_LOCALE translation in globalisation
1 parent ff8b555 commit e46b4e3

File tree

6 files changed

+61
-25
lines changed

6 files changed

+61
-25
lines changed

bootstrap/src/component/Globalisation.jsx

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/* global DEFAULT_LOCALE */
2+
13
import { useMemo, Fragment } from "react";
24
import { createIntl, createIntlCache, RawIntlProvider } from "react-intl";
35
import { useSelector } from "react-redux";
@@ -15,6 +17,7 @@ const Globalisation = (props) => {
1517
createIntl(
1618
{
1719
locale,
20+
defaultLocale: DEFAULT_LOCALE,
1821
textComponent: Fragment,
1922
messages,
2023
onError: (err) => {

bootstrap/src/component/Main.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const Main = (props) => {
3131
store.dispatch({
3232
type: constants.SET_LANGUAGE,
3333
payload: {
34-
language: props.defaultLocale ?? DEFAULT_LOCALE,
34+
language: DEFAULT_LOCALE,
3535
},
3636
});
3737
store.dispatch({

bootstrap/src/component/__tests__/Main.test.jsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/* global DEFAULT_LOCALE */
2+
13
import { render, screen, waitFor, act } from "@testing-library/react";
24
import React from "react";
35
import configureStore from "redux-mock-store";
@@ -73,6 +75,7 @@ class ErrorBoundary extends React.Component {
7375

7476
describe("<Main />", () => {
7577
beforeEach(() => {
78+
global.DEFAULT_LOCALE = "en-US";
7679
mockStore.clearActions();
7780
});
7881

@@ -94,8 +97,9 @@ describe("<Main />", () => {
9497
});
9598

9699
it("should use provided default locale", async () => {
100+
global.DEFAULT_LOCALE = "fr-FR";
97101
const fetchContext = jest.fn();
98-
render(<Main contextRefreshInterval={10} defaultLocale="fr-FR" fetchContext={fetchContext} />);
102+
render(<Main contextRefreshInterval={10} fetchContext={fetchContext} />);
99103
await waitFor(() => {
100104
expect(screen.getByTestId("module/some-entrypoint")).toBeInTheDocument();
101105
});

bootstrap/src/selector/__test__/index.test.js

+28-11
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
import * as selectors from "..";
22

33
describe("selector", () => {
4-
const state = {
5-
runtime: {
6-
entrypoint: "value",
7-
},
8-
env: {
9-
language: "en-US",
10-
messages: {
11-
"en-US": {
12-
foo: "bar",
4+
let state = null;
5+
6+
beforeEach(() => {
7+
global.DEFAULT_LOCALE = "en-US";
8+
state = {
9+
runtime: {
10+
entrypoint: "value",
11+
},
12+
env: {
13+
language: "en-US",
14+
messages: {
15+
"en-US": {
16+
foo: "bar",
17+
},
1318
},
1419
},
15-
},
16-
};
20+
};
21+
});
1722

1823
describe(".getEntrypoint", () => {
1924
it("should return entrypoint", () => {
@@ -33,5 +38,17 @@ describe("selector", () => {
3338
expect(messages.foo).toEqual(state.env.messages["en-US"].foo);
3439
expect(messages.miss).not.toBeDefined();
3540
});
41+
42+
it("should fallback on DEFAULT_LOCALE when it is missing in current locale", () => {
43+
state.env.language = "fr-FR";
44+
const messages = selectors.getI18nMessages(state);
45+
expect(messages.foo).toEqual(state.env.messages["en-US"].foo);
46+
});
47+
48+
it("should work properly when no messages exist at all", () => {
49+
delete state.env.messages;
50+
const messages = selectors.getI18nMessages(state);
51+
expect(messages.foo).not.toBeDefined();
52+
});
3653
});
3754
});

bootstrap/src/selector/index.js

+23-11
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,41 @@
1+
/* global DEFAULT_LOCALE */
2+
13
const emptydict = {};
2-
const descriptor = { configurable: true, enumerable: true };
34

45
const memoizedMessages = new Proxy(
56
{
6-
messages: emptydict,
7-
descriptor: undefined,
7+
fallback: emptydict,
8+
primary: emptydict,
9+
descriptor: { configurable: true, enumerable: true },
810
},
911
{
1012
getOwnPropertyDescriptor(ref, key) {
1113
return ref.descriptor;
1214
},
1315
get(ref, key) {
14-
return ref.messages[key];
16+
if (key in ref.primary) {
17+
return ref.primary[key];
18+
}
19+
if (key in ref.fallback) {
20+
return ref.fallback[key];
21+
}
22+
return undefined;
1523
},
1624
set(ref, locale, messages) {
17-
let next = undefined;
25+
if (!messages) {
26+
ref.primary = emptydict;
27+
ref.fallback = emptydict;
28+
return true;
29+
}
1830
if (locale in messages) {
19-
next = messages[locale];
31+
ref.primary = messages[locale];
32+
} else {
33+
ref.primary = emptydict;
2034
}
21-
if (next) {
22-
ref.descriptor = descriptor;
23-
ref.messages = next;
35+
if (DEFAULT_LOCALE in messages) {
36+
ref.fallback = messages[DEFAULT_LOCALE];
2437
} else {
25-
ref.descriptor = undefined;
26-
ref.messages = emptydict;
38+
ref.fallback = emptydict;
2739
}
2840
return true;
2941
},

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@lastui/rocker",
3-
"version": "0.19.37",
3+
"version": "0.19.38",
44
"license": "Apache-2.0",
55
"author": "[email protected]",
66
"homepage": "https://github.com/lastui/rocker#readme",

0 commit comments

Comments
 (0)