Permalink
Browse files

Provide a uniform api between Simple, KeyValue and Chain stores for p…

…ublic and private methods
  • Loading branch information...
1 parent 541a05f commit 3bc7ac9c407f09269b7ae4aea0b1ac1cb8aaac7c Paco Viramontes committed Sep 21, 2011
Showing with 86 additions and 0 deletions.
  1. +22 −0 lib/i18n/backend/chain.rb
  2. +25 −0 lib/i18n/backend/key_value.rb
  3. +26 −0 test/backend/chain_test.rb
  4. +13 −0 test/backend/key_value_test.rb
View
@@ -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
@@ -67,6 +76,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
@@ -1,6 +1,7 @@
require 'i18n/backend/base'
require 'active_support/json'
require 'active_support/ordered_hash' # active_support/json/encoding uses ActiveSupport::OrderedHash but does not require it
+require 'active_support/core_ext/hash/deep_merge'
module I18n
module Backend
@@ -58,6 +59,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|
@@ -86,6 +91,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])
View
@@ -62,6 +62,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' }, :plural_1 => { :one => '%{count}' }
+ }}
+ end
+
protected
def backend(translations)
@@ -43,4 +43,17 @@ def assert_flattens(expected, nested, escape=true, subtree=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 defined?(Rufus::Tokyo::Cabinet)

1 comment on commit 3bc7ac9

I kinda like the idea.

I do think though that if we're supporting an api for 3rd party code then we should make it public.

Still pondering the exact api though.

Please sign in to comment.