@@ -34,81 +34,59 @@ const EXPECTED_SECTIONS = [
3434 'simulator' ,
3535] ;
3636
37+ const ALL_LANGUAGES : AvailableLanguage [ ] = [
38+ 'en' ,
39+ 'he' ,
40+ 'id' ,
41+ 'ja' ,
42+ 'ko' ,
43+ 'ms' ,
44+ 'ru' ,
45+ 'zh' ,
46+ ] ;
47+
3748describe ( 'l10n object' , ( ) => {
3849 it ( 'supports all expected languages' , ( ) => {
39- expect ( supportedLanguages ) . toEqual ( [ 'en' , 'id' , 'ja' , 'zh' ] ) ;
40- expect ( Object . keys ( l10n ) ) . toEqual ( [ 'en' , 'id' , 'ja' , 'zh' ] ) ;
50+ expect ( supportedLanguages ) . toEqual ( ALL_LANGUAGES ) ;
51+ expect ( Object . keys ( l10n ) ) . toEqual ( ALL_LANGUAGES ) ;
4152 } ) ;
4253
4354 it ( 'l10n.en is eagerly loaded and equals raw enData' , ( ) => {
4455 expect ( l10n . en ) . toBe ( enData ) ; // same reference, not a copy
4556 } ) ;
4657
47- it ( 'l10n.en has all 19 expected top-level sections' , ( ) => {
48- const enSections = Object . keys ( l10n . en ) ;
49- for ( const section of EXPECTED_SECTIONS ) {
50- expect ( enSections ) . toContain ( section ) ;
51- }
52- expect ( enSections ) . toHaveLength ( EXPECTED_SECTIONS . length ) ;
53- } ) ;
54-
55- it ( 'l10n.ja has all 19 expected top-level sections' , ( ) => {
56- const jaSections = Object . keys ( l10n . ja ) ;
57- for ( const section of EXPECTED_SECTIONS ) {
58- expect ( jaSections ) . toContain ( section ) ;
59- }
60- expect ( jaSections ) . toHaveLength ( EXPECTED_SECTIONS . length ) ;
61- } ) ;
62-
63- it ( 'l10n.id has all 19 expected top-level sections' , ( ) => {
64- const idSections = Object . keys ( l10n . id ) ;
65- for ( const section of EXPECTED_SECTIONS ) {
66- expect ( idSections ) . toContain ( section ) ;
67- }
68- expect ( idSections ) . toHaveLength ( EXPECTED_SECTIONS . length ) ;
69- } ) ;
70-
71- it ( 'l10n.zh has all 19 expected top-level sections' , ( ) => {
72- const zhSections = Object . keys ( l10n . zh ) ;
73- for ( const section of EXPECTED_SECTIONS ) {
74- expect ( zhSections ) . toContain ( section ) ;
75- }
76- expect ( zhSections ) . toHaveLength ( EXPECTED_SECTIONS . length ) ;
77- } ) ;
58+ it . each ( ALL_LANGUAGES ) (
59+ 'l10n.%s has all 19 expected top-level sections' ,
60+ lang => {
61+ const sections = Object . keys ( l10n [ lang ] ) ;
62+ for ( const section of EXPECTED_SECTIONS ) {
63+ expect ( sections ) . toContain ( section ) ;
64+ }
65+ expect ( sections ) . toHaveLength ( EXPECTED_SECTIONS . length ) ;
66+ } ,
67+ ) ;
7868
7969 it ( 'l10n.en matches the raw en.json data' , ( ) => {
8070 expect ( l10n . en ) . toEqual ( enData ) ;
8171 } ) ;
8272
83- it ( 'l10n.id contains Indonesian translations where they exist' , ( ) => {
84- const idData = require ( '../id.json' ) ;
85- expect ( l10n . id . common . cancel ) . toBe ( idData . common . cancel ) ;
86- expect ( l10n . id . common . cancel ) . not . toBe ( l10n . en . common . cancel ) ;
87- } ) ;
88-
89- it ( 'returns cached result on repeated access for id' , ( ) => {
90- const first = l10n . id ;
91- const second = l10n . id ;
92- expect ( first ) . toBe ( second ) ; // same reference = cached
93- } ) ;
94-
95- it ( 'returns cached result on repeated access for zh' , ( ) => {
96- const first = l10n . zh ;
97- const second = l10n . zh ;
98- expect ( first ) . toBe ( second ) ; // same reference = cached
99- } ) ;
100-
101- it ( 'l10n.ja contains Japanese translations where they exist' , ( ) => {
102- const jaData = require ( '../ja.json' ) ;
103- expect ( l10n . ja . common . cancel ) . toBe ( jaData . common . cancel ) ;
104- expect ( l10n . ja . common . cancel ) . not . toBe ( l10n . en . common . cancel ) ;
105- } ) ;
106-
107- it ( 'l10n.zh contains Chinese translations where they exist' , ( ) => {
108- const zhData = require ( '../zh.json' ) ;
109- expect ( l10n . zh . common . cancel ) . toBe ( zhData . common . cancel ) ;
110- expect ( l10n . zh . common . cancel ) . not . toBe ( l10n . en . common . cancel ) ;
111- } ) ;
73+ it . each ( [ 'he' , 'id' , 'ja' , 'ko' , 'ms' , 'ru' , 'zh' ] as AvailableLanguage [ ] ) (
74+ 'l10n.%s contains translations where they exist' ,
75+ lang => {
76+ const langData = require ( `../${ lang } .json` ) ;
77+ expect ( l10n [ lang ] . common . cancel ) . toBe ( langData . common . cancel ) ;
78+ expect ( l10n [ lang ] . common . cancel ) . not . toBe ( l10n . en . common . cancel ) ;
79+ } ,
80+ ) ;
81+
82+ it . each ( [ 'he' , 'id' , 'ja' , 'ko' , 'ms' , 'ru' , 'zh' ] as AvailableLanguage [ ] ) (
83+ 'returns cached result on repeated access for %s' ,
84+ lang => {
85+ const first = l10n [ lang ] ;
86+ const second = l10n [ lang ] ;
87+ expect ( first ) . toBe ( second ) ; // same reference = cached
88+ } ,
89+ ) ;
11290
11391 it ( 'l10n.ja falls back to English for missing keys' , ( ) => {
11492 // Verify the merge mechanism by building a partial ja
@@ -138,26 +116,24 @@ describe('l10n object', () => {
138116 expect ( enData ) . toEqual ( enClone ) ;
139117 } ) ;
140118
141- it ( 'returns cached result on repeated access' , ( ) => {
142- const first = l10n . ja ;
143- const second = l10n . ja ;
144- expect ( first ) . toBe ( second ) ; // same reference = cached
145- } ) ;
146-
147119 it ( 'supports in operator for all languages' , ( ) => {
148120 expect ( 'en' in l10n ) . toBe ( true ) ;
121+ expect ( 'he' in l10n ) . toBe ( true ) ;
149122 expect ( 'id' in l10n ) . toBe ( true ) ;
150123 expect ( 'ja' in l10n ) . toBe ( true ) ;
124+ expect ( 'ko' in l10n ) . toBe ( true ) ;
125+ expect ( 'ms' in l10n ) . toBe ( true ) ;
126+ expect ( 'ru' in l10n ) . toBe ( true ) ;
151127 expect ( 'zh' in l10n ) . toBe ( true ) ;
152128 expect ( 'xx' in l10n ) . toBe ( false ) ;
153129 expect ( 'fr' in l10n ) . toBe ( false ) ;
154130 } ) ;
155131
156132 it ( 'returns undefined for unsupported language key' , ( ) => {
157133 // Access a property that does not exist on the l10n object
158- // eslint-disable-next-line @typescript-eslint/no-explicit-any
134+
159135 expect ( ( l10n as any ) . xx ) . toBeUndefined ( ) ;
160- // eslint-disable-next-line @typescript-eslint/no-explicit-any
136+
161137 expect ( ( l10n as any ) . fr ) . toBeUndefined ( ) ;
162138 } ) ;
163139
@@ -170,7 +146,7 @@ describe('l10n object', () => {
170146
171147 // Object.keys should enumerate property names without invoking getters
172148 const keys = Object . keys ( freshModule . l10n ) ;
173- expect ( keys ) . toEqual ( [ 'en' , 'id' , 'ja' , 'zh' ] ) ;
149+ expect ( keys ) . toEqual ( ALL_LANGUAGES ) ;
174150
175151 // Cache should still only have en -- getters were not called
176152 expect ( freshModule . _testGetCacheKeys ( ) ) . toEqual ( [ 'en' ] ) ;
@@ -192,7 +168,7 @@ describe('l10n object', () => {
192168
193169describe ( 'exports' , ( ) => {
194170 it ( 'supportedLanguages matches expected array' , ( ) => {
195- expect ( supportedLanguages ) . toEqual ( [ 'en' , 'id' , 'ja' , 'zh' ] ) ;
171+ expect ( supportedLanguages ) . toEqual ( ALL_LANGUAGES ) ;
196172 } ) ;
197173
198174 it ( 'languageDisplayNames has entries for all supported languages' , ( ) => {
@@ -204,9 +180,15 @@ describe('exports', () => {
204180
205181 it ( 'languageDisplayNames contains expected values' , ( ) => {
206182 expect ( languageDisplayNames . en ) . toBe ( 'English (EN)' ) ;
183+ expect ( languageDisplayNames . he ) . toBe ( '\u05E2\u05D1\u05E8\u05D9\u05EA (HE)' ) ;
184+ expect ( languageDisplayNames . id ) . toBe ( 'Indonesia (ID)' ) ;
207185 expect ( languageDisplayNames . ja ) . toBe ( '\u65E5\u672C\u8A9E (JA)' ) ;
186+ expect ( languageDisplayNames . ko ) . toBe ( '\uD55C\uAD6D\uC5B4 (KO)' ) ;
187+ expect ( languageDisplayNames . ms ) . toBe ( 'Melayu (MS)' ) ;
188+ expect ( languageDisplayNames . ru ) . toBe (
189+ '\u0420\u0443\u0441\u0441\u043A\u0438\u0439 (RU)' ,
190+ ) ;
208191 expect ( languageDisplayNames . zh ) . toBe ( '\u4E2D\u6587 (ZH)' ) ;
209- expect ( languageDisplayNames . id ) . toBe ( 'Indonesia (ID)' ) ;
210192 } ) ;
211193
212194 it ( 'languageDisplayNames has exactly the same keys as supportedLanguages' , ( ) => {
@@ -235,64 +217,37 @@ describe('lazy loading', () => {
235217 } ) ;
236218 } ) ;
237219
238- it ( 'accessing a language populates the cache' , ( ) => {
239- jest . isolateModules ( ( ) => {
240- const freshModule = require ( '../index' ) ;
241-
242- // Before access: only en
243- expect ( freshModule . _testGetCacheKeys ( ) ) . toEqual ( [ 'en' ] ) ;
220+ it . each ( [ 'he' , 'id' , 'ja' , 'ko' , 'ms' , 'ru' , 'zh' ] as AvailableLanguage [ ] ) (
221+ 'accessing %s populates the cache' ,
222+ lang => {
223+ jest . isolateModules ( ( ) => {
224+ const freshModule = require ( '../index' ) ;
225+ expect ( freshModule . _testGetCacheKeys ( ) ) . toEqual ( [ 'en' ] ) ;
244226
245- // Access ja
246- const _ja = freshModule . l10n . ja ;
247- expect ( _ja ) . toBeDefined ( ) ;
248-
249- // After access: en and ja
250- expect ( freshModule . _testGetCacheKeys ( ) ) . toContain ( 'ja' ) ;
251- } ) ;
252- } ) ;
253-
254- it ( 'accessing id populates the cache' , ( ) => {
255- jest . isolateModules ( ( ) => {
256- const freshModule = require ( '../index' ) ;
257- expect ( freshModule . _testGetCacheKeys ( ) ) . toEqual ( [ 'en' ] ) ;
258-
259- const _id = freshModule . l10n . id ;
260- expect ( _id ) . toBeDefined ( ) ;
261- expect ( freshModule . _testGetCacheKeys ( ) ) . toContain ( 'id' ) ;
262- } ) ;
263- } ) ;
264-
265- it ( 'accessing zh populates the cache' , ( ) => {
266- jest . isolateModules ( ( ) => {
267- const freshModule = require ( '../index' ) ;
268- expect ( freshModule . _testGetCacheKeys ( ) ) . toEqual ( [ 'en' ] ) ;
269-
270- const _zh = freshModule . l10n . zh ;
271- expect ( _zh ) . toBeDefined ( ) ;
272- expect ( freshModule . _testGetCacheKeys ( ) ) . toContain ( 'zh' ) ;
273- } ) ;
274- } ) ;
227+ const _data = freshModule . l10n [ lang ] ;
228+ expect ( _data ) . toBeDefined ( ) ;
229+ expect ( freshModule . _testGetCacheKeys ( ) ) . toContain ( lang ) ;
230+ } ) ;
231+ } ,
232+ ) ;
275233
276234 it ( 'accessing all languages populates the full cache' , ( ) => {
277235 jest . isolateModules ( ( ) => {
278236 const freshModule = require ( '../index' ) ;
279237 expect ( freshModule . _testGetCacheKeys ( ) ) . toEqual ( [ 'en' ] ) ;
280238
281239 // Access each non-en language
282- const _id = freshModule . l10n . id ;
283- const _ja = freshModule . l10n . ja ;
284- const _zh = freshModule . l10n . zh ;
285-
286- expect ( _id ) . toBeDefined ( ) ;
287- expect ( _ja ) . toBeDefined ( ) ;
288- expect ( _zh ) . toBeDefined ( ) ;
240+ const nonEn = ALL_LANGUAGES . filter ( l => l !== 'en' ) ;
241+ for ( const lang of nonEn ) {
242+ const _data = freshModule . l10n [ lang ] ;
243+ expect ( _data ) . toBeDefined ( ) ;
244+ }
289245
290246 const cacheKeys = freshModule . _testGetCacheKeys ( ) ;
291- expect ( cacheKeys ) . toContain ( 'en' ) ;
292- expect ( cacheKeys ) . toContain ( 'id' ) ;
293- expect ( cacheKeys ) . toContain ( 'ja' ) ;
294- expect ( cacheKeys ) . toContain ( 'zh' ) ;
295- expect ( cacheKeys ) . toHaveLength ( 4 ) ;
247+ for ( const lang of ALL_LANGUAGES ) {
248+ expect ( cacheKeys ) . toContain ( lang ) ;
249+ }
250+ expect ( cacheKeys ) . toHaveLength ( ALL_LANGUAGES . length ) ;
296251 } ) ;
297252 } ) ;
298253
@@ -305,13 +260,22 @@ describe('lazy loading', () => {
305260
306261describe ( 'type safety' , ( ) => {
307262 it ( 'AvailableLanguage matches supported languages' , ( ) => {
308- const keys : AvailableLanguage [ ] = [ 'en' , 'id' , 'ja' , 'zh' ] ;
263+ const keys : AvailableLanguage [ ] = ALL_LANGUAGES ;
309264 expect ( keys ) . toEqual ( supportedLanguages ) ;
310265 } ) ;
311266
312267 it ( 'keyof typeof l10n resolves to literal union' , ( ) => {
313268 // At runtime we verify the keys match
314- const keys : Array < keyof typeof l10n > = [ 'en' , 'id' , 'ja' , 'zh' ] ;
269+ const keys : Array < keyof typeof l10n > = [
270+ 'en' ,
271+ 'he' ,
272+ 'id' ,
273+ 'ja' ,
274+ 'ko' ,
275+ 'ms' ,
276+ 'ru' ,
277+ 'zh' ,
278+ ] ;
315279 expect ( Object . keys ( l10n ) . sort ( ) ) . toEqual ( keys . sort ( ) ) ;
316280
317281 // This would cause a compile error if the type were wrong:
0 commit comments