Skip to content

Commit

Permalink
Implement Fast backend as a module.
Browse files Browse the repository at this point in the history
  • Loading branch information
thedarkone authored and Sven Fuchs committed Dec 12, 2009
1 parent 9550939 commit bd2f09f
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/i18n/backend.rb
Expand Up @@ -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'
Expand Down
69 changes: 69 additions & 0 deletions 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
31 changes: 31 additions & 0 deletions 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
50 changes: 50 additions & 0 deletions 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

0 comments on commit bd2f09f

Please sign in to comment.