mirror of
https://github.com/discourse/discourse.git
synced 2024-11-28 06:03:44 +08:00
89add4a4a2
moment.js uses a different naming conventions for locale files. E.g. "zh-zn" instead of "zh_ZN" and "nb" instead of "nb_NO" This change allows us to use the locale files without renaming which makes future upgrades of moment.js a lot easier.
189 lines
5.7 KiB
Ruby
189 lines
5.7 KiB
Ruby
require 'rails_helper'
|
|
require_dependency 'js_locale_helper'
|
|
|
|
describe JsLocaleHelper do
|
|
|
|
module StubLoadTranslations
|
|
def set_translations(locale, translations)
|
|
@loaded_translations ||= HashWithIndifferentAccess.new
|
|
@loaded_translations[locale] = translations
|
|
end
|
|
|
|
def clear_cache!
|
|
@loaded_translations = nil
|
|
@loaded_merges = nil
|
|
end
|
|
end
|
|
JsLocaleHelper.extend StubLoadTranslations
|
|
|
|
after do
|
|
JsLocaleHelper.clear_cache!
|
|
end
|
|
|
|
it 'should be able to generate translations' do
|
|
expect(JsLocaleHelper.output_locale('en').length).to be > 0
|
|
end
|
|
|
|
def setup_message_format(format)
|
|
@ctx = V8::Context.new
|
|
@ctx.eval('MessageFormat = {locale: {}};')
|
|
@ctx.load(Rails.root + 'lib/javascripts/locale/en.js')
|
|
compiled = JsLocaleHelper.compile_message_format('en', format)
|
|
@ctx.eval("var test = #{compiled}")
|
|
end
|
|
|
|
def localize(opts)
|
|
@ctx.eval("test(#{opts.to_json})")
|
|
end
|
|
|
|
it 'handles plurals' do
|
|
setup_message_format('{NUM_RESULTS, plural,
|
|
one {1 result}
|
|
other {# results}
|
|
}')
|
|
expect(localize(NUM_RESULTS: 1)).to eq('1 result')
|
|
expect(localize(NUM_RESULTS: 2)).to eq('2 results')
|
|
end
|
|
|
|
it 'handles double plurals' do
|
|
setup_message_format('{NUM_RESULTS, plural,
|
|
one {1 result}
|
|
other {# results}
|
|
} and {NUM_APPLES, plural,
|
|
one {1 apple}
|
|
other {# apples}
|
|
}')
|
|
|
|
|
|
expect(localize(NUM_RESULTS: 1, NUM_APPLES: 2)).to eq('1 result and 2 apples')
|
|
expect(localize(NUM_RESULTS: 2, NUM_APPLES: 1)).to eq('2 results and 1 apple')
|
|
end
|
|
|
|
it 'handles select' do
|
|
setup_message_format('{GENDER, select, male {He} female {She} other {They}} read a book')
|
|
expect(localize(GENDER: 'male')).to eq('He read a book')
|
|
expect(localize(GENDER: 'female')).to eq('She read a book')
|
|
expect(localize(GENDER: 'none')).to eq('They read a book')
|
|
end
|
|
|
|
it 'can strip out message formats' do
|
|
hash = {"a" => "b", "c" => { "d" => {"f_MF" => "bob"} }}
|
|
expect(JsLocaleHelper.strip_out_message_formats!(hash)).to eq({"c.d.f_MF" => "bob"})
|
|
expect(hash["c"]["d"]).to eq({})
|
|
end
|
|
|
|
it 'handles message format special keys' do
|
|
ctx = V8::Context.new
|
|
ctx.eval("I18n = {};")
|
|
|
|
JsLocaleHelper.set_translations 'en', {
|
|
"en" =>
|
|
{
|
|
"js" => {
|
|
"hello" => "world",
|
|
"test_MF" => "{HELLO} {COUNT, plural, one {1 duck} other {# ducks}}",
|
|
"error_MF" => "{{BLA}",
|
|
"simple_MF" => "{COUNT, plural, one {1} other {#}}"
|
|
}
|
|
}
|
|
}
|
|
|
|
ctx.eval(JsLocaleHelper.output_locale('en'))
|
|
|
|
expect(ctx.eval('I18n.translations["en"]["js"]["hello"]')).to eq("world")
|
|
expect(ctx.eval('I18n.translations["en"]["js"]["test_MF"]')).to eq(nil)
|
|
|
|
expect(ctx.eval('I18n.messageFormat("test_MF", { HELLO: "hi", COUNT: 3 })')).to eq("hi 3 ducks")
|
|
expect(ctx.eval('I18n.messageFormat("error_MF", { HELLO: "hi", COUNT: 3 })')).to match(/Invalid Format/)
|
|
expect(ctx.eval('I18n.messageFormat("missing", {})')).to match(/missing/)
|
|
expect(ctx.eval('I18n.messageFormat("simple_MF", {})')).to match(/COUNT/) # error
|
|
end
|
|
|
|
it 'load pluralizations rules before precompile' do
|
|
message = JsLocaleHelper.compile_message_format('ru', 'format')
|
|
expect(message).not_to match 'Plural Function not found'
|
|
end
|
|
|
|
it 'performs fallbacks to english if a translation is not available' do
|
|
JsLocaleHelper.set_translations 'en', {
|
|
"en" => {
|
|
"js" => {
|
|
"only_english" => "1-en",
|
|
"english_and_site" => "3-en",
|
|
"english_and_user" => "5-en",
|
|
"all_three" => "7-en",
|
|
}
|
|
}
|
|
}
|
|
JsLocaleHelper.set_translations 'ru', {
|
|
"ru" => {
|
|
"js" => {
|
|
"only_site" => "2-ru",
|
|
"english_and_site" => "3-ru",
|
|
"site_and_user" => "6-ru",
|
|
"all_three" => "7-ru",
|
|
}
|
|
}
|
|
}
|
|
JsLocaleHelper.set_translations 'uk', {
|
|
"uk" => {
|
|
"js" => {
|
|
"only_user" => "4-uk",
|
|
"english_and_user" => "5-uk",
|
|
"site_and_user" => "6-uk",
|
|
"all_three" => "7-uk",
|
|
}
|
|
}
|
|
}
|
|
|
|
expected = {
|
|
"none" => "[uk.js.none]",
|
|
"only_english" => "1-en",
|
|
"only_site" => "2-ru",
|
|
"english_and_site" => "3-ru",
|
|
"only_user" => "4-uk",
|
|
"english_and_user" => "5-uk",
|
|
"site_and_user" => "6-uk",
|
|
"all_three" => "7-uk",
|
|
}
|
|
|
|
SiteSetting.default_locale = 'ru'
|
|
I18n.locale = :uk
|
|
|
|
ctx = V8::Context.new
|
|
ctx.eval('var window = this;')
|
|
ctx.load(Rails.root + 'app/assets/javascripts/locales/i18n.js')
|
|
ctx.eval(JsLocaleHelper.output_locale(I18n.locale))
|
|
ctx.eval('I18n.defaultLocale = "ru";')
|
|
|
|
# Test - unneeded translations are not emitted
|
|
expect(ctx.eval('I18n.translations.en.js').keys).to eq(["only_english"])
|
|
expect(ctx.eval('I18n.translations.ru.js').keys).to eq(["only_site", "english_and_site"])
|
|
|
|
expected.each do |key, expect|
|
|
expect(ctx.eval("I18n.t(#{"js.#{key}".inspect})")).to eq(expect)
|
|
end
|
|
end
|
|
|
|
LocaleSiteSetting.values.each do |locale|
|
|
it "generates valid date helpers for #{locale[:value]} locale" do
|
|
js = JsLocaleHelper.output_locale(locale[:value])
|
|
ctx = V8::Context.new
|
|
ctx.eval('var window = this;')
|
|
ctx.load(Rails.root + 'app/assets/javascripts/locales/i18n.js')
|
|
ctx.eval(js)
|
|
end
|
|
|
|
it "finds moment.js locale file for #{locale[:value]}" do
|
|
content = JsLocaleHelper.moment_locale(locale[:value])
|
|
|
|
if (locale[:value] == 'en')
|
|
expect(content).to eq('')
|
|
else
|
|
expect(content).to_not eq('')
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|