Skip to content

Commit bf0241c

Browse files
committed
apply new changes for language setoption and add new test
1 parent d94606d commit bf0241c

File tree

3 files changed

+93
-46
lines changed

3 files changed

+93
-46
lines changed

src/i18n/language.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const languages = {
1515
} as const;
1616

1717
export type LanguageCode = keyof typeof languages;
18+
export const DefaultLanguage: LanguageCode = "en_US";
1819

1920
/**
2021
* Get all available language codes
@@ -33,14 +34,14 @@ export class Translator {
3334
const rawLang = (
3435
navigator.language ||
3536
(navigator as any).userLanguage ||
36-
"en-US"
37+
DefaultLanguage
3738
).replace("-", "_");
3839

3940
const normalizedLang = (Object.keys(languages) as LanguageCode[]).find(
4041
(key) => key.toLowerCase() === rawLang.toLowerCase()
4142
);
4243

43-
this._languageCode = normalizedLang ?? "en_US";
44+
this._languageCode = normalizedLang ?? DefaultLanguage;
4445
}
4546
}
4647

src/option.test.ts

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { setOption, setOptions } from "./option";
2+
import { Translator } from "./i18n/language";
23

34
Object.defineProperty(global, "navigator", {
45
value: { language: "en-US" },
@@ -13,7 +14,7 @@ describe("option", () => {
1314
// Act → capture return value
1415
const result = setOption(mockOption, "key1", "newValue1");
1516

16-
// Assert
17+
//Assert
1718
expect(result.key1).toBe("newValue1");
1819
expect(mockOption.key1).toBe("value1");
1920
});
@@ -40,19 +41,19 @@ describe("option", () => {
4041
describe("setOptions with language", () => {
4142
it("should set language when provided", () => {
4243
const mockOption: any = {};
43-
44+
// Act
4445
const result = setOptions(mockOption, { language: "fr_FR" });
45-
46+
// Assert
4647
expect(result.language).toEqual("fr_FR");
4748
});
4849

4950
it("should not override language when other options change", () => {
5051
const mockOption: any = {
5152
language: "en_US",
5253
};
53-
54+
// Act
5455
const result = setOptions(mockOption, { htmlRender: true });
55-
56+
// Assert
5657
expect(result.language).toEqual("en_US");
5758
expect(result.htmlRender).toBe(true);
5859
});
@@ -63,16 +64,72 @@ describe("option", () => {
6364
htmlRender: true,
6465
customProp: "test",
6566
};
66-
67-
// Change language via setOption
67+
// Act
6868
const updatedOption = setOption(mockOption, "language", "fr_FR");
69-
70-
// Assert language updated
69+
// Assert
7170
expect(updatedOption.language).toEqual("fr_FR");
72-
73-
// Other options should remain
7471
expect(updatedOption.htmlRender).toBe(true);
7572
expect(updatedOption.customProp).toBe("test");
7673
});
7774
});
75+
76+
describe("Label handling and emoji overrides", () => {
77+
it("should override label with emoji when language is already set", () => {
78+
const options: any = {
79+
language: "de_DE",
80+
nextLabel: "Weiter",
81+
prevLabel: "Zurück",
82+
doneLabel: "Fertig",
83+
};
84+
85+
const updated = setOptions(options, { nextLabel: "➡️" });
86+
87+
expect(updated.nextLabel).toBe("➡️"); // emoji kept
88+
expect(updated.prevLabel).toBe("Zurück"); // other labels stay German
89+
expect(updated.doneLabel).toBe("Fertig");
90+
});
91+
92+
it("overWritten emoji label when changing language", () => {
93+
const options: any = {
94+
language: "de_DE",
95+
nextLabel: "➡️",
96+
prevLabel: "Zurück",
97+
doneLabel: "Fertig",
98+
};
99+
100+
const updated = setOptions(options, { language: "fr_FR" });
101+
102+
expect(updated.nextLabel).toBe("Suivant"); // emoji overWritten by French
103+
const t = new Translator("fr_FR");
104+
expect(updated.prevLabel).toBe(t.translate("buttons.prev")); // now French
105+
expect(updated.doneLabel).toBe(t.translate("buttons.done"));
106+
});
107+
108+
it("should retranslate all labels if none are custom", () => {
109+
const options: any = { language: "en_US" };
110+
const updated = setOptions(options, { language: "de_DE" });
111+
112+
const t = new Translator("de_DE");
113+
expect(updated.nextLabel).toBe(t.translate("buttons.next"));
114+
expect(updated.prevLabel).toBe(t.translate("buttons.prev"));
115+
expect(updated.doneLabel).toBe(t.translate("buttons.done"));
116+
});
117+
118+
it("should keep emoji doneLabel when language is not set", () => {
119+
const defaultOptions: any = {
120+
nextLabel: "Next",
121+
prevLabel: "Back",
122+
doneLabel: "Done",
123+
};
124+
125+
const withEmoji = setOptions(defaultOptions, { doneLabel: "✅" });
126+
127+
const afterStart = setOptions(withEmoji, { isActive: true });
128+
129+
expect(afterStart.doneLabel).toBe("✅");
130+
131+
expect(afterStart.nextLabel).toBe("Next");
132+
expect(afterStart.prevLabel).toBe("Back");
133+
});
134+
});
78135
});

src/option.ts

Lines changed: 22 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,38 @@
11
import { getDefaultTourOptions, TourOptions } from "./packages/tour/option";
22
import { getDefaultHintOptions, HintOptions } from "./packages/hint/option";
3-
import { Translator } from "./i18n/language";
3+
import { Translator, DefaultLanguage } from "./i18n/language";
44

55
function isHintOptions(options: any): options is HintOptions {
66
return "hints" in options;
77
}
88

9-
/**
10-
* Ensures a valid Translator instance exists for a tour or hint.
11-
* Translator is **not** part of the public options.
12-
*/
13-
function ensureTranslator(options: Partial<TourOptions | HintOptions>) {
14-
const language = options.language ?? "en_US";
15-
16-
const translator = new Translator();
17-
translator.setLanguage(language);
18-
return translator;
19-
}
20-
219
export function applyLanguageDefaults<T extends TourOptions | HintOptions>(
2210
options: T
2311
): T {
24-
const translator = ensureTranslator(options);
12+
const language = options.language ?? DefaultLanguage;
13+
const translator = new Translator();
14+
translator.setLanguage(language);
2515

26-
const defaults = isHintOptions(options)
27-
? getDefaultHintOptions(translator)
28-
: getDefaultTourOptions(translator);
16+
if (isHintOptions(options)) {
17+
const translatedOptions = getDefaultHintOptions(translator);
2918

30-
const {
31-
nextLabel,
32-
prevLabel,
33-
skipLabel,
34-
doneLabel,
35-
stepNumbersOfLabel,
36-
dontShowAgainLabel,
37-
hintButtonLabel,
38-
language: _,
39-
...userOptions
40-
} = options as any;
19+
return {
20+
...options,
21+
hintButtonLabel: translatedOptions.hintButtonLabel,
22+
};
23+
} else {
24+
const translatedOptions = getDefaultTourOptions(translator);
4125

42-
return {
43-
...defaults,
44-
...userOptions,
45-
language: translator.getLanguage(),
46-
} as T;
26+
return {
27+
...options,
28+
doneLabel: translatedOptions.doneLabel,
29+
nextLabel: translatedOptions.nextLabel,
30+
prevLabel: translatedOptions.prevLabel,
31+
skipLabel: translatedOptions.skipLabel,
32+
dontShowAgainLabel: translatedOptions.dontShowAgainLabel,
33+
stepNumbersOfLabel: translatedOptions.stepNumbersOfLabel,
34+
};
35+
}
4736
}
4837

4938
/**

0 commit comments

Comments
 (0)