Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Chained backend with KeyValue #407

Merged
merged 1 commit into from Feb 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 19 additions & 9 deletions lib/i18n/backend/base.rb
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
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
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
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