167 lines
5.2 KiB
JavaScript
167 lines
5.2 KiB
JavaScript
/*
|
|
* Copyright (C) 2013 - present Instructure, Inc.
|
|
*
|
|
* This file is part of Canvas.
|
|
*
|
|
* Canvas is free software: you can redistribute it and/or modify it under
|
|
* the terms of the GNU Affero General Public License as published by the Free
|
|
* Software Foundation, version 3 of the License.
|
|
*
|
|
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License along
|
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
// note: most of these tests are now redundant w/ i18nliner-js, leaving them
|
|
// for a little bit though
|
|
|
|
import I18n, {useScope} from '@canvas/i18n'
|
|
import I18nStubber from 'helpers/I18nStubber'
|
|
import {raw} from '@instructure/html-escape'
|
|
|
|
const scope = useScope('foo')
|
|
const t = (...args) => scope.t(...Array.from(args || []))
|
|
const interpolate = (...args) => I18n.interpolate(...Array.from(args || []))
|
|
|
|
QUnit.module('I18n', {
|
|
setup() {
|
|
return I18nStubber.pushFrame()
|
|
},
|
|
|
|
teardown() {
|
|
return I18nStubber.clear()
|
|
},
|
|
})
|
|
|
|
test('missing placeholders', () => {
|
|
equal(t('k', 'ohai %{name}'), 'ohai [missing %{name} value]')
|
|
equal(t('k', 'ohai %{name}', {name: null}), 'ohai [missing %{name} value]')
|
|
equal(t('k', 'ohai %{name}', {name: undefined}), 'ohai [missing %{name} value]')
|
|
})
|
|
|
|
test('html safety: should not html-escape translations or interpolations by default', () => {
|
|
equal(
|
|
t('bar', 'these are some tags: <input> and %{another}', {another: '<img>'}),
|
|
'these are some tags: <input> and <img>'
|
|
)
|
|
})
|
|
|
|
test('html safety: should html-escape translations and interpolations if any interpolated values are htmlSafe', () => {
|
|
equal(
|
|
t('bar', "only one of these won't get escaped: <input>, %{a}, %{b} & %{c}", {
|
|
a: '<img>',
|
|
b: raw('<br>'),
|
|
c: '<hr>',
|
|
}),
|
|
'only one of these won't get escaped: <input>, <img>, <br> & <hr>'
|
|
)
|
|
})
|
|
|
|
test('wrappers: should auto-html-escape', () => {
|
|
equal(t('bar', '*2* > 1', {wrapper: '<b>$1</b>'}), '<b>2</b> > 1')
|
|
})
|
|
|
|
test('wrappers: should not escape already-escaped text', () => {
|
|
equal(
|
|
t('bar', '*%{input}* > 1', {input: raw('<input>'), wrapper: '<b>$1</b>'}),
|
|
'<b><input></b> > 1'
|
|
)
|
|
})
|
|
|
|
test('wrappers: should support multiple wrappers', () => {
|
|
equal(
|
|
t('bar', '*1 + 1* == **2**', {wrapper: {'*': '<i>$1</i>', '**': '<b>$1</b>'}}),
|
|
'<i>1 + 1</i> == <b>2</b>'
|
|
)
|
|
})
|
|
|
|
test('wrappers: should replace globally', () => {
|
|
equal(t('bar', '*1 + 1* == *2*', {wrapper: '<i>$1</i>'}), '<i>1 + 1</i> == <i>2</i>')
|
|
})
|
|
|
|
test('wrappers: should interpolate placeholders in wrappers', () => {
|
|
// this functionality is primarily useful in handlebars templates where
|
|
// wrappers are auto-generated ... in normal js you'd probably just
|
|
// manually concatenate it into your wrapper
|
|
equal(
|
|
t('bar', 'you need to *log in*', {wrapper: '<a href="%{url}">$1</a>', url: 'http://foo.bar'}),
|
|
'you need to <a href="http://foo.bar">log in</a>'
|
|
)
|
|
})
|
|
|
|
test('interpolate: should format numbers', () => {
|
|
equal(interpolate('user count: %{foo}', {foo: 1500}), 'user count: 1,500')
|
|
})
|
|
|
|
test('interpolate: should not format numbery strings', () => {
|
|
equal(interpolate('user count: %{foo}', {foo: '1500'}), 'user count: 1500')
|
|
})
|
|
|
|
test('interpolate: should not mutate the options', () => {
|
|
const options = {foo: 1500}
|
|
interpolate('user count: %{foo}', options)
|
|
equal(options.foo, 1500)
|
|
})
|
|
|
|
test('pluralize: should format the number', () => {
|
|
equal(t({one: '1 thing', other: '%{count} things'}, {count: 1500}), '1,500 things')
|
|
})
|
|
|
|
QUnit.module('I18n localize number', {
|
|
setup() {
|
|
this.delimiter = ' '
|
|
this.separator = ','
|
|
I18nStubber.pushFrame()
|
|
I18nStubber.stub('foo', {
|
|
'number.format.delimiter': this.delimiter,
|
|
'number.format.precision': 3,
|
|
'number.format.separator': this.separator,
|
|
'number.format.strip_insignificant_zeros': false,
|
|
})
|
|
return I18nStubber.setLocale('foo')
|
|
},
|
|
|
|
teardown() {
|
|
return I18nStubber.clear()
|
|
},
|
|
})
|
|
|
|
test('uses delimiter from local', function () {
|
|
equal(I18n.localizeNumber(1000), `1${this.delimiter}000`)
|
|
})
|
|
|
|
test('uses separator from local', function () {
|
|
equal(I18n.localizeNumber(1.2), `1${this.separator}2`)
|
|
})
|
|
|
|
test('uses precision from number if not specified', function () {
|
|
equal(I18n.localizeNumber(1.2345), `1${this.separator}2345`)
|
|
})
|
|
|
|
test('uses precision specified', function () {
|
|
equal(I18n.localizeNumber(1.2, {precision: 3}), `1${this.separator}200`)
|
|
equal(I18n.localizeNumber(1.2345, {precision: 3}), `1${this.separator}235`)
|
|
})
|
|
|
|
test('formats as a percentage if set to true', function () {
|
|
equal(I18n.localizeNumber(1.2, {percentage: true}), `1${this.separator}2%`)
|
|
})
|
|
|
|
test('allows stripping of 0s to be explicitly toggled along with precision', function () {
|
|
equal(
|
|
I18n.localizeNumber(1.12, {precision: 4, strip_insignificant_zeros: true}),
|
|
`1${this.separator}12`
|
|
)
|
|
})
|
|
|
|
test('does not have precision errors with large numbers', function () {
|
|
equal(
|
|
I18n.localizeNumber(50000000.12),
|
|
`50${this.delimiter}000${this.delimiter}000${this.separator}12`
|
|
)
|
|
})
|