Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Implement Fast backend as a module.

  • Loading branch information...
commit bd2f09f0a251ca793b0e8ecc7e32177a2f091c23 1 parent 9550939
@thedarkone thedarkone authored committed
View
1  lib/i18n/backend.rb
@@ -16,6 +16,7 @@ module Backend
autoload :Cache, 'i18n/backend/cache'
autoload :Chain, 'i18n/backend/chain'
autoload :Fallbacks, 'i18n/backend/fallbacks'
+ autoload :Fast, 'i18n/backend/fast'
autoload :Gettext, 'i18n/backend/gettext'
autoload :Helpers, 'i18n/backend/helpers'
autoload :InterpolationCompiler, 'i18n/backend/interpolation_compiler'
View
69 lib/i18n/backend/fast.rb
@@ -0,0 +1,69 @@
+# encoding: utf-8
+
+module I18n
+ module Backend
+ module Fast
+ SEPARATOR_ESCAPE_CHAR = "\001"
+
+ def reset_flattened_translations!
+ @flattened_translations = nil
+ end
+
+ def flattened_translations
+ @flattened_translations ||= flatten_translations(translations)
+ end
+
+ def merge_translations(locale, data)
+ super
+ reset_flattened_translations!
+ end
+
+ def init_translations
+ super
+ reset_flattened_translations!
+ end
+
+ protected
+ # flatten_hash({:a=>'a', :b=>{:c=>'c', :d=>'d', :f=>{:x=>'x'}}})
+ # # => {:a=>'a', :b=>{:c=>'c', :d=>'d', :f=>{:x=>'x'}}, :"b.f" => {:x=>"x"}, :"b.c"=>"c", :"b.f.x"=>"x", :"b.d"=>"d"}
+ def flatten_hash(h, nested_stack = [], flattened_h = {})
+ h.each_pair do |k, v|
+ new_nested_stack = nested_stack + [escape_default_separator(k)]
+ flattened_h[nested_stack_to_flat_key(new_nested_stack)] = v
+ flatten_hash(v, new_nested_stack, flattened_h) if v.kind_of?(Hash)
+ end
+
+ flattened_h
+ end
+
+ def escape_default_separator(key)
+ key.to_s.tr(I18n.default_separator, SEPARATOR_ESCAPE_CHAR)
+ end
+
+ def nested_stack_to_flat_key(nested_stack)
+ nested_stack.join(I18n.default_separator).to_sym
+ end
+
+ def flatten_translations(translations)
+ # don't flatten locale roots
+ translations.inject({}) do |flattened_h, (locale_name, locale_translations)|
+ flattened_h[locale_name] = flatten_hash(locale_translations)
+ flattened_h
+ end
+ end
+
+ def lookup(locale, key, scope = nil, separator = nil)
+ init_translations unless @initialized
+ if separator
+ key = cleanup_non_standard_separator(key, separator)
+ scope = Array(scope).map{|k| cleanup_non_standard_separator(k, separator)} if scope
+ end
+ flattened_translations[locale.to_sym][(scope ? (Array(scope) + [key]).join(I18n.default_separator) : key).to_sym] rescue nil
+ end
+
+ def cleanup_non_standard_separator(key, user_separator)
+ escape_default_separator(key).tr(user_separator, I18n.default_separator)
+ end
+ end
+ end
+end
View
31 test/cases/api/fast_test.rb
@@ -0,0 +1,31 @@
+# encoding: utf-8
+
+require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
+
+class I18nFastBackendApiTest < Test::Unit::TestCase
+ include Tests::Api::Basics
+ include Tests::Api::Defaults
+ include Tests::Api::Interpolation
+ include Tests::Api::Link
+ include Tests::Api::Lookup
+ include Tests::Api::Pluralization
+ include Tests::Api::Procs
+ include Tests::Api::Localization::Date
+ include Tests::Api::Localization::DateTime
+ include Tests::Api::Localization::Time
+ include Tests::Api::Localization::Procs
+
+ class FastBackend
+ include I18n::Backend::Base
+ include I18n::Backend::Fast
+ end
+
+ def setup
+ I18n.backend = FastBackend.new
+ super
+ end
+
+ define_method "test: make sure we use the FastBackend backend" do
+ assert_equal FastBackend, I18n.backend.class
+ end
+end
View
50 test/cases/backend/fast_test.rb
@@ -0,0 +1,50 @@
+# encoding: utf-8
+
+require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
+require File.expand_path(File.dirname(__FILE__) + '/simple_test')
+
+class I18nBackendFastTest < I18nBackendSimpleTest
+ class FastBackend
+ include I18n::Backend::Base
+ include I18n::Backend::Fast
+ end
+
+ def setup
+ super
+ I18n.backend = FastBackend.new
+ end
+end
+
+class I18nBackendFastSpecificTest < Test::Unit::TestCase
+ class FastBackend
+ include I18n::Backend::Base
+ include I18n::Backend::Fast
+ end
+
+ def setup
+ @backend = FastBackend.new
+ end
+
+ def assert_flattens(expected, nested)
+ assert_equal expected, @backend.send(:flatten_hash, nested)
+ end
+
+ def test_hash_flattening_works
+ assert_flattens(
+ {:a=>'a', :b=>{:c=>'c', :d=>'d', :f=>{:x=>'x'}}, :"b.f" => {:x=>"x"}, :"b.c"=>"c", :"b.f.x"=>"x", :"b.d"=>"d"},
+ {:a=>'a', :b=>{:c=>'c', :d=>'d', :f=>{:x=>'x'}}}
+ )
+ assert_flattens({:a=>{:b =>['a', 'b']}, :"a.b"=>['a', 'b']}, {:a=>{:b =>['a', 'b']}})
+ end
+
+ def test_pluralization_logic_and_lookup_works
+ counts_hash = {:zero => 'zero', :one => 'one', :other => 'other'}
+ @backend.store_translations :en, {:a => counts_hash}
+ assert_equal 'one', @backend.translate(:en, :a, :count => 1)
+ end
+
+ def test_translation_subtree_retrieval
+ @backend.store_translations :en, :a => {:foo => 'bar'}
+ assert_equal({:foo => 'bar'}, @backend.translate(:en, :a))
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.