import { describe, expect, it } from 'vitest' import Translator, { type Locale } from './Translator.js' const english: Locale<0 | 1> = { strings: { chooseFile: 'Choose a file', youHaveChosen: 'You have chosen: %{fileName}', filesChosen: { 0: '%{smart_count} file selected', 1: '%{smart_count} files selected', }, }, pluralize(n) { if (n === 1) { return 0 } return 1 }, } const russian = { strings: { chooseFile: 'Выберите файл', youHaveChosen: 'Вы выбрали: %{file_name}', filesChosen: { 0: 'Выбран %{smart_count} файл', 1: 'Выбрано %{smart_count} файла', 2: 'Выбрано %{smart_count} файлов', }, }, pluralize(n: number) { if (n % 10 === 1 && n % 100 !== 11) { return 0 } if (n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20)) { return 1 } return 2 }, } describe('Translator', () => { describe('translate', () => { it('should translate a string', () => { const translator = new Translator(russian) expect(translator.translate('chooseFile')).toEqual('Выберите файл') }) it('should translate a string with non-string elements', () => { const translator = new Translator({ pluralize: english.pluralize, strings: { test: 'Hello %{who}!', test2: 'Hello %{who}', }, }) const who = Symbol('who') as any as string expect(translator.translateArray('test', { who })).toEqual([ 'Hello ', who, '!', ]) // No empty string at the end. expect(translator.translateArray('test2', { who })).toEqual([ 'Hello ', who, ]) }) }) describe('translation strings inheritance / overriding', () => { const launguagePackLoadedInCore = english const defaultStrings = { pluralize: english.pluralize, strings: { youHaveChosen: 'You have chosen 123: %{fileName}', }, } const userSuppliedStrings = { pluralize: english.pluralize, strings: { youHaveChosen: 'Beep boop: %{fileName}', }, } it('should prioritize language pack strings from Core over default', () => { const translator = new Translator([ defaultStrings, launguagePackLoadedInCore, ]) expect( translator.translate('youHaveChosen', { fileName: 'img.jpg' }), ).toEqual('You have chosen: img.jpg') }) it('should prioritize user-supplied strings over language pack from Core', () => { const translator = new Translator([ defaultStrings, launguagePackLoadedInCore, userSuppliedStrings, ]) expect( translator.translate('youHaveChosen', { fileName: 'img.jpg' }), ).toEqual('Beep boop: img.jpg') }) }) describe('interpolation', () => { it('should interpolate a string', () => { const translator = new Translator(english) expect( translator.translate('youHaveChosen', { fileName: 'img.jpg' }), ).toEqual('You have chosen: img.jpg') }) }) describe('pluralization', () => { it('should translate a string', () => { const translator = new Translator(russian) expect(translator.translate('filesChosen', { smart_count: 18 })).toEqual( 'Выбрано 18 файлов', ) expect(translator.translate('filesChosen', { smart_count: 1 })).toEqual( 'Выбран 1 файл', ) expect(translator.translate('filesChosen', { smart_count: 0 })).toEqual( 'Выбрано 0 файлов', ) }) it('should support strings without plural forms', () => { const translator = new Translator({ strings: { theAmount: 'het aantal is %{smart_count}', }, pluralize: () => 0, }) expect(translator.translate('theAmount', { smart_count: 0 })).toEqual( 'het aantal is 0', ) expect(translator.translate('theAmount', { smart_count: 1 })).toEqual( 'het aantal is 1', ) expect( translator.translate('theAmount', { smart_count: 1202530 }), ).toEqual('het aantal is 1202530') }) it('should error when using a plural form without %{smart_count}', () => { const translator = new Translator({ strings: { test: { 0: 'A test', 1: '%{smart_count} tests', }, }, pluralize: () => 1, }) expect(() => { translator.translate('test') }).toThrow( 'Attempted to use a string with plural forms, but no value was given for %{smart_count}', ) }) }) })