From 77c26aaedee5ad26fba6d69b0f72aa3d69c244c7 Mon Sep 17 00:00:00 2001 From: fatkodima Date: Wed, 7 Feb 2018 16:15:34 +0200 Subject: [PATCH] Fix Chained backend with KeyValue --- lib/i18n/backend/base.rb | 28 +++++++++++++++++++--------- lib/i18n/backend/key_value.rb | 18 +++++++++++++++++- test/backend/chain_test.rb | 33 ++++++++++++++++++++++++++++++++- test/backend/key_value_test.rb | 12 ++++++++++++ 4 files changed, 80 insertions(+), 11 deletions(-) diff --git a/lib/i18n/backend/base.rb b/lib/i18n/backend/base.rb index 1fb52cdb..a73a3ae0 100644 --- a/lib/i18n/backend/base.rb +++ b/lib/i18n/backend/base.rb @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/lib/i18n/backend/key_value.rb b/lib/i18n/backend/key_value.rb index f26f4a7e..95bdc641 100644 --- a/lib/i18n/backend/key_value.rb +++ b/lib/i18n/backend/key_value.rb @@ -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}"] @@ -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 @@ -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 diff --git a/test/backend/chain_test.rb b/test/backend/chain_test.rb index 0b402af2..2fae0945 100644 --- a/test/backend/chain_test.rb +++ b/test/backend/chain_test.rb @@ -13,7 +13,7 @@ def setup }) @second = backend(:en => { :bar => 'Bar', :formats => { - :long => 'long', + :long => 'long', :subformats => {:long => 'long'}, }, :plural_2 => { :one => 'one' }, @@ -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? diff --git a/test/backend/key_value_test.rb b/test/backend/key_value_test.rb index 6885efd2..be220d34 100644 --- a/test/backend/key_value_test.rb +++ b/test/backend/key_value_test.rb @@ -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" })