Skip to content

Commit

Permalink
experimental cascading backend (thanks to Clemens Kofler for the init…
Browse files Browse the repository at this point in the history
…ial idea)
  • Loading branch information
Sven Fuchs committed Dec 12, 2009
1 parent 6b3f8bb commit 8009aef
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/i18n/backend.rb
Expand Up @@ -3,6 +3,7 @@ module Backend
autoload :ActiveRecord, 'i18n/backend/active_record'
autoload :Base, 'i18n/backend/base'
autoload :Cache, 'i18n/backend/cache'
autoload :Cascade, 'i18n/backend/cascade'
autoload :Chain, 'i18n/backend/chain'
autoload :Fallbacks, 'i18n/backend/fallbacks'
autoload :Gettext, 'i18n/backend/gettext'
Expand Down
20 changes: 20 additions & 0 deletions lib/i18n/backend/cascade.rb
@@ -0,0 +1,20 @@
# encoding: utf-8

module I18n
@@fallbacks = nil

module Backend
module Cascade
def lookup(locale, key, scope = [], separator = nil)
return unless key
locale, *scope = I18n.send(:normalize_translation_keys, locale, key, scope, separator)
key = scope.pop

begin
result = super
return result unless result.nil?
end while scope.pop
end
end
end
end
66 changes: 66 additions & 0 deletions test/cases/backend/cascade_test.rb
@@ -0,0 +1,66 @@
# encoding: utf-8

require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')

class I18nBackendCascadeTest < Test::Unit::TestCase
class Backend
include I18n::Backend::Base
include I18n::Backend::Cascade
end

def setup
I18n.backend = Backend.new
store_translations(:en,
:foo => 'foo',
:bar => { :baz => 'baz' }
)
end

define_method "test: still returns an existing translation as usual" do
assert_equal 'foo', I18n.t(:foo)
assert_equal 'baz', I18n.t(:'bar.baz')
end

define_method "test: falls back by cutting keys off the end of the scope" do
assert_equal 'foo', I18n.t(:'does_not_exist.foo')
assert_equal 'foo', I18n.t(:'does_not_exist.does_not_exist.foo')

assert_equal 'baz', I18n.t(:'bar.does_not_exist.baz')
assert_equal 'baz', I18n.t(:'bar.does_not_exist.does_not_exist.baz')
end

define_method "test: raises I18n::MissingTranslationData exception when no translation was found" do
assert_raises(I18n::MissingTranslationData) { I18n.t(:'foo.does_not_exist', :raise => true) }
assert_raises(I18n::MissingTranslationData) { I18n.t(:'bar.baz.does_not_exist', :raise => true) }
assert_raises(I18n::MissingTranslationData) { I18n.t(:'does_not_exist.bar.baz', :raise => true) }
end

define_method "test: cascades before evaluating the default" do
assert_equal 'foo', I18n.t(:foo, :scope => :does_not_exist, :default => 'default')
end

define_method "test: let's us assemble required fallbacks for ActiveRecord validation messages" do
store_translations(:en,
:errors => {
:reply => {
:title => {
:blank => 'blank on reply title'
},
:taken => 'taken on reply'
},
:topic => {
:title => {
:format => 'format on topic title'
},
:length => 'length on topic'
},
:odd => 'odd on errors'
}
)
assert_equal 'blank on reply title', I18n.t(:'errors.reply.title.blank', :default => :'errors.topic.title.blank')
assert_equal 'taken on reply', I18n.t(:'errors.reply.title.taken', :default => :'errors.topic.title.taken')
assert_equal 'format on topic title', I18n.t(:'errors.reply.title.format', :default => :'errors.topic.title.format')
assert_equal 'length on topic', I18n.t(:'errors.reply.title.length', :default => :'errors.topic.title.length')
assert_equal 'odd on errors', I18n.t(:'errors.reply.title.odd', :default => :'errors.topic.title.odd')
end
end

0 comments on commit 8009aef

Please sign in to comment.