mirror of
https://github.com/transloadit/uppy.git
synced 2026-07-23 18:29:09 +00:00
* Fix translations that did not respect word order Fixes #2069 We were still using raw string concatenation in these two places. To maintain backwards compatibility, this commit adds _new_ translations that are substitution-based instead of concatenation-based. The old translation is passed in as a possible substitution parameter `backwardsCompat`, and the default (English) translations use this parameter. With this, if you are using a custom locale that overrides eg. the `exceedsSize` string, Uppy will first get your `exceedsSize` translation, and then use the default `exceedsSize2` translation which concatenates that result and the file size. So it works the same as it did in the past. If a translation requires a different word order, it can override the `exceedsSize2` translation instead. ```js new Uppy({ locale: { strings: { exceedsSize2: 'Maximum file size of %{size} exceeded', poweredBy2: '%{uppy} made this!' } } }) ``` In 2.0, we can remove all the old strings and only use `poweredBy2` (and probably rename them to `poweredBy` too, heh) * website: add missing dashboard strings to docs * locales: remove unused second plural form from EN and NL * build: allow different numbers of plural forms * utils: add test for new throwing behaviour * docs: insert PR url * locales: revert ko_KR changes * changelog: add 2.0 backlog entry * locales: var → const * docs: add brief note that translators should supply a pluralize function * locales: update en_US with new template * fix HEIGHT_MD = 400 Co-authored-by: Artur Paikin <artur@arturpaikin.com>
152 lines
4.3 KiB
JavaScript
152 lines
4.3 KiB
JavaScript
const Translator = require('./Translator')
|
|
|
|
const english = {
|
|
strings: {
|
|
chooseFile: 'Choose a file',
|
|
youHaveChosen: 'You have chosen: %{fileName}',
|
|
filesChosen: {
|
|
0: '%{smart_count} file selected',
|
|
1: '%{smart_count} files selected'
|
|
},
|
|
pluralize: function (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: function (n) {
|
|
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({
|
|
strings: {
|
|
test: 'Hello %{who}!',
|
|
test2: 'Hello %{who}'
|
|
}
|
|
})
|
|
|
|
const who = Symbol('who')
|
|
expect(translator.translateArray('test', { who: who })).toEqual(['Hello ', who, '!'])
|
|
// No empty string at the end.
|
|
expect(translator.translateArray('test2', { who: who })).toEqual(['Hello ', who])
|
|
})
|
|
})
|
|
|
|
describe('translation strings inheritance / overriding', () => {
|
|
const launguagePackLoadedInCore = english
|
|
const defaultStrings = {
|
|
strings: {
|
|
youHaveChosen: 'You have chosen 123: %{fileName}'
|
|
}
|
|
}
|
|
const userSuppliedStrings = {
|
|
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'
|
|
}
|
|
}
|
|
})
|
|
|
|
expect(() => {
|
|
translator.translate('test')
|
|
}).toThrow('Attempted to use a string with plural forms, but no value was given for %{smart_count}')
|
|
})
|
|
})
|
|
})
|