i18n: vendor gem.
This commit is contained in:
parent
aaabb81fea
commit
5fb9c255a5
1
.gitignore
vendored
1
.gitignore
vendored
@ -38,6 +38,7 @@
|
||||
**/vendor/bundle-standalone/ruby/*/gems/backports-*/lib
|
||||
**/vendor/bundle-standalone/ruby/*/gems/minitest-*/lib
|
||||
**/vendor/bundle-standalone/ruby/*/gems/thread_safe-*/lib
|
||||
**/vendor/bundle-standalone/ruby/*/gems/i18n-*/lib/i18n/tests*
|
||||
|
||||
# Ignore rubocop dependencies we don't wish to vendor
|
||||
**/vendor/bundle-standalone/ruby/*/gems/ast-*/
|
||||
|
@ -4,7 +4,7 @@ ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'ruby'
|
||||
ruby_version = RbConfig::CONFIG["ruby_version"]
|
||||
path = File.expand_path('..', __FILE__)
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/concurrent-ruby-1.1.4/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/i18n-1.1.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/i18n-1.2.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/minitest-5.11.3/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/thread_safe-0.3.6/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/tzinfo-1.2.5/lib"
|
||||
|
@ -1,14 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module I18n
|
||||
module Tests
|
||||
autoload :Basics, 'i18n/tests/basics'
|
||||
autoload :Defaults, 'i18n/tests/defaults'
|
||||
autoload :Interpolation, 'i18n/tests/interpolation'
|
||||
autoload :Link, 'i18n/tests/link'
|
||||
autoload :Localization, 'i18n/tests/localization'
|
||||
autoload :Lookup, 'i18n/tests/lookup'
|
||||
autoload :Pluralization, 'i18n/tests/pluralization'
|
||||
autoload :Procs, 'i18n/tests/procs'
|
||||
end
|
||||
end
|
@ -1,60 +0,0 @@
|
||||
module I18n
|
||||
module Tests
|
||||
module Basics
|
||||
def teardown
|
||||
I18n.available_locales = nil
|
||||
end
|
||||
|
||||
test "available_locales returns the locales stored to the backend by default" do
|
||||
I18n.backend.store_translations('de', :foo => 'bar')
|
||||
I18n.backend.store_translations('en', :foo => 'foo')
|
||||
|
||||
assert I18n.available_locales.include?(:de)
|
||||
assert I18n.available_locales.include?(:en)
|
||||
end
|
||||
|
||||
test "available_locales can be set to something else independently from the actual locale data" do
|
||||
I18n.backend.store_translations('de', :foo => 'bar')
|
||||
I18n.backend.store_translations('en', :foo => 'foo')
|
||||
|
||||
I18n.available_locales = :foo
|
||||
assert_equal [:foo], I18n.available_locales
|
||||
|
||||
I18n.available_locales = [:foo, 'bar']
|
||||
assert_equal [:foo, :bar], I18n.available_locales
|
||||
|
||||
I18n.available_locales = nil
|
||||
assert I18n.available_locales.include?(:de)
|
||||
assert I18n.available_locales.include?(:en)
|
||||
end
|
||||
|
||||
test "available_locales memoizes when set explicitely" do
|
||||
I18n.backend.expects(:available_locales).never
|
||||
I18n.available_locales = [:foo]
|
||||
I18n.backend.store_translations('de', :bar => 'baz')
|
||||
I18n.reload!
|
||||
assert_equal [:foo], I18n.available_locales
|
||||
end
|
||||
|
||||
test "available_locales delegates to the backend when not set explicitely" do
|
||||
original_available_locales_value = I18n.backend.available_locales
|
||||
I18n.backend.expects(:available_locales).returns(original_available_locales_value).twice
|
||||
assert_equal I18n.backend.available_locales, I18n.available_locales
|
||||
end
|
||||
|
||||
test "exists? is implemented by the backend" do
|
||||
I18n.backend.store_translations(:foo, :bar => 'baz')
|
||||
assert I18n.exists?(:bar, :foo)
|
||||
end
|
||||
|
||||
test "storing a nil value as a translation removes it from the available locale data" do
|
||||
I18n.backend.store_translations(:en, :to_be_deleted => 'bar')
|
||||
assert_equal 'bar', I18n.t(:to_be_deleted, :default => 'baz')
|
||||
|
||||
I18n.cache_store.clear if I18n.respond_to?(:cache_store) && I18n.cache_store
|
||||
I18n.backend.store_translations(:en, :to_be_deleted => nil)
|
||||
assert_equal 'baz', I18n.t(:to_be_deleted, :default => 'baz')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,52 +0,0 @@
|
||||
# encoding: utf-8
|
||||
|
||||
module I18n
|
||||
module Tests
|
||||
module Defaults
|
||||
def setup
|
||||
super
|
||||
I18n.backend.store_translations(:en, :foo => { :bar => 'bar', :baz => 'baz' })
|
||||
end
|
||||
|
||||
test "defaults: given nil as a key it returns the given default" do
|
||||
assert_equal 'default', I18n.t(nil, :default => 'default')
|
||||
end
|
||||
|
||||
test "defaults: given a symbol as a default it translates the symbol" do
|
||||
assert_equal 'bar', I18n.t(nil, :default => :'foo.bar')
|
||||
end
|
||||
|
||||
test "defaults: given a symbol as a default and a scope it stays inside the scope when looking up the symbol" do
|
||||
assert_equal 'bar', I18n.t(:missing, :default => :bar, :scope => :foo)
|
||||
end
|
||||
|
||||
test "defaults: given an array as a default it returns the first match" do
|
||||
assert_equal 'bar', I18n.t(:does_not_exist, :default => [:does_not_exist_2, :'foo.bar'])
|
||||
end
|
||||
|
||||
test "defaults: given an array as a default with false it returns false" do
|
||||
assert_equal false, I18n.t(:does_not_exist, :default => [false])
|
||||
end
|
||||
|
||||
test "defaults: given false it returns false" do
|
||||
assert_equal false, I18n.t(:does_not_exist, :default => false)
|
||||
end
|
||||
|
||||
test "defaults: given nil it returns nil" do
|
||||
assert_nil I18n.t(:does_not_exist, :default => nil)
|
||||
end
|
||||
|
||||
test "defaults: given an array of missing keys it raises a MissingTranslationData exception" do
|
||||
assert_raise I18n::MissingTranslationData do
|
||||
I18n.t(:does_not_exist, :default => [:does_not_exist_2, :does_not_exist_3], :raise => true)
|
||||
end
|
||||
end
|
||||
|
||||
test "defaults: using a custom scope separator" do
|
||||
# data must have been stored using the custom separator when using the ActiveRecord backend
|
||||
I18n.backend.store_translations(:en, { :foo => { :bar => 'bar' } }, { :separator => '|' })
|
||||
assert_equal 'bar', I18n.t(nil, :default => :'foo|bar', :separator => '|')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,159 +0,0 @@
|
||||
# encoding: utf-8
|
||||
|
||||
module I18n
|
||||
module Tests
|
||||
module Interpolation
|
||||
# If no interpolation parameter is not given, I18n should not alter the string.
|
||||
# This behavior is due to three reasons:
|
||||
#
|
||||
# * Checking interpolation keys in all strings hits performance, badly;
|
||||
#
|
||||
# * This allows us to retrieve untouched values through I18n. For example
|
||||
# I could have a middleware that returns I18n lookup results in JSON
|
||||
# to be processed through Javascript. Leaving the keys untouched allows
|
||||
# the interpolation to happen at the javascript level;
|
||||
#
|
||||
# * Security concerns: if I allow users to translate a web site, they can
|
||||
# insert %{} in messages causing the I18n lookup to fail in every request.
|
||||
#
|
||||
test "interpolation: given no values it does not alter the string" do
|
||||
assert_equal 'Hi %{name}!', interpolate(:default => 'Hi %{name}!')
|
||||
end
|
||||
|
||||
test "interpolation: given values it interpolates them into the string" do
|
||||
assert_equal 'Hi David!', interpolate(:default => 'Hi %{name}!', :name => 'David')
|
||||
end
|
||||
|
||||
test "interpolation: given a nil value it still interpolates it into the string" do
|
||||
assert_equal 'Hi !', interpolate(:default => 'Hi %{name}!', :name => nil)
|
||||
end
|
||||
|
||||
test "interpolation: given a lambda as a value it calls it if the string contains the key" do
|
||||
assert_equal 'Hi David!', interpolate(:default => 'Hi %{name}!', :name => lambda { |*args| 'David' })
|
||||
end
|
||||
|
||||
test "interpolation: given a lambda as a value it does not call it if the string does not contain the key" do
|
||||
assert_nothing_raised { interpolate(:default => 'Hi!', :name => lambda { |*args| raise 'fail' }) }
|
||||
end
|
||||
|
||||
test "interpolation: given values but missing a key it raises I18n::MissingInterpolationArgument" do
|
||||
assert_raise(I18n::MissingInterpolationArgument) do
|
||||
interpolate(:default => '%{foo}', :bar => 'bar')
|
||||
end
|
||||
end
|
||||
|
||||
test "interpolation: it does not raise I18n::MissingInterpolationArgument for escaped variables" do
|
||||
assert_nothing_raised do
|
||||
assert_equal 'Barr %{foo}', interpolate(:default => '%{bar} %%{foo}', :bar => 'Barr')
|
||||
end
|
||||
end
|
||||
|
||||
test "interpolation: it does not change the original, stored translation string" do
|
||||
I18n.backend.store_translations(:en, :interpolate => 'Hi %{name}!')
|
||||
assert_equal 'Hi David!', interpolate(:interpolate, :name => 'David')
|
||||
assert_equal 'Hi Yehuda!', interpolate(:interpolate, :name => 'Yehuda')
|
||||
end
|
||||
|
||||
test "interpolation: given an array interpolates each element" do
|
||||
I18n.backend.store_translations(:en, :array_interpolate => ['Hi', 'Mr. %{name}', 'or sir %{name}'])
|
||||
assert_equal ['Hi', 'Mr. Bartuz', 'or sir Bartuz'], interpolate(:array_interpolate, :name => 'Bartuz')
|
||||
end
|
||||
|
||||
test "interpolation: given the translation is in utf-8 it still works" do
|
||||
assert_equal 'Häi David!', interpolate(:default => 'Häi %{name}!', :name => 'David')
|
||||
end
|
||||
|
||||
test "interpolation: given the value is in utf-8 it still works" do
|
||||
assert_equal 'Hi ゆきひろ!', interpolate(:default => 'Hi %{name}!', :name => 'ゆきひろ')
|
||||
end
|
||||
|
||||
test "interpolation: given the translation and the value are in utf-8 it still works" do
|
||||
assert_equal 'こんにちは、ゆきひろさん!', interpolate(:default => 'こんにちは、%{name}さん!', :name => 'ゆきひろ')
|
||||
end
|
||||
|
||||
if Object.const_defined?(:Encoding)
|
||||
test "interpolation: given a euc-jp translation and a utf-8 value it raises Encoding::CompatibilityError" do
|
||||
assert_raise(Encoding::CompatibilityError) do
|
||||
interpolate(:default => euc_jp('こんにちは、%{name}さん!'), :name => 'ゆきひろ')
|
||||
end
|
||||
end
|
||||
|
||||
test "interpolation: given a utf-8 translation and a euc-jp value it raises Encoding::CompatibilityError" do
|
||||
assert_raise(Encoding::CompatibilityError) do
|
||||
interpolate(:default => 'こんにちは、%{name}さん!', :name => euc_jp('ゆきひろ'))
|
||||
end
|
||||
end
|
||||
|
||||
test "interpolation: ASCII strings in the backend should be encoded to UTF8 if interpolation options are in UTF8" do
|
||||
I18n.backend.store_translations 'en', 'encoding' => ('%{who} let me go'.force_encoding("ASCII"))
|
||||
result = I18n.t 'encoding', :who => "måmmå miå"
|
||||
assert_equal Encoding::UTF_8, result.encoding
|
||||
end
|
||||
|
||||
test "interpolation: UTF8 strings in the backend are still returned as UTF8 with ASCII interpolation" do
|
||||
I18n.backend.store_translations 'en', 'encoding' => 'måmmå miå %{what}'
|
||||
result = I18n.t 'encoding', :what => 'let me go'.force_encoding("ASCII")
|
||||
assert_equal Encoding::UTF_8, result.encoding
|
||||
end
|
||||
|
||||
test "interpolation: UTF8 strings in the backend are still returned as UTF8 even with numbers interpolation" do
|
||||
I18n.backend.store_translations 'en', 'encoding' => '%{count} times: måmmå miå'
|
||||
result = I18n.t 'encoding', :count => 3
|
||||
assert_equal Encoding::UTF_8, result.encoding
|
||||
end
|
||||
end
|
||||
|
||||
test "interpolation: given a translations containing a reserved key it raises I18n::ReservedInterpolationKey" do
|
||||
assert_raise(I18n::ReservedInterpolationKey) { interpolate(:foo => :bar, :default => '%{exception_handler}') }
|
||||
assert_raise(I18n::ReservedInterpolationKey) { interpolate(:foo => :bar, :default => '%{default}') }
|
||||
assert_raise(I18n::ReservedInterpolationKey) { interpolate(:foo => :bar, :default => '%{separator}') }
|
||||
assert_raise(I18n::ReservedInterpolationKey) { interpolate(:foo => :bar, :default => '%{scope}') }
|
||||
end
|
||||
|
||||
test "interpolation: deep interpolation for default string" do
|
||||
assert_equal 'Hi %{name}!', interpolate(:default => 'Hi %{name}!', :deep_interpolation => true)
|
||||
end
|
||||
|
||||
test "interpolation: deep interpolation for interpolated string" do
|
||||
assert_equal 'Hi Ann!', interpolate(:default => 'Hi %{name}!', :name => 'Ann', :deep_interpolation => true)
|
||||
end
|
||||
|
||||
test "interpolation: deep interpolation for Hash" do
|
||||
people = { :people => { :ann => 'Ann is %{ann}', :john => 'John is %{john}' } }
|
||||
interpolated_people = { :people => { :ann => 'Ann is good', :john => 'John is big' } }
|
||||
assert_equal interpolated_people, interpolate(:default => people, :ann => 'good', :john => 'big', :deep_interpolation => true)
|
||||
end
|
||||
|
||||
test "interpolation: deep interpolation for Array" do
|
||||
people = { :people => ['Ann is %{ann}', 'John is %{john}'] }
|
||||
interpolated_people = { :people => ['Ann is good', 'John is big'] }
|
||||
assert_equal interpolated_people, interpolate(:default => people, :ann => 'good', :john => 'big', :deep_interpolation => true)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def capture(stream)
|
||||
begin
|
||||
stream = stream.to_s
|
||||
eval "$#{stream} = StringIO.new"
|
||||
yield
|
||||
result = eval("$#{stream}").string
|
||||
ensure
|
||||
eval("$#{stream} = #{stream.upcase}")
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
def euc_jp(string)
|
||||
string.encode!(Encoding::EUC_JP)
|
||||
end
|
||||
|
||||
def interpolate(*args)
|
||||
options = args.last.is_a?(Hash) ? args.pop : {}
|
||||
key = args.pop
|
||||
I18n.backend.translate('en', key, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,56 +0,0 @@
|
||||
# encoding: utf-8
|
||||
|
||||
module I18n
|
||||
module Tests
|
||||
module Link
|
||||
test "linked lookup: if a key resolves to a symbol it looks up the symbol" do
|
||||
I18n.backend.store_translations 'en', {
|
||||
:link => :linked,
|
||||
:linked => 'linked'
|
||||
}
|
||||
assert_equal 'linked', I18n.backend.translate('en', :link)
|
||||
end
|
||||
|
||||
test "linked lookup: if a key resolves to a dot-separated symbol it looks up the symbol" do
|
||||
I18n.backend.store_translations 'en', {
|
||||
:link => :"foo.linked",
|
||||
:foo => { :linked => 'linked' }
|
||||
}
|
||||
assert_equal('linked', I18n.backend.translate('en', :link))
|
||||
end
|
||||
|
||||
test "linked lookup: if a dot-separated key resolves to a symbol it looks up the symbol" do
|
||||
I18n.backend.store_translations 'en', {
|
||||
:foo => { :link => :linked },
|
||||
:linked => 'linked'
|
||||
}
|
||||
assert_equal('linked', I18n.backend.translate('en', :'foo.link'))
|
||||
end
|
||||
|
||||
test "linked lookup: if a dot-separated key resolves to a dot-separated symbol it looks up the symbol" do
|
||||
I18n.backend.store_translations 'en', {
|
||||
:foo => { :link => :"bar.linked" },
|
||||
:bar => { :linked => 'linked' }
|
||||
}
|
||||
assert_equal('linked', I18n.backend.translate('en', :'foo.link'))
|
||||
end
|
||||
|
||||
test "linked lookup: links always refer to the absolute key" do
|
||||
I18n.backend.store_translations 'en', {
|
||||
:foo => { :link => :linked, :linked => 'linked in foo' },
|
||||
:linked => 'linked absolutely'
|
||||
}
|
||||
assert_equal 'linked absolutely', I18n.backend.translate('en', :link, :scope => :foo)
|
||||
end
|
||||
|
||||
test "linked lookup: a link can resolve to a namespace in the middle of a dot-separated key" do
|
||||
I18n.backend.store_translations 'en', {
|
||||
:activemodel => { :errors => { :messages => { :blank => "can't be blank" } } },
|
||||
:activerecord => { :errors => { :messages => :"activemodel.errors.messages" } }
|
||||
}
|
||||
assert_equal "can't be blank", I18n.t(:"activerecord.errors.messages.blank")
|
||||
assert_equal "can't be blank", I18n.t(:"activerecord.errors.messages.blank")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,19 +0,0 @@
|
||||
module I18n
|
||||
module Tests
|
||||
module Localization
|
||||
autoload :Date, 'i18n/tests/localization/date'
|
||||
autoload :DateTime, 'i18n/tests/localization/date_time'
|
||||
autoload :Time, 'i18n/tests/localization/time'
|
||||
autoload :Procs, 'i18n/tests/localization/procs'
|
||||
|
||||
def self.included(base)
|
||||
base.class_eval do
|
||||
include I18n::Tests::Localization::Date
|
||||
include I18n::Tests::Localization::DateTime
|
||||
include I18n::Tests::Localization::Procs
|
||||
include I18n::Tests::Localization::Time
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,95 +0,0 @@
|
||||
# encoding: utf-8
|
||||
|
||||
module I18n
|
||||
module Tests
|
||||
module Localization
|
||||
module Date
|
||||
def setup
|
||||
super
|
||||
setup_date_translations
|
||||
@date = ::Date.new(2008, 3, 1)
|
||||
end
|
||||
|
||||
test "localize Date: given the short format it uses it" do
|
||||
# TODO should be Mrz, shouldn't it?
|
||||
assert_equal '01. Mar', I18n.l(@date, :format => :short, :locale => :de)
|
||||
end
|
||||
|
||||
test "localize Date: given the long format it uses it" do
|
||||
assert_equal '01. März 2008', I18n.l(@date, :format => :long, :locale => :de)
|
||||
end
|
||||
|
||||
test "localize Date: given the default format it uses it" do
|
||||
assert_equal '01.03.2008', I18n.l(@date, :format => :default, :locale => :de)
|
||||
end
|
||||
|
||||
test "localize Date: given a day name format it returns the correct day name" do
|
||||
assert_equal 'Samstag', I18n.l(@date, :format => '%A', :locale => :de)
|
||||
end
|
||||
|
||||
test "localize Date: given an abbreviated day name format it returns the correct abbreviated day name" do
|
||||
assert_equal 'Sa', I18n.l(@date, :format => '%a', :locale => :de)
|
||||
end
|
||||
|
||||
test "localize Date: given a month name format it returns the correct month name" do
|
||||
assert_equal 'März', I18n.l(@date, :format => '%B', :locale => :de)
|
||||
end
|
||||
|
||||
test "localize Date: given an abbreviated month name format it returns the correct abbreviated month name" do
|
||||
# TODO should be Mrz, shouldn't it?
|
||||
assert_equal 'Mar', I18n.l(@date, :format => '%b', :locale => :de)
|
||||
end
|
||||
|
||||
test "localize Date: given an unknown format it does not fail" do
|
||||
assert_nothing_raised { I18n.l(@date, :format => '%x') }
|
||||
end
|
||||
|
||||
test "localize Date: does not modify the options hash" do
|
||||
options = { :format => '%b', :locale => :de }
|
||||
assert_equal 'Mar', I18n.l(@date, options)
|
||||
assert_equal({ :format => '%b', :locale => :de }, options)
|
||||
assert_nothing_raised { I18n.l(@date, options.freeze) }
|
||||
end
|
||||
|
||||
test "localize Date: given nil with default value it returns default" do
|
||||
assert_equal 'default', I18n.l(nil, :default => 'default')
|
||||
end
|
||||
|
||||
test "localize Date: given nil it raises I18n::ArgumentError" do
|
||||
assert_raise(I18n::ArgumentError) { I18n.l(nil) }
|
||||
end
|
||||
|
||||
test "localize Date: given a plain Object it raises I18n::ArgumentError" do
|
||||
assert_raise(I18n::ArgumentError) { I18n.l(Object.new) }
|
||||
end
|
||||
|
||||
test "localize Date: given a format is missing it raises I18n::MissingTranslationData" do
|
||||
assert_raise(I18n::MissingTranslationData) { I18n.l(@date, :format => :missing) }
|
||||
end
|
||||
|
||||
test "localize Date: it does not alter the format string" do
|
||||
assert_equal '01. Februar 2009', I18n.l(::Date.parse('2009-02-01'), :format => :long, :locale => :de)
|
||||
assert_equal '01. Oktober 2009', I18n.l(::Date.parse('2009-10-01'), :format => :long, :locale => :de)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def setup_date_translations
|
||||
I18n.backend.store_translations :de, {
|
||||
:date => {
|
||||
:formats => {
|
||||
:default => "%d.%m.%Y",
|
||||
:short => "%d. %b",
|
||||
:long => "%d. %B %Y",
|
||||
},
|
||||
:day_names => %w(Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag),
|
||||
:abbr_day_names => %w(So Mo Di Mi Do Fr Sa),
|
||||
:month_names => %w(Januar Februar März April Mai Juni Juli August September Oktober November Dezember).unshift(nil),
|
||||
:abbr_month_names => %w(Jan Feb Mar Apr Mai Jun Jul Aug Sep Okt Nov Dez).unshift(nil)
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,82 +0,0 @@
|
||||
# encoding: utf-8
|
||||
|
||||
module I18n
|
||||
module Tests
|
||||
module Localization
|
||||
module DateTime
|
||||
def setup
|
||||
super
|
||||
setup_datetime_translations
|
||||
@datetime = ::DateTime.new(2008, 3, 1, 6)
|
||||
@other_datetime = ::DateTime.new(2008, 3, 1, 18)
|
||||
end
|
||||
|
||||
test "localize DateTime: given the short format it uses it" do
|
||||
# TODO should be Mrz, shouldn't it?
|
||||
assert_equal '01. Mar 06:00', I18n.l(@datetime, :format => :short, :locale => :de)
|
||||
end
|
||||
|
||||
test "localize DateTime: given the long format it uses it" do
|
||||
assert_equal '01. März 2008 06:00', I18n.l(@datetime, :format => :long, :locale => :de)
|
||||
end
|
||||
|
||||
test "localize DateTime: given the default format it uses it" do
|
||||
# TODO should be Mrz, shouldn't it?
|
||||
assert_equal 'Sa, 01. Mar 2008 06:00:00 +0000', I18n.l(@datetime, :format => :default, :locale => :de)
|
||||
end
|
||||
|
||||
test "localize DateTime: given a day name format it returns the correct day name" do
|
||||
assert_equal 'Samstag', I18n.l(@datetime, :format => '%A', :locale => :de)
|
||||
end
|
||||
|
||||
test "localize DateTime: given an abbreviated day name format it returns the correct abbreviated day name" do
|
||||
assert_equal 'Sa', I18n.l(@datetime, :format => '%a', :locale => :de)
|
||||
end
|
||||
|
||||
test "localize DateTime: given a month name format it returns the correct month name" do
|
||||
assert_equal 'März', I18n.l(@datetime, :format => '%B', :locale => :de)
|
||||
end
|
||||
|
||||
test "localize DateTime: given an abbreviated month name format it returns the correct abbreviated month name" do
|
||||
# TODO should be Mrz, shouldn't it?
|
||||
assert_equal 'Mar', I18n.l(@datetime, :format => '%b', :locale => :de)
|
||||
end
|
||||
|
||||
test "localize DateTime: given a meridian indicator format it returns the correct meridian indicator" do
|
||||
assert_equal 'AM', I18n.l(@datetime, :format => '%p', :locale => :de)
|
||||
assert_equal 'PM', I18n.l(@other_datetime, :format => '%p', :locale => :de)
|
||||
end
|
||||
|
||||
test "localize DateTime: given a meridian indicator format it returns the correct meridian indicator in downcase" do
|
||||
assert_equal 'am', I18n.l(@datetime, :format => '%P', :locale => :de)
|
||||
assert_equal 'pm', I18n.l(@other_datetime, :format => '%P', :locale => :de)
|
||||
end
|
||||
|
||||
test "localize DateTime: given an unknown format it does not fail" do
|
||||
assert_nothing_raised { I18n.l(@datetime, :format => '%x') }
|
||||
end
|
||||
|
||||
test "localize DateTime: given a format is missing it raises I18n::MissingTranslationData" do
|
||||
assert_raise(I18n::MissingTranslationData) { I18n.l(@datetime, :format => :missing) }
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def setup_datetime_translations
|
||||
# time translations might have been set up in Tests::Api::Localization::Time
|
||||
I18n.backend.store_translations :de, {
|
||||
:time => {
|
||||
:formats => {
|
||||
:default => "%a, %d. %b %Y %H:%M:%S %z",
|
||||
:short => "%d. %b %H:%M",
|
||||
:long => "%d. %B %Y %H:%M"
|
||||
},
|
||||
:am => 'am',
|
||||
:pm => 'pm'
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,116 +0,0 @@
|
||||
# encoding: utf-8
|
||||
|
||||
module I18n
|
||||
module Tests
|
||||
module Localization
|
||||
module Procs
|
||||
test "localize: using day names from lambdas" do
|
||||
setup_time_proc_translations
|
||||
time = ::Time.utc(2008, 3, 1, 6, 0)
|
||||
assert_match(/Суббота/, I18n.l(time, :format => "%A, %d %B", :locale => :ru))
|
||||
assert_match(/суббота/, I18n.l(time, :format => "%d %B (%A)", :locale => :ru))
|
||||
end
|
||||
|
||||
test "localize: using month names from lambdas" do
|
||||
setup_time_proc_translations
|
||||
time = ::Time.utc(2008, 3, 1, 6, 0)
|
||||
assert_match(/марта/, I18n.l(time, :format => "%d %B %Y", :locale => :ru))
|
||||
assert_match(/Март /, I18n.l(time, :format => "%B %Y", :locale => :ru))
|
||||
end
|
||||
|
||||
test "localize: using abbreviated day names from lambdas" do
|
||||
setup_time_proc_translations
|
||||
time = ::Time.utc(2008, 3, 1, 6, 0)
|
||||
assert_match(/марта/, I18n.l(time, :format => "%d %b %Y", :locale => :ru))
|
||||
assert_match(/март /, I18n.l(time, :format => "%b %Y", :locale => :ru))
|
||||
end
|
||||
|
||||
test "localize Date: given a format that resolves to a Proc it calls the Proc with the object" do
|
||||
setup_time_proc_translations
|
||||
date = ::Date.new(2008, 3, 1)
|
||||
assert_equal '[Sat, 01 Mar 2008, {}]', I18n.l(date, :format => :proc, :locale => :ru)
|
||||
end
|
||||
|
||||
test "localize Date: given a format that resolves to a Proc it calls the Proc with the object and extra options" do
|
||||
setup_time_proc_translations
|
||||
date = ::Date.new(2008, 3, 1)
|
||||
assert_equal '[Sat, 01 Mar 2008, {:foo=>"foo"}]', I18n.l(date, :format => :proc, :foo => 'foo', :locale => :ru)
|
||||
end
|
||||
|
||||
test "localize DateTime: given a format that resolves to a Proc it calls the Proc with the object" do
|
||||
setup_time_proc_translations
|
||||
datetime = ::DateTime.new(2008, 3, 1, 6)
|
||||
assert_equal '[Sat, 01 Mar 2008 06:00:00 +00:00, {}]', I18n.l(datetime, :format => :proc, :locale => :ru)
|
||||
end
|
||||
|
||||
test "localize DateTime: given a format that resolves to a Proc it calls the Proc with the object and extra options" do
|
||||
setup_time_proc_translations
|
||||
datetime = ::DateTime.new(2008, 3, 1, 6)
|
||||
assert_equal '[Sat, 01 Mar 2008 06:00:00 +00:00, {:foo=>"foo"}]', I18n.l(datetime, :format => :proc, :foo => 'foo', :locale => :ru)
|
||||
end
|
||||
|
||||
test "localize Time: given a format that resolves to a Proc it calls the Proc with the object" do
|
||||
setup_time_proc_translations
|
||||
time = ::Time.utc(2008, 3, 1, 6, 0)
|
||||
assert_equal I18n::Tests::Localization::Procs.inspect_args([time, {}]), I18n.l(time, :format => :proc, :locale => :ru)
|
||||
end
|
||||
|
||||
test "localize Time: given a format that resolves to a Proc it calls the Proc with the object and extra options" do
|
||||
setup_time_proc_translations
|
||||
time = ::Time.utc(2008, 3, 1, 6, 0)
|
||||
options = { :foo => 'foo' }
|
||||
assert_equal I18n::Tests::Localization::Procs.inspect_args([time, options]), I18n.l(time, options.merge(:format => :proc, :locale => :ru))
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def self.inspect_args(args)
|
||||
args = args.map do |arg|
|
||||
case arg
|
||||
when ::Time, ::DateTime
|
||||
arg.strftime('%a, %d %b %Y %H:%M:%S %Z').sub('+0000', '+00:00')
|
||||
when ::Date
|
||||
arg.strftime('%a, %d %b %Y')
|
||||
when Hash
|
||||
arg.delete(:fallback_in_progress)
|
||||
arg.inspect
|
||||
else
|
||||
arg.inspect
|
||||
end
|
||||
end
|
||||
"[#{args.join(', ')}]"
|
||||
end
|
||||
|
||||
def setup_time_proc_translations
|
||||
I18n.backend.store_translations :ru, {
|
||||
:time => {
|
||||
:formats => {
|
||||
:proc => lambda { |*args| I18n::Tests::Localization::Procs.inspect_args(args) }
|
||||
}
|
||||
},
|
||||
:date => {
|
||||
:formats => {
|
||||
:proc => lambda { |*args| I18n::Tests::Localization::Procs.inspect_args(args) }
|
||||
},
|
||||
:'day_names' => lambda { |key, options|
|
||||
(options[:format] =~ /^%A/) ?
|
||||
%w(Воскресенье Понедельник Вторник Среда Четверг Пятница Суббота) :
|
||||
%w(воскресенье понедельник вторник среда четверг пятница суббота)
|
||||
},
|
||||
:'month_names' => lambda { |key, options|
|
||||
(options[:format] =~ /(%d|%e)(\s*)?(%B)/) ?
|
||||
%w(января февраля марта апреля мая июня июля августа сентября октября ноября декабря).unshift(nil) :
|
||||
%w(Январь Февраль Март Апрель Май Июнь Июль Август Сентябрь Октябрь Ноябрь Декабрь).unshift(nil)
|
||||
},
|
||||
:'abbr_month_names' => lambda { |key, options|
|
||||
(options[:format] =~ /(%d|%e)(\s*)(%b)/) ?
|
||||
%w(янв. февр. марта апр. мая июня июля авг. сент. окт. нояб. дек.).unshift(nil) :
|
||||
%w(янв. февр. март апр. май июнь июль авг. сент. окт. нояб. дек.).unshift(nil)
|
||||
},
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,81 +0,0 @@
|
||||
# encoding: utf-8
|
||||
|
||||
module I18n
|
||||
module Tests
|
||||
module Localization
|
||||
module Time
|
||||
def setup
|
||||
super
|
||||
setup_time_translations
|
||||
@time = ::Time.utc(2008, 3, 1, 6, 0)
|
||||
@other_time = ::Time.utc(2008, 3, 1, 18, 0)
|
||||
end
|
||||
|
||||
test "localize Time: given the short format it uses it" do
|
||||
# TODO should be Mrz, shouldn't it?
|
||||
assert_equal '01. Mar 06:00', I18n.l(@time, :format => :short, :locale => :de)
|
||||
end
|
||||
|
||||
test "localize Time: given the long format it uses it" do
|
||||
assert_equal '01. März 2008 06:00', I18n.l(@time, :format => :long, :locale => :de)
|
||||
end
|
||||
|
||||
# TODO Seems to break on Windows because ENV['TZ'] is ignored. What's a better way to do this?
|
||||
# def test_localize_given_the_default_format_it_uses_it
|
||||
# assert_equal 'Sa, 01. Mar 2008 06:00:00 +0000', I18n.l(@time, :format => :default, :locale => :de)
|
||||
# end
|
||||
|
||||
test "localize Time: given a day name format it returns the correct day name" do
|
||||
assert_equal 'Samstag', I18n.l(@time, :format => '%A', :locale => :de)
|
||||
end
|
||||
|
||||
test "localize Time: given an abbreviated day name format it returns the correct abbreviated day name" do
|
||||
assert_equal 'Sa', I18n.l(@time, :format => '%a', :locale => :de)
|
||||
end
|
||||
|
||||
test "localize Time: given a month name format it returns the correct month name" do
|
||||
assert_equal 'März', I18n.l(@time, :format => '%B', :locale => :de)
|
||||
end
|
||||
|
||||
test "localize Time: given an abbreviated month name format it returns the correct abbreviated month name" do
|
||||
# TODO should be Mrz, shouldn't it?
|
||||
assert_equal 'Mar', I18n.l(@time, :format => '%b', :locale => :de)
|
||||
end
|
||||
|
||||
test "localize Time: given a meridian indicator format it returns the correct meridian indicator" do
|
||||
assert_equal 'AM', I18n.l(@time, :format => '%p', :locale => :de)
|
||||
assert_equal 'PM', I18n.l(@other_time, :format => '%p', :locale => :de)
|
||||
end
|
||||
|
||||
test "localize Time: given a meridian indicator format it returns the correct meridian indicator in upcase" do
|
||||
assert_equal 'am', I18n.l(@time, :format => '%P', :locale => :de)
|
||||
assert_equal 'pm', I18n.l(@other_time, :format => '%P', :locale => :de)
|
||||
end
|
||||
|
||||
test "localize Time: given an unknown format it does not fail" do
|
||||
assert_nothing_raised { I18n.l(@time, :format => '%x') }
|
||||
end
|
||||
|
||||
test "localize Time: given a format is missing it raises I18n::MissingTranslationData" do
|
||||
assert_raise(I18n::MissingTranslationData) { I18n.l(@time, :format => :missing) }
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def setup_time_translations
|
||||
I18n.backend.store_translations :de, {
|
||||
:time => {
|
||||
:formats => {
|
||||
:default => "%a, %d. %b %Y %H:%M:%S %z",
|
||||
:short => "%d. %b %H:%M",
|
||||
:long => "%d. %B %Y %H:%M",
|
||||
},
|
||||
:am => 'am',
|
||||
:pm => 'pm'
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,81 +0,0 @@
|
||||
# encoding: utf-8
|
||||
|
||||
module I18n
|
||||
module Tests
|
||||
module Lookup
|
||||
def setup
|
||||
super
|
||||
I18n.backend.store_translations(:en, :foo => { :bar => 'bar', :baz => 'baz' }, :falsy => false, :truthy => true,
|
||||
:string => "a", :array => %w(a b c), :hash => { "a" => "b" })
|
||||
end
|
||||
|
||||
test "lookup: it returns a string" do
|
||||
assert_equal("a", I18n.t(:string))
|
||||
end
|
||||
|
||||
test "lookup: it returns hash" do
|
||||
assert_equal({ :a => "b" }, I18n.t(:hash))
|
||||
end
|
||||
|
||||
test "lookup: it returns an array" do
|
||||
assert_equal(%w(a b c), I18n.t(:array))
|
||||
end
|
||||
|
||||
test "lookup: it returns a native true" do
|
||||
assert I18n.t(:truthy) === true
|
||||
end
|
||||
|
||||
test "lookup: it returns a native false" do
|
||||
assert I18n.t(:falsy) === false
|
||||
end
|
||||
|
||||
test "lookup: given a missing key, no default and no raise option it returns an error message" do
|
||||
assert_equal "translation missing: en.missing", I18n.t(:missing)
|
||||
end
|
||||
|
||||
test "lookup: given a missing key, no default and the raise option it raises MissingTranslationData" do
|
||||
assert_raise(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
|
||||
end
|
||||
|
||||
test "lookup: does not raise an exception if no translation data is present for the given locale" do
|
||||
assert_nothing_raised { I18n.t(:foo, :locale => :xx) }
|
||||
end
|
||||
|
||||
test "lookup: does not modify the options hash" do
|
||||
options = {}
|
||||
assert_equal "a", I18n.t(:string, options)
|
||||
assert_equal({}, options)
|
||||
assert_nothing_raised { I18n.t(:string, options.freeze) }
|
||||
end
|
||||
|
||||
test "lookup: given an array of keys it translates all of them" do
|
||||
assert_equal %w(bar baz), I18n.t([:bar, :baz], :scope => [:foo])
|
||||
end
|
||||
|
||||
test "lookup: using a custom scope separator" do
|
||||
# data must have been stored using the custom separator when using the ActiveRecord backend
|
||||
I18n.backend.store_translations(:en, { :foo => { :bar => 'bar' } }, { :separator => '|' })
|
||||
assert_equal 'bar', I18n.t('foo|bar', :separator => '|')
|
||||
end
|
||||
|
||||
# In fact it probably *should* fail but Rails currently relies on using the default locale instead.
|
||||
# So we'll stick to this for now until we get it fixed in Rails.
|
||||
test "lookup: given nil as a locale it does not raise but use the default locale" do
|
||||
# assert_raise(I18n::InvalidLocale) { I18n.t(:bar, :locale => nil) }
|
||||
assert_nothing_raised { I18n.t(:bar, :locale => nil) }
|
||||
end
|
||||
|
||||
test "lookup: a resulting String is not frozen" do
|
||||
assert !I18n.t(:string).frozen?
|
||||
end
|
||||
|
||||
test "lookup: a resulting Array is not frozen" do
|
||||
assert !I18n.t(:array).frozen?
|
||||
end
|
||||
|
||||
test "lookup: a resulting Hash is not frozen" do
|
||||
assert !I18n.t(:hash).frozen?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,35 +0,0 @@
|
||||
# encoding: utf-8
|
||||
|
||||
module I18n
|
||||
module Tests
|
||||
module Pluralization
|
||||
test "pluralization: given 0 it returns the :zero translation if it is defined" do
|
||||
assert_equal 'zero', I18n.t(:default => { :zero => 'zero' }, :count => 0)
|
||||
end
|
||||
|
||||
test "pluralization: given 0 it returns the :other translation if :zero is not defined" do
|
||||
assert_equal 'bars', I18n.t(:default => { :other => 'bars' }, :count => 0)
|
||||
end
|
||||
|
||||
test "pluralization: given 1 it returns the singular translation" do
|
||||
assert_equal 'bar', I18n.t(:default => { :one => 'bar' }, :count => 1)
|
||||
end
|
||||
|
||||
test "pluralization: given 2 it returns the :other translation" do
|
||||
assert_equal 'bars', I18n.t(:default => { :other => 'bars' }, :count => 2)
|
||||
end
|
||||
|
||||
test "pluralization: given 3 it returns the :other translation" do
|
||||
assert_equal 'bars', I18n.t(:default => { :other => 'bars' }, :count => 3)
|
||||
end
|
||||
|
||||
test "pluralization: given nil it returns the whole entry" do
|
||||
assert_equal({ :one => 'bar' }, I18n.t(:default => { :one => 'bar' }, :count => nil))
|
||||
end
|
||||
|
||||
test "pluralization: given incomplete pluralization data it raises I18n::InvalidPluralizationData" do
|
||||
assert_raise(I18n::InvalidPluralizationData) { I18n.t(:default => { :one => 'bar' }, :count => 2) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,55 +0,0 @@
|
||||
# encoding: utf-8
|
||||
|
||||
module I18n
|
||||
module Tests
|
||||
module Procs
|
||||
test "lookup: given a translation is a proc it calls the proc with the key and interpolation values" do
|
||||
I18n.backend.store_translations(:en, :a_lambda => lambda { |*args| I18n::Tests::Procs.filter_args(*args) })
|
||||
assert_equal '[:a_lambda, {:foo=>"foo"}]', I18n.t(:a_lambda, :foo => 'foo')
|
||||
end
|
||||
|
||||
test "defaults: given a default is a Proc it calls it with the key and interpolation values" do
|
||||
proc = lambda { |*args| I18n::Tests::Procs.filter_args(*args) }
|
||||
assert_equal '[nil, {:foo=>"foo"}]', I18n.t(nil, :default => proc, :foo => 'foo')
|
||||
end
|
||||
|
||||
test "defaults: given a default is a key that resolves to a Proc it calls it with the key and interpolation values" do
|
||||
the_lambda = lambda { |*args| I18n::Tests::Procs.filter_args(*args) }
|
||||
I18n.backend.store_translations(:en, :a_lambda => the_lambda)
|
||||
assert_equal '[:a_lambda, {:foo=>"foo"}]', I18n.t(nil, :default => :a_lambda, :foo => 'foo')
|
||||
assert_equal '[:a_lambda, {:foo=>"foo"}]', I18n.t(nil, :default => [nil, :a_lambda], :foo => 'foo')
|
||||
end
|
||||
|
||||
test "interpolation: given an interpolation value is a lambda it calls it with key and values before interpolating it" do
|
||||
proc = lambda { |*args| I18n::Tests::Procs.filter_args(*args) }
|
||||
assert_match %r(\[\{:foo=>#<Proc.*>\}\]), I18n.t(nil, :default => '%{foo}', :foo => proc)
|
||||
end
|
||||
|
||||
test "interpolation: given a key resolves to a Proc that returns a string then interpolation still works" do
|
||||
proc = lambda { |*args| "%{foo}: " + I18n::Tests::Procs.filter_args(*args) }
|
||||
assert_equal 'foo: [nil, {:foo=>"foo"}]', I18n.t(nil, :default => proc, :foo => 'foo')
|
||||
end
|
||||
|
||||
test "pluralization: given a key resolves to a Proc that returns valid data then pluralization still works" do
|
||||
proc = lambda { |*args| { :zero => 'zero', :one => 'one', :other => 'other' } }
|
||||
assert_equal 'zero', I18n.t(:default => proc, :count => 0)
|
||||
assert_equal 'one', I18n.t(:default => proc, :count => 1)
|
||||
assert_equal 'other', I18n.t(:default => proc, :count => 2)
|
||||
end
|
||||
|
||||
test "lookup: given the option :resolve => false was passed it does not resolve proc translations" do
|
||||
I18n.backend.store_translations(:en, :a_lambda => lambda { |*args| I18n::Tests::Procs.filter_args(*args) })
|
||||
assert_equal Proc, I18n.t(:a_lambda, :resolve => false).class
|
||||
end
|
||||
|
||||
test "lookup: given the option :resolve => false was passed it does not resolve proc default" do
|
||||
assert_equal Proc, I18n.t(nil, :default => lambda { |*args| I18n::Tests::Procs.filter_args(*args) }, :resolve => false).class
|
||||
end
|
||||
|
||||
|
||||
def self.filter_args(*args)
|
||||
args.map {|arg| arg.delete(:fallback_in_progress) if arg.is_a?(Hash) ; arg }.inspect
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -5,6 +5,7 @@ module I18n
|
||||
autoload :Base, 'i18n/backend/base'
|
||||
autoload :InterpolationCompiler, 'i18n/backend/interpolation_compiler'
|
||||
autoload :Cache, 'i18n/backend/cache'
|
||||
autoload :CacheFile, 'i18n/backend/cache_file'
|
||||
autoload :Cascade, 'i18n/backend/cascade'
|
||||
autoload :Chain, 'i18n/backend/chain'
|
||||
autoload :Fallbacks, 'i18n/backend/fallbacks'
|
@ -1,6 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'yaml'
|
||||
require 'json'
|
||||
require 'i18n/core_ext/hash'
|
||||
|
||||
module I18n
|
||||
@ -9,7 +10,7 @@ module I18n
|
||||
include I18n::Backend::Transliterator
|
||||
|
||||
# Accepts a list of paths to translation files. Loads translations from
|
||||
# plain Ruby (*.rb) or YAML files (*.yml). See #load_rb and #load_yml
|
||||
# plain Ruby (*.rb), YAML files (*.yml), or JSON files (*.json). See #load_rb, #load_yml, and #load_json
|
||||
# for details.
|
||||
def load_translations(*filenames)
|
||||
filenames = I18n.load_path if filenames.empty?
|
||||
@ -235,6 +236,16 @@ module I18n
|
||||
end
|
||||
alias_method :load_yaml, :load_yml
|
||||
|
||||
# Loads a JSON translations file. The data must have locales as
|
||||
# toplevel keys.
|
||||
def load_json(filename)
|
||||
begin
|
||||
::JSON.parse(File.read(filename))
|
||||
rescue TypeError, StandardError => e
|
||||
raise InvalidLocaleData.new(filename, e.inspect)
|
||||
end
|
||||
end
|
||||
|
||||
def translate_localization_format(locale, object, format, options)
|
||||
format.to_s.gsub(/%[aAbBpP]/) do |match|
|
||||
case match
|
@ -0,0 +1,36 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'digest/sha2'
|
||||
|
||||
module I18n
|
||||
module Backend
|
||||
# Overwrites the Base load_file method to cache loaded file contents.
|
||||
module CacheFile
|
||||
# Optionally provide path_roots array to normalize filename paths,
|
||||
# to make the cached i18n data portable across environments.
|
||||
attr_accessor :path_roots
|
||||
|
||||
protected
|
||||
|
||||
# Track loaded translation files in the `i18n.load_file` scope,
|
||||
# and skip loading the file if its contents are still up-to-date.
|
||||
def load_file(filename)
|
||||
initialized = !respond_to?(:initialized?) || initialized?
|
||||
key = I18n::Backend::Flatten.escape_default_separator(normalized_path(filename))
|
||||
old_mtime, old_digest = initialized && lookup(:i18n, key, :load_file)
|
||||
return if (mtime = File.mtime(filename).to_i) == old_mtime ||
|
||||
(digest = Digest::SHA2.file(filename).hexdigest) == old_digest
|
||||
super
|
||||
store_translations(:i18n, load_file: { key => [mtime, digest] })
|
||||
end
|
||||
|
||||
# Translate absolute filename to relative path for i18n key.
|
||||
def normalized_path(file)
|
||||
return file unless path_roots
|
||||
path = path_roots.find(&file.method(:start_with?)) ||
|
||||
raise(InvalidLocaleData.new(file, 'outside expected path roots'))
|
||||
file.sub(path, path_roots.index(path).to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -26,6 +26,15 @@ module I18n
|
||||
self.backends = backends
|
||||
end
|
||||
|
||||
def initialized?
|
||||
backends.all? do |backend|
|
||||
backend.instance_eval do
|
||||
return false unless initialized?
|
||||
end
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def reload!
|
||||
backends.each { |backend| backend.reload! }
|
||||
end
|
||||
@ -74,6 +83,19 @@ module I18n
|
||||
end
|
||||
|
||||
protected
|
||||
def init_translations
|
||||
backends.each do |backend|
|
||||
backend.send(:init_translations)
|
||||
end
|
||||
end
|
||||
|
||||
def translations
|
||||
backends.first.instance_eval do
|
||||
init_translations unless initialized?
|
||||
translations
|
||||
end
|
||||
end
|
||||
|
||||
def namespace_lookup?(result, options)
|
||||
result.is_a?(Hash) && !options.has_key?(:count)
|
||||
end
|
@ -76,6 +76,10 @@ module I18n
|
||||
@store, @subtrees = store, subtrees
|
||||
end
|
||||
|
||||
def initialized?
|
||||
!@store.nil?
|
||||
end
|
||||
|
||||
def store_translations(locale, data, options = EMPTY_HASH)
|
||||
escape = options.fetch(:escape, true)
|
||||
flatten_translations(locale, data, escape, @subtrees).each do |key, value|
|
||||
@ -105,6 +109,26 @@ module I18n
|
||||
|
||||
protected
|
||||
|
||||
# Queries the translations from the key-value store and converts
|
||||
# them into a hash such as the one returned from loading the
|
||||
# haml files
|
||||
def translations
|
||||
@translations = @store.keys.clone.map do |main_key|
|
||||
main_value = JSON.decode(@store[main_key])
|
||||
main_key.to_s.split(".").reverse.inject(main_value) do |value, key|
|
||||
{key.to_sym => value}
|
||||
end
|
||||
end.inject{|hash, elem| hash.deep_merge!(elem)}.deep_symbolize_keys
|
||||
end
|
||||
|
||||
def init_translations
|
||||
# NO OP
|
||||
# This call made also inside Simple Backend and accessed by
|
||||
# other plugins like I18n-js and babilu and
|
||||
# to use it along with the Chain backend we need to
|
||||
# provide a uniform API even for protected methods :S
|
||||
end
|
||||
|
||||
def subtrees?
|
||||
@subtrees
|
||||
end
|
@ -39,7 +39,7 @@ module I18n
|
||||
end
|
||||
locale = locale.to_sym
|
||||
translations[locale] ||= {}
|
||||
data = data.deep_symbolize_keys
|
||||
data = data.deep_stringify_keys.deep_symbolize_keys
|
||||
translations[locale].deep_merge!(data)
|
||||
end
|
||||
|
@ -145,5 +145,21 @@ module I18n
|
||||
def enforce_available_locales=(enforce_available_locales)
|
||||
@@enforce_available_locales = enforce_available_locales
|
||||
end
|
||||
|
||||
# Returns the current interpolation patterns. Defaults to
|
||||
# I18n::DEFAULT_INTERPOLATION_PATTERNS.
|
||||
def interpolation_patterns
|
||||
@@interpolation_patterns ||= I18n::DEFAULT_INTERPOLATION_PATTERNS.dup
|
||||
end
|
||||
|
||||
# Sets the current interpolation patterns. Used to set a interpolation
|
||||
# patterns.
|
||||
#
|
||||
# E.g. using {{}} as a placeholder like "{{hello}}, world!":
|
||||
#
|
||||
# I18n.config.interpolation_patterns << /\{\{(\w+)\}\}/
|
||||
def interpolation_patterns=(interpolation_patterns)
|
||||
@@interpolation_patterns = interpolation_patterns
|
||||
end
|
||||
end
|
||||
end
|
@ -17,6 +17,14 @@ class Hash
|
||||
}
|
||||
end unless Hash.method_defined?(:deep_symbolize_keys)
|
||||
|
||||
def deep_stringify_keys
|
||||
inject({}) { |result, (key, value)|
|
||||
value = value.deep_stringify_keys if value.is_a?(Hash)
|
||||
result[key.to_s] = value
|
||||
result
|
||||
}
|
||||
end unless Hash.method_defined?(:deep_stringify_keys)
|
||||
|
||||
# deep_merge_hash! by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
|
||||
MERGER = proc do |key, v1, v2|
|
||||
Hash === v1 && Hash === v2 ? v1.merge(v2, &MERGER) : v2
|
@ -2,11 +2,13 @@
|
||||
# http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb
|
||||
|
||||
module I18n
|
||||
INTERPOLATION_PATTERN = Regexp.union(
|
||||
DEFAULT_INTERPOLATION_PATTERNS = [
|
||||
/%%/,
|
||||
/%\{(\w+)\}/, # matches placeholders like "%{foo}"
|
||||
/%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/ # matches placeholders like "%<foo>.d"
|
||||
)
|
||||
].freeze
|
||||
INTERPOLATION_PATTERN = Regexp.union(DEFAULT_INTERPOLATION_PATTERNS)
|
||||
deprecate_constant :INTERPOLATION_PATTERN if method_defined? :INTERPOLATION_PATTERN
|
||||
|
||||
class << self
|
||||
# Return String or raises MissingInterpolationArgument exception.
|
||||
@ -18,7 +20,7 @@ module I18n
|
||||
end
|
||||
|
||||
def interpolate_hash(string, values)
|
||||
string.gsub(INTERPOLATION_PATTERN) do |match|
|
||||
string.gsub(Regexp.union(config.interpolation_patterns)) do |match|
|
||||
if match == '%%'
|
||||
'%'
|
||||
else
|
@ -1,5 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module I18n
|
||||
VERSION = "1.1.1"
|
||||
VERSION = "1.2.0"
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user