From 15343c5935ce904ab91daa94871918b62b8b7134 Mon Sep 17 00:00:00 2001 From: Paco Viramontes Date: Tue, 20 Sep 2011 18:50:10 -0700 Subject: [PATCH] Provide a uniform api between Simple, KeyValue and Chain stores for public and private methods --- README.md | 1 + lib/i18n/backend/chain.rb | 22 ++++++++++++++++++++++ lib/i18n/backend/key_value.rb | 25 +++++++++++++++++++++++++ test/backend/chain_test.rb | 26 ++++++++++++++++++++++++++ test/backend/key_value_test.rb | 13 +++++++++++++ 5 files changed, 87 insertions(+) diff --git a/README.md b/README.md index ae9faf7d..c2e2efed 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,7 @@ follow the usual test setup and should be easy to grok. * [Stephan Soller](http://www.arkanis-development.de) * [Saimon Moore](http://saimonmoore.net) * [Matt Aimonetti](https://matt.aimonetti.net/) +* [Francisco Viramontes](https://twitter.com/kidpollo) ## Contributors diff --git a/lib/i18n/backend/chain.rb b/lib/i18n/backend/chain.rb index 2a45cad3..c73306c2 100644 --- a/lib/i18n/backend/chain.rb +++ b/lib/i18n/backend/chain.rb @@ -24,6 +24,15 @@ def initialize(*backends) 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 @@ -72,6 +81,19 @@ def localize(locale, object, format = :default, options = {}) end protected + def init_translations + backends.each { |backend| + backend.send(:init_translations) + } + 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 diff --git a/lib/i18n/backend/key_value.rb b/lib/i18n/backend/key_value.rb index a79fc1aa..26bad83a 100644 --- a/lib/i18n/backend/key_value.rb +++ b/lib/i18n/backend/key_value.rb @@ -1,5 +1,6 @@ require 'i18n/backend/base' require 'active_support/json' +require 'active_support/core_ext/hash/deep_merge' module I18n module Backend @@ -57,6 +58,10 @@ def initialize(store, subtrees=true) @store, @subtrees = store, subtrees end + def initialized? + !@store.nil? + end + def store_translations(locale, data, options = {}) escape = options.fetch(:escape, true) flatten_translations(locale, data, escape, @subtrees).each do |key, value| @@ -85,6 +90,26 @@ def available_locales end 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 = ActiveSupport::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 lookup(locale, key, scope = [], options = {}) key = normalize_flat_keys(locale, key, scope, options[:separator]) diff --git a/test/backend/chain_test.rb b/test/backend/chain_test.rb index 0b402af2..dd45813c 100644 --- a/test/backend/chain_test.rb +++ b/test/backend/chain_test.rb @@ -81,6 +81,32 @@ def setup I18n.backend.store_translations :foo, {:bar => :baz}, {:option => 'persists'} end + test 'store should call initialize on all backends and return true if all initialized' do + @first.send :init_translations + @second.send :init_translations + assert_equal(I18n.backend.initialized?, true) + end + + test 'store should call initialize on all backends and return false if one not initialized' do + @first.reload! + @second.send :init_translations + assert_equal(I18n.backend.initialized?, false) + end + + test 'should reload all backends' do + @first.send :init_translations + @second.send :init_translations + I18n.backend.reload! + assert_equal(@first.initialized?, false) + assert_equal(@second.initialized?, false) + end + + test 'should be able to get all translations of the first backend' do + assert_equal I18n.backend.send(:translations),{:en => { + :foo=>"Foo", :formats=>{:short=>"short", :subformats=>{:short=>"short"}}, :plural_1=>{:one=>"%{count}"}, :dates=>{:a=>"A"} + }} + end + protected def backend(translations) diff --git a/test/backend/key_value_test.rb b/test/backend/key_value_test.rb index 097780df..63a25a74 100644 --- a/test/backend/key_value_test.rb +++ b/test/backend/key_value_test.rb @@ -40,4 +40,17 @@ def assert_flattens(expected, nested, escape=true, subtree=true) I18n.t("foo", :raise => true) end end + + test 'initialized? checks that a store is available' do + setup_backend! + I18n.backend.reload! + assert_equal I18n.backend.initialized?, true + end + + test 'translations gets the translations from the store' do + setup_backend! + I18n.backend.send(:translations) + expected = { :en => {:foo => { :bar => 'bar', :baz => 'baz' }} } + assert_equal expected, translations + end end if I18n::TestCase.key_value?