Skip to content

Commit b574d71

Browse files
committed
tests(localization): Add automation for localization and new util functions. Tweak getting resources.
1 parent 995f79e commit b574d71

File tree

4 files changed

+270
-13
lines changed

4 files changed

+270
-13
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import { getCurrentResourceStrings, getI18nManager, registerI18n, setCurrentI18n } from 'igniteui-i18n-core';
2+
import { ActionStripResourceStringsEN } from './action-strip-resources';
3+
import { BannerResourceStringsEN } from './banner-resources';
4+
import { changei18n, getCurrentResourceStrings as igxGetCurrentResourceStrings } from './resources';
5+
import { ActionStripResourceStringsBG } from 'projects/igniteui-angular-i18n/src/i18n/BG/action-strip-resources';
6+
import { BannerResourceStringsBG, ResourceStringsBG } from 'igniteui-i18n-resources';
7+
8+
describe('i18n', () => {
9+
beforeEach(() => {
10+
// Clear manager state between tests.
11+
getI18nManager()['_resourcesMap'] = new Map([[getI18nManager().currentLocale, {}]]);
12+
});
13+
14+
describe('old public API', () => {
15+
it('should correctly register old igx_ prefixed resources to new manager', () => {
16+
expect(getCurrentResourceStrings()).toEqual({});
17+
changei18n(ActionStripResourceStringsEN);
18+
19+
expect(getCurrentResourceStrings()).toEqual({
20+
action_strip_button_more_title: 'More'
21+
});
22+
});
23+
24+
it('should append new registered resources, if they have different keys', () => {
25+
changei18n(ActionStripResourceStringsEN);
26+
changei18n(BannerResourceStringsEN);
27+
28+
expect(getCurrentResourceStrings()).toEqual({
29+
action_strip_button_more_title: 'More',
30+
banner_button_dismiss: 'Dismiss'
31+
});
32+
});
33+
34+
it('should override old registered resources, if they have same keys', () => {
35+
changei18n(ActionStripResourceStringsEN);
36+
changei18n(BannerResourceStringsEN);
37+
changei18n(ActionStripResourceStringsBG);
38+
39+
expect(getCurrentResourceStrings()).toEqual({
40+
action_strip_button_more_title: 'Още',
41+
banner_button_dismiss: 'Dismiss'
42+
});
43+
});
44+
});
45+
46+
describe('internal API', () => {
47+
it('should correctly return component resources based on registered init resources', () => {
48+
igxGetCurrentResourceStrings(ActionStripResourceStringsEN, true);
49+
50+
expect(igxGetCurrentResourceStrings(ActionStripResourceStringsEN, false)).toEqual({
51+
igx_action_strip_button_more_title: 'More'
52+
});
53+
});
54+
55+
it('should correctly filter out component resources based on registered init resources', () => {
56+
igxGetCurrentResourceStrings(ActionStripResourceStringsEN, true);
57+
igxGetCurrentResourceStrings(BannerResourceStringsEN, true);
58+
59+
expect(getCurrentResourceStrings()).toEqual({
60+
action_strip_button_more_title: 'More',
61+
banner_button_dismiss: 'Dismiss'
62+
});
63+
expect(igxGetCurrentResourceStrings(ActionStripResourceStringsEN, false)).toEqual({
64+
igx_action_strip_button_more_title: 'More'
65+
});
66+
});
67+
68+
it('getting correctly filter out component resources should interfere with other calls for getting resources', () => {
69+
igxGetCurrentResourceStrings(ActionStripResourceStringsEN, true);
70+
igxGetCurrentResourceStrings(ActionStripResourceStringsEN, false);
71+
igxGetCurrentResourceStrings(BannerResourceStringsEN, true);
72+
igxGetCurrentResourceStrings(BannerResourceStringsEN, false);
73+
igxGetCurrentResourceStrings(ActionStripResourceStringsEN, false);
74+
75+
expect(getCurrentResourceStrings()).toEqual({
76+
action_strip_button_more_title: 'More',
77+
banner_button_dismiss: 'Dismiss'
78+
});
79+
expect(igxGetCurrentResourceStrings(ActionStripResourceStringsEN, false)).toEqual({
80+
igx_action_strip_button_more_title: 'More'
81+
});
82+
});
83+
});
84+
85+
describe('new public API', () => {
86+
it('should return correct component resources when locale is changed using new API', () => {
87+
// Components init their default locales
88+
igxGetCurrentResourceStrings(ActionStripResourceStringsEN, true);
89+
igxGetCurrentResourceStrings(BannerResourceStringsEN, true);
90+
91+
// User registers new locale
92+
registerI18n(ResourceStringsBG, 'bg');
93+
setCurrentI18n('bg');
94+
95+
expect(igxGetCurrentResourceStrings(ActionStripResourceStringsEN, false)).toEqual({
96+
igx_action_strip_button_more_title: 'Още'
97+
});
98+
})
99+
100+
it('should return default strings if locale is changed using new API, but its missing resources', () => {
101+
// Components init their default locales
102+
igxGetCurrentResourceStrings(ActionStripResourceStringsEN, true);
103+
igxGetCurrentResourceStrings(BannerResourceStringsEN, true);
104+
105+
// User registers new locale
106+
setCurrentI18n('bg');
107+
108+
expect(igxGetCurrentResourceStrings(ActionStripResourceStringsEN, false)).toEqual({
109+
igx_action_strip_button_more_title: 'More'
110+
});
111+
});
112+
113+
it('should return default strings if locale is changed using new API, but its missing resources for this particular component', () => {
114+
// Components init their default locales
115+
igxGetCurrentResourceStrings(ActionStripResourceStringsEN, true);
116+
igxGetCurrentResourceStrings(BannerResourceStringsEN, true);
117+
118+
// User registers new locale
119+
registerI18n(BannerResourceStringsBG, 'bg');
120+
setCurrentI18n('bg');
121+
122+
expect(igxGetCurrentResourceStrings(ActionStripResourceStringsEN, false)).toEqual({
123+
igx_action_strip_button_more_title: 'More'
124+
});
125+
});
126+
});
127+
});

projects/igniteui-angular/src/lib/core/i18n/resources.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ import {
1717
getCurrentResourceStrings as getCurrentResourceStringsCore,
1818
IResourceStrings as IResourceStringsCore,
1919
setCurrentI18n,
20-
getI18nManager,
21-
getCurrentI18n
20+
getI18nManager
2221
} from 'igniteui-i18n-core';
2322

2423
export interface IResourceStrings extends IGridResourceStrings, ITimePickerResourceStrings, ICalendarResourceStrings,
@@ -27,7 +26,7 @@ export interface IResourceStrings extends IGridResourceStrings, ITimePickerResou
2726
IActionStripResourceStrings, IQueryBuilderResourceStrings, IBannerResourceStrings { }
2827

2928

30-
function igxRegisterI18n(resourceStrings: IResourceStrings, locale: string) {
29+
function igxRegisterI18n(resourceStrings: IResourceStrings, locale: string) {
3130
// Remove `igx_` prefix for compatibility with older versions.
3231
const genericResourceStrings: IResourceStringsCore = {};
3332
for (const key of Object.keys(resourceStrings)) {
@@ -60,13 +59,15 @@ export function getCurrentResourceStrings<T>(defaultEN: T, init = true) {
6059
const resourceStrings = getCurrentResourceStringsCore();
6160
const normalizedResourceStrings: T = {} as T;
6261
const resourceStringsKeys = Object.keys(resourceStrings);
63-
for (const key of resourceStringsKeys) {
64-
let stringKey = key;
65-
if (!stringKey.startsWith("igx_")) {
66-
stringKey = "igx_" + stringKey;
62+
for (const igxKey of igxResourceStringKeys) {
63+
let coreKey = igxKey;
64+
if (coreKey.startsWith("igx_")) {
65+
coreKey = coreKey.replace("igx_", "");
6766
}
68-
if (igxResourceStringKeys.includes(stringKey)) {
69-
normalizedResourceStrings[stringKey] = resourceStrings[key];
67+
if (resourceStringsKeys.includes(coreKey)) {
68+
normalizedResourceStrings[igxKey] = resourceStrings[coreKey];
69+
} else {
70+
normalizedResourceStrings[igxKey] = defaultEN[igxKey];
7071
}
7172
}
7273

projects/igniteui-angular/src/lib/core/utils.spec.ts

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { cloneValue, isObject, isDate } from './utils';
1+
import { cloneValue, isObject, isDate, getCurrencyCode, getCurrencySymbol, getLocaleFirstDayOfWeek, formatDate, formatCurrency, formatPercent, formatNumber, getLocaleDateFormat, getLocaleDateTimeFormat } from './utils';
22
import { SampleTestData } from '../test-utils/sample-test-data.spec';
33

44
describe('Utils', () => {
@@ -253,4 +253,133 @@ describe('Utils', () => {
253253
expect(isDate(variable)).toBeFalsy();
254254
});
255255
});
256+
257+
describe('Localization', () => {
258+
describe('number formatting', () => {
259+
it('should format number correctly', () => {
260+
expect(formatNumber(1.25, 'en')).toEqual('1.25');
261+
expect(formatNumber(125, 'en')).toEqual('125');
262+
expect(formatNumber(1250, 'en')).toEqual('1,250');
263+
expect(formatNumber(12500, 'en')).toEqual('12,500');
264+
265+
expect(formatNumber(1.25, 'bg')).toEqual('1,25');
266+
expect(formatNumber(125, 'bg')).toEqual('125');
267+
expect(formatNumber(1250, 'bg')).toEqual('1250');
268+
expect(formatNumber(12500, 'bg')).toEqual('12 500');
269+
270+
expect(formatNumber(1.25, 'de')).toEqual('1,25');
271+
expect(formatNumber(125, 'de')).toEqual('125');
272+
expect(formatNumber(1250, 'de')).toEqual('1.250');
273+
expect(formatNumber(12500, 'de')).toEqual('12.500');
274+
});
275+
276+
it('should format percent correctly', () => {
277+
expect(formatPercent(1.25, 'en')).toEqual('125%');
278+
expect(formatPercent(125, 'en')).toEqual('12,500%');
279+
expect(formatPercent(1.25, 'bg')).toEqual('125%');
280+
expect(formatPercent(125, 'bg')).toEqual('12 500%');
281+
});
282+
283+
it('should format currency correctly', () => {
284+
expect(formatCurrency(12345, 'en', 'symbol', 'EUR')).toEqual('€12,345.00');
285+
expect(formatCurrency(12345, 'en', 'symbol', 'EUR', '1.0-3')).toEqual('€12,345');
286+
expect(formatCurrency('12345.33', 'en', 'symbol', 'EUR', '1.0-3')).toEqual('€12,345.33');
287+
expect(formatCurrency(12345, 'en', 'symbol', 'EUR', '1.1-3')).toEqual('€12,345.0');
288+
expect(formatCurrency('12345', 'en', 'symbol', 'EUR', '1.1-3')).toEqual('€12,345.0');
289+
});
290+
})
291+
292+
describe('date formatting', () => {
293+
it('should format string to dateTime', () => {
294+
expect(formatDate('2025-01-25T14:15:00', 'short', 'en-US')).toEqual('1/25/25, 2:15 PM');
295+
expect(formatDate('2025-01-25T14:15:00', 'medium', 'en-US')).toEqual('Jan 25, 2025, 2:15:00 PM');
296+
expect(formatDate('2025-01-25T14:15:00', 'long', 'en-US')).toEqual('January 25, 2025 at 2:15:00 PM GMT+2');
297+
expect(formatDate('2025-01-25T14:15:00', 'full', 'en-US')).toEqual('Saturday, January 25, 2025 at 2:15:00 PM Eastern European Standard Time');
298+
});
299+
300+
it('should format string to date', () => {
301+
expect(formatDate('2025-01-25T14:15:00', 'shortDate', 'en-US')).toEqual('1/25/25');
302+
expect(formatDate('2025-01-25T14:15:00', 'mediumDate', 'en-US')).toEqual('Jan 25, 2025');
303+
expect(formatDate('2025-01-25T14:15:00', 'longDate', 'en-US')).toEqual('January 25, 2025');
304+
expect(formatDate('2025-01-25T14:15:00', 'fullDate', 'en-US')).toEqual('Saturday, January 25, 2025');
305+
});
306+
307+
it('should format string to time', () => {
308+
expect(formatDate('2025-01-25T14:15:00', 'shortTime', 'en-US')).toEqual('2:15 PM');
309+
expect(formatDate('2025-01-25T14:15:00', 'mediumTime', 'en-US')).toEqual('2:15:00 PM');
310+
expect(formatDate('2025-01-25T14:15:00', 'longTime', 'en-US')).toEqual('2:15:00 PM GMT+2');
311+
expect(formatDate('2025-01-25T14:15:00', 'fullTime', 'en-US')).toEqual('2:15:00 PM Eastern European Standard Time');
312+
});
313+
314+
it('should format string to custom format', () => {
315+
expect(formatDate('2025-01-25T14:15:00', 'ex: hh:mm bbb GGG', 'en-US')).toEqual('ex: 02:15 in th. af. AD');
316+
expect(formatDate('2025-01-25T14:15:00', 'ex: HH:mm bbb GGG', 'en-US')).toEqual('ex: 14:15 in th. af. AD');
317+
});
318+
319+
it('should return correct date format per locale', () => {
320+
// Defaults to Angular's one because they are registered in tests
321+
expect(getLocaleDateFormat('en', 'short')).toEqual('M/d/yy');
322+
expect(getLocaleDateFormat('en', 'medium')).toEqual('MMM d, y');
323+
expect(getLocaleDateFormat('en', 'long')).toEqual('MMMM d, y');
324+
expect(getLocaleDateFormat('en', 'full')).toEqual('EEEE, MMMM d, y');
325+
326+
expect(getLocaleDateFormat('de', 'short')).toEqual('dd.MM.yy');
327+
expect(getLocaleDateFormat('de', 'medium')).toEqual('dd.MM.y');
328+
expect(getLocaleDateFormat('de', 'long')).toEqual('d. MMMM y');
329+
expect(getLocaleDateFormat('de', 'full')).toEqual('EEEE, d. MMMM y');
330+
331+
// There's no registered locale for IT in tests, so use new API
332+
expect(getLocaleDateFormat('it', 'short')).toEqual('dd/MM/yy');
333+
expect(getLocaleDateFormat('it', 'medium')).toEqual('d MMM yyyy');
334+
expect(getLocaleDateFormat('it', 'long')).toEqual(`d MMMM yyyy`);
335+
expect(getLocaleDateFormat('it', 'full')).toEqual(`EEEE d MMMM yyyy`);
336+
});
337+
338+
it('should return correct datetime format per locale', () => {
339+
// Defaults to Angular's one because they are registered in tests
340+
expect(getLocaleDateTimeFormat('en', 'short')).toEqual('{1}, {0}');
341+
expect(getLocaleDateTimeFormat('en', 'medium')).toEqual('{1}, {0}');
342+
expect(getLocaleDateTimeFormat('en', 'long')).toEqual(`{1} 'at' {0}`);
343+
expect(getLocaleDateTimeFormat('en', 'full')).toEqual(`{1} 'at' {0}`);
344+
345+
expect(getLocaleDateTimeFormat('de', 'short')).toEqual('{1}, {0}');
346+
expect(getLocaleDateTimeFormat('de', 'medium')).toEqual('{1}, {0}');
347+
expect(getLocaleDateTimeFormat('de', 'long')).toEqual(`{1} 'um' {0}`);
348+
expect(getLocaleDateTimeFormat('de', 'full')).toEqual(`{1} 'um' {0}`);
349+
350+
// There's no registered locale for IT in tests, so use new API
351+
expect(getLocaleDateTimeFormat('it', 'short')).toEqual('dd/MM/yy, HH:mm');
352+
expect(getLocaleDateTimeFormat('it', 'medium')).toEqual('d MMM yyyy, HH:mm:ss');
353+
expect(getLocaleDateTimeFormat('it', 'long')).toEqual(`d MMMM yyyy alle ore HH:mm:ss z`);
354+
expect(getLocaleDateTimeFormat('it', 'full')).toEqual(`EEEE d MMMM yyyy alle ore HH:mm:ss zzzz`);
355+
});
356+
});
357+
358+
describe('other', () => {
359+
it('getCurrencyCode should return default USD as currency code for locale, if no Angular is defined', () => {
360+
expect(getCurrencyCode('en-US')).toEqual('USD');
361+
362+
// Registered in tests, that's why they are available
363+
expect(getCurrencyCode('bg')).toEqual('BGN');
364+
expect(getCurrencyCode('de')).toEqual('EUR');
365+
366+
// This is not registered in tests yet
367+
expect(getCurrencyCode('it')).toEqual('USD');
368+
});
369+
370+
it('getCurrencySymbol should return correct currency symbol', () => {
371+
expect(getCurrencySymbol('USD', 'en-US')).toEqual('$');
372+
expect(getCurrencySymbol('BGN', 'bg')).toEqual('лв.');
373+
expect(getCurrencySymbol('EUR', 'de')).toEqual('€');
374+
expect(getCurrencySymbol('EUR', 'it')).toEqual('€');
375+
});
376+
377+
it('getLocaleFirstDayOfWeek should return correct values per locale', () => {
378+
expect(getLocaleFirstDayOfWeek('en-US')).toEqual(0); // This is Angular's default
379+
expect(getLocaleFirstDayOfWeek('bg')).toEqual(1);
380+
expect(getLocaleFirstDayOfWeek('de')).toEqual(1);
381+
expect(getLocaleFirstDayOfWeek('it')).toEqual(1);
382+
});
383+
});
384+
});
256385
});

projects/igniteui-angular/src/lib/core/utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ export function onResourceChangeHandle(destroyObj: Subject<any> | DestroyRef, ca
601601
destroyObj.onDestroy(() => removeHandler());
602602
} else if (destroyObj) {
603603
destroyObj.subscribe({
604-
complete: () => removeHandler()
604+
complete: () => removeHandler()
605605
});
606606
}
607607
}
@@ -753,15 +753,15 @@ export function getCurrencyCode(locale: string, overrideCode?: string) {
753753
return currencyCode;
754754
}
755755

756-
export function getCurrencySymbol(currencyCode: string, locale?: string, currencyDisplay: keyof Intl.NumberFormatOptionsCurrencyDisplayRegistry = "symbol") {
756+
export function getCurrencySymbol(currencyCode: string, locale?: string, currencyDisplay: keyof Intl.NumberFormatOptionsCurrencyDisplayRegistry = "symbol") {
757757
return getI18nManager().getCurrencySymbol(currencyCode, locale, currencyDisplay);
758758
}
759759

760760
export function getLocaleFirstDayOfWeek(locale?: string) {
761761
try {
762762
// Angular returns 0 for Sunday...
763763
return ngGetLocaleFirstDayOfWeek(locale);
764-
} catch {}
764+
} catch { }
765765
return getI18nManager().getFirstDayOfWeek(locale);
766766
}
767767

0 commit comments

Comments
 (0)