Skip to content

Commit

Permalink
Merge pull request #407 from fatkodima/fix-key-value-subtrees
Browse files Browse the repository at this point in the history
Fix Chained backend with KeyValue
  • Loading branch information
radar authored Feb 9, 2018
2 parents 9ddc9f5 77c26aa commit ba8b206
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 11 deletions.
28 changes: 19 additions & 9 deletions lib/i18n/backend/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 34,21 @@ def translate(locale, key, options = {})
entry = resolve(locale, key, entry, options)
end

entry = entry.dup if entry.is_a?(String)

count = options[:count]
entry = pluralize(locale, entry, count) if count

if entry.nil?
if entry.nil? && (subtrees? || !count)
if (options.key?(:default) && !options[:default].nil?) || !options.key?(:default)
throw(:exception, I18n::MissingTranslation.new(locale, key, options))
end
end

entry = entry.dup if entry.is_a?(String)
entry = pluralize(locale, entry, count) if count

if entry.nil? && !subtrees?
throw(:exception, I18n::MissingTranslation.new(locale, key, options))
end

deep_interpolation = options[:deep_interpolation]
values = options.except(*RESERVED_KEYS)
if values
Expand Down Expand Up @@ -97,6 101,10 @@ def lookup(locale, key, scope = [], options = {})
raise NotImplementedError
end

def subtrees?
true
end

# Evaluates defaults.
# If given subject is an Array, it walks the array and returns the
# first translation that can be resolved. Otherwise it tries to resolve
Expand Down Expand Up @@ -145,8 153,7 @@ def resolve(locale, object, subject, options = {})
def pluralize(locale, entry, count)
return entry unless entry.is_a?(Hash) && count

key = :zero if count == 0 && entry.has_key?(:zero)
key ||= count == 1 ? :one : :other
key = pluralization_key(entry, count)
raise InvalidPluralizationData.new(entry, count, key) unless entry.has_key?(key)
entry[key]
end
Expand All @@ -161,9 168,7 @@ def pluralize(locale, entry, count)
# each element of the array is recursively interpolated (until it finds a string)
# method interpolates ["yes, %{user}", ["maybe no, %{user}, "no, %{user}"]], :user => "bartuz"
# # => "["yes, bartuz",["maybe no, bartuz", "no, bartuz"]]"


def interpolate(locale, subject, values = {})
def interpolate(locale, subject, values = {})
return subject if values.empty?

case subject
Expand Down Expand Up @@ -240,6 245,11 @@ def translate_localization_format(locale, object, format, options)
end
end
end

def pluralization_key(entry, count)
key = :zero if count == 0 && entry.has_key?(:zero)
key ||= count == 1 ? :one : :other
end
end
end
end
18 changes: 17 additions & 1 deletion lib/i18n/backend/key_value.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 103,10 @@ def available_locales

protected

def subtrees?
@subtrees
end

def lookup(locale, key, scope = [], options = {})
key = normalize_flat_keys(locale, key, scope, options[:separator])
value = @store["#{locale}.#{key}"]
Expand All @@ -116,6 120,15 @@ def lookup(locale, key, scope = [], options = {})
SubtreeProxy.new("#{locale}.#{key}", @store)
end
end

def pluralize(locale, entry, count)
if subtrees?
super
else
key = pluralization_key(entry, count)
entry[key]
end
end
end

class SubtreeProxy
Expand All @@ -132,7 145,10 @@ def has_key?(key)
def [](key)
unless @subtree && value = @subtree[key]
value = @store["#{@master_key}.#{key}"]
(@subtree ||= {})[key] = JSON.decode(value) if value
if value
value = JSON.decode(value)
(@subtree ||= {})[key] = value
end
end
value
end
Expand Down
33 changes: 32 additions & 1 deletion test/backend/chain_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 13,7 @@ def setup
})
@second = backend(:en => {
:bar => 'Bar', :formats => {
:long => 'long',
:long => 'long',
:subformats => {:long => 'long'},
},
:plural_2 => { :one => 'one' },
Expand Down Expand Up @@ -89,3 89,34 @@ def backend(translations)
backend
end
end

class I18nBackendChainWithKeyValueTest < I18n::TestCase
def setup_backend!(subtrees = true)
first = I18n::Backend::KeyValue.new({}, subtrees)
first.store_translations(:en, :plural_1 => { :one => '%{count}' })

second = I18n::Backend::Simple.new
second.store_translations(:en, :plural_2 => { :one => 'one' })
I18n.backend = I18n::Backend::Chain.new(first, second)
end

test "subtrees enabled: looks up pluralization translations from the first chained backend" do
setup_backend!
assert_equal '1', I18n.t(:plural_1, count: 1)
end

test "subtrees disabled: looks up pluralization translations from the first chained backend" do
setup_backend!(false)
assert_equal '1', I18n.t(:plural_1, count: 1)
end

test "subtrees enabled: looks up translations from the second chained backend" do
setup_backend!
assert_equal 'one', I18n.t(:plural_2, count: 1)
end

test "subtrees disabled: looks up translations from the second chained backend" do
setup_backend!(false)
assert_equal 'one', I18n.t(:plural_2, count: 1)
end
end if I18n::TestCase.key_value?
12 changes: 12 additions & 0 deletions test/backend/key_value_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 41,18 @@ def assert_flattens(expected, nested, escape=true, subtree=true)
end
end

test "subtrees enabled: given incomplete pluralization data it raises I18n::InvalidPluralizationData" do
setup_backend!
store_translations(:en, :bar => { :one => "One" })
assert_raise(I18n::InvalidPluralizationData) { I18n.t(:bar, :count => 2) }
end

test "subtrees disabled: given incomplete pluralization data it returns an error message" do
setup_backend!(false)
store_translations(:en, :bar => { :one => "One" })
assert_equal "translation missing: en.bar", I18n.t(:bar, :count => 2)
end

test "translate handles subtrees for pluralization" do
setup_backend!(false)
store_translations(:en, :bar => { :one => "One" })
Expand Down

0 comments on commit ba8b206

Please sign in to comment.