i18n 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of i18n might be problematic. Click here for more details.
- data/VERSION +1 -1
- data/lib/i18n.rb +4 -2
- data/lib/i18n/backend.rb +1 -0
- data/lib/i18n/backend/active_record/store_procs.rb +19 -18
- data/lib/i18n/backend/base.rb +29 -10
- data/lib/i18n/backend/cache.rb +6 -2
- data/lib/i18n/backend/cascade.rb +44 -0
- data/lib/i18n/backend/gettext.rb +1 -1
- data/test/api/interpolation.rb +6 -6
- data/test/api/localization/date.rb +1 -1
- data/test/api/localization/date_time.rb +4 -1
- data/test/api/localization/time.rb +4 -2
- data/test/api/lookup.rb +5 -2
- data/test/cases/api/active_record_test.rb +5 -4
- data/test/cases/backend/active_record/missing_test.rb +1 -1
- data/test/cases/backend/active_record_test.rb +7 -5
- data/test/cases/backend/cache_test.rb +16 -13
- data/test/cases/backend/cascade_test.rb +66 -0
- data/test/cases/i18n_test.rb +25 -21
- data/test/test_helper.rb +39 -20
- metadata +5 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.2
|
data/lib/i18n.rb
CHANGED
@@ -203,7 +203,7 @@ module I18n
|
|
203
203
|
def translate(*args)
|
204
204
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
205
205
|
key = args.shift
|
206
|
-
locale = options.
|
206
|
+
locale = options.delete(:locale) || I18n.locale
|
207
207
|
raises = options.delete(:raise)
|
208
208
|
backend.translate(locale, key, options)
|
209
209
|
rescue I18n::ArgumentError => exception
|
@@ -225,7 +225,9 @@ module I18n
|
|
225
225
|
end
|
226
226
|
alias :l :localize
|
227
227
|
|
228
|
-
protected
|
228
|
+
# making these private until Ruby 1.9.2 can send to protected methods again
|
229
|
+
# see http://redmine.ruby-lang.org/repositories/revision/ruby-19?rev=24280
|
230
|
+
private
|
229
231
|
|
230
232
|
# Handles exceptions raised in the backend. All exceptions except for
|
231
233
|
# MissingTranslationData exceptions are re-raised. When a MissingTranslationData
|
data/lib/i18n/backend.rb
CHANGED
@@ -3,6 +3,7 @@ module I18n
|
|
3
3
|
autoload :ActiveRecord, 'i18n/backend/active_record'
|
4
4
|
autoload :Base, 'i18n/backend/base'
|
5
5
|
autoload :Cache, 'i18n/backend/cache'
|
6
|
+
autoload :Cascade, 'i18n/backend/cascade'
|
6
7
|
autoload :Chain, 'i18n/backend/chain'
|
7
8
|
autoload :Fallbacks, 'i18n/backend/fallbacks'
|
8
9
|
autoload :Gettext, 'i18n/backend/gettext'
|
@@ -8,30 +8,31 @@
|
|
8
8
|
# was extracted from the original backend.
|
9
9
|
#
|
10
10
|
# ParseTree is not compatible with Ruby 1.9.
|
11
|
+
|
12
|
+
begin
|
13
|
+
require 'ruby2ruby'
|
14
|
+
require 'parse_tree'
|
15
|
+
require 'parse_tree_extensions'
|
16
|
+
rescue LoadError => e
|
17
|
+
puts "can't use StoreProcs because: #{e.message}"
|
18
|
+
end
|
19
|
+
|
11
20
|
module I18n
|
12
21
|
module Backend
|
13
22
|
class ActiveRecord
|
14
23
|
module StoreProcs
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
def value=(v)
|
25
|
-
case v
|
26
|
-
when Proc
|
27
|
-
write_attribute(:value, v.to_ruby)
|
28
|
-
write_attribute(:is_proc, true)
|
29
|
-
else
|
30
|
-
write_attribute(:value, v)
|
31
|
-
end
|
24
|
+
def value=(v)
|
25
|
+
case v
|
26
|
+
when Proc
|
27
|
+
write_attribute(:value, v.to_ruby)
|
28
|
+
write_attribute(:is_proc, true)
|
29
|
+
else
|
30
|
+
write_attribute(:value, v)
|
32
31
|
end
|
33
32
|
end
|
33
|
+
|
34
|
+
Translation.send(:include, self) unless RUBY_VERSION >= '1.9'
|
34
35
|
end
|
35
36
|
end
|
36
37
|
end
|
37
|
-
end
|
38
|
+
end
|
data/lib/i18n/backend/base.rb
CHANGED
@@ -173,23 +173,42 @@ module I18n
|
|
173
173
|
def interpolate(locale, string, values = {})
|
174
174
|
return string unless string.is_a?(String) && !values.empty?
|
175
175
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
176
|
+
preserve_encoding(string) do
|
177
|
+
s = string.gsub(INTERPOLATION_SYNTAX_PATTERN) do
|
178
|
+
escaped, key = $1, $2.to_sym
|
179
|
+
if escaped
|
180
|
+
"{{#{key}}}"
|
181
|
+
elsif RESERVED_KEYS.include?(key)
|
182
|
+
raise ReservedInterpolationKey.new(key, string)
|
183
|
+
else
|
184
|
+
"%{#{key}}"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
values.each do |key, value|
|
189
|
+
value = value.call(values) if interpolate_lambda?(value, s, key)
|
190
|
+
value = value.to_s unless value.is_a?(String)
|
191
|
+
values[key] = value
|
184
192
|
end
|
193
|
+
|
194
|
+
s % values
|
185
195
|
end
|
186
|
-
values.each { |key, value| values[key] = value.call(values) if interpolate_lambda?(value, s, key) }
|
187
|
-
s % values
|
188
196
|
|
189
197
|
rescue KeyError => e
|
190
198
|
raise MissingInterpolationArgument.new(values, string)
|
191
199
|
end
|
192
200
|
|
201
|
+
def preserve_encoding(string)
|
202
|
+
if string.respond_to?(:encoding)
|
203
|
+
encoding = string.encoding
|
204
|
+
result = yield
|
205
|
+
result.force_encoding(encoding) if result.respond_to?(:force_encoding)
|
206
|
+
result
|
207
|
+
else
|
208
|
+
yield
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
193
212
|
# returns true when the given value responds to :call and the key is
|
194
213
|
# an interpolation placeholder in the given string
|
195
214
|
def interpolate_lambda?(object, string, key)
|
data/lib/i18n/backend/cache.rb
CHANGED
@@ -62,8 +62,12 @@ module I18n
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def cache_key(*args)
|
65
|
-
#
|
66
|
-
|
65
|
+
# This assumes that only simple, native Ruby values are passed to I18n.translate.
|
66
|
+
# Also, in Ruby < 1.8.7 {}.hash != {}.hash
|
67
|
+
# (see http://paulbarry.com/articles/2009/09/14/why-rails-3-will-require-ruby-1-8-7)
|
68
|
+
# If args.inspect does not work for you for some reason, patches are very welcome :)
|
69
|
+
hash = RUBY_VERSION >= "1.8.7" ? args.hash : args.inspect
|
70
|
+
keys = ['i18n', I18n.cache_namespace, hash]
|
67
71
|
keys.compact.join('-')
|
68
72
|
end
|
69
73
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# EXPERIMENTAL
|
4
|
+
#
|
5
|
+
# The cascade module adds the ability to do cascading lookups to backends that
|
6
|
+
# are compatible to the Simple backend.
|
7
|
+
#
|
8
|
+
# By cascading lookups we mean that for any key that can not be found the
|
9
|
+
# Cascade module strips one segment off the scope part of the key and then
|
10
|
+
# tries to look up the key in that scope.
|
11
|
+
#
|
12
|
+
# E.g. when a lookup for the key :"foo.bar.baz" does not yield a result then
|
13
|
+
# the segment :bar will be stripped off the scope part :"foo.bar" and the new
|
14
|
+
# scope :foo will be used to look up the key :baz. If that does not succeed
|
15
|
+
# then the remaining scope segment :foo will be omitted, too, and again the
|
16
|
+
# key :baz will be looked up (now with no scope).
|
17
|
+
#
|
18
|
+
# Defaults will only kick in after the cascading lookups haven't succeeded.
|
19
|
+
#
|
20
|
+
# This behavior is useful for libraries like ActiveRecord validations where
|
21
|
+
# the library wants to give users a bunch of more or less fine-grained options
|
22
|
+
# of scopes for a particular key.
|
23
|
+
#
|
24
|
+
# Thanks to Clemens Kofler for the initial idea and implementation! See
|
25
|
+
# http://github.com/clemens/i18n-cascading-backend
|
26
|
+
|
27
|
+
module I18n
|
28
|
+
@@fallbacks = nil
|
29
|
+
|
30
|
+
module Backend
|
31
|
+
module Cascade
|
32
|
+
def lookup(locale, key, scope = [], separator = nil)
|
33
|
+
return unless key
|
34
|
+
locale, *scope = I18n.send(:normalize_translation_keys, locale, key, scope, separator)
|
35
|
+
key = scope.pop
|
36
|
+
|
37
|
+
begin
|
38
|
+
result = super
|
39
|
+
return result unless result.nil?
|
40
|
+
end while scope.pop
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/i18n/backend/gettext.rb
CHANGED
@@ -41,7 +41,7 @@ module I18n
|
|
41
41
|
|
42
42
|
def normalize(locale, data)
|
43
43
|
data.inject({}) do |result, (key, value)|
|
44
|
-
unless key.
|
44
|
+
unless key.nil? || key.empty?
|
45
45
|
key, value = normalize_pluralization(locale, key, value) if key.index("\000")
|
46
46
|
|
47
47
|
parts = key.split('|').reverse
|
data/test/api/interpolation.rb
CHANGED
@@ -22,11 +22,11 @@ module Tests
|
|
22
22
|
end
|
23
23
|
|
24
24
|
define_method "test interpolation: given a lambda as a value it calls it if the string contains the key" do
|
25
|
-
assert_equal 'Hi David!', interpolate(:default => 'Hi {{name}}!', :name => lambda { 'David' })
|
25
|
+
assert_equal 'Hi David!', interpolate(:default => 'Hi {{name}}!', :name => lambda { |*args| 'David' })
|
26
26
|
end
|
27
27
|
|
28
28
|
define_method "test interpolation: given a lambda as a value it does not call it if the string does not contain the key" do
|
29
|
-
assert_nothing_raised { interpolate(:default => 'Hi!', :name => lambda { raise 'fail' }) }
|
29
|
+
assert_nothing_raised { interpolate(:default => 'Hi!', :name => lambda { |*args| raise 'fail' }) }
|
30
30
|
end
|
31
31
|
|
32
32
|
define_method "test interpolation: given values but missing a key it raises I18n::MissingInterpolationArgument" do
|
@@ -64,16 +64,16 @@ module Tests
|
|
64
64
|
end
|
65
65
|
|
66
66
|
if Kernel.const_defined?(:Encoding)
|
67
|
-
define_method "test interpolation: given a utf-8 translation and a euc-jp value it returns a translation in euc-jp" do
|
68
|
-
assert_equal euc_jp('Hi ゆきひろ!'), interpolate(:default => 'Hi {{name}}!', :name => euc_jp('ゆきひろ'))
|
69
|
-
end
|
70
|
-
|
71
67
|
define_method "test interpolation: given a euc-jp translation and a utf-8 value it raises Encoding::CompatibilityError" do
|
72
68
|
assert_raises(Encoding::CompatibilityError) do
|
73
69
|
interpolate(:default => euc_jp('こんにちは、{{name}}さん!'), :name => 'ゆきひろ')
|
74
70
|
end
|
75
71
|
end
|
76
72
|
|
73
|
+
# define_method "test interpolation: given a utf-8 translation and a euc-jp value it returns a translation in euc-jp" do
|
74
|
+
# assert_equal euc_jp('Hi ゆきひろ!'), interpolate(:default => 'Hi {{name}}!', :name => euc_jp('ゆきひろ'))
|
75
|
+
# end
|
76
|
+
#
|
77
77
|
# TODO should better explain how this relates to the test above with the simpler utf-8 default string
|
78
78
|
define_method "test interpolation: given a utf-8 translation and a euc-jp value it raises Encoding::CompatibilityError" do
|
79
79
|
assert_raises(Encoding::CompatibilityError) do
|
@@ -45,7 +45,7 @@ module Tests
|
|
45
45
|
assert_equal '[Sat, 01 Mar 2008, {}]', I18n.l(@date, :format => :proc, :locale => :de)
|
46
46
|
end
|
47
47
|
|
48
|
-
# TODO fails, but probably should pass
|
48
|
+
# TODO fails, but something along these lines probably should pass
|
49
49
|
# define_method "test localize Date: given a format that resolves to a Proc it calls the Proc with the object and extra options" do
|
50
50
|
# assert_equal '[Sat Mar 01 06:00:00 UTC 2008, {:foo=>"foo"}]', I18n.l(@time, :format => :proc, :foo => 'foo', :locale => :de)
|
51
51
|
# end
|
@@ -48,9 +48,12 @@ module Tests
|
|
48
48
|
end
|
49
49
|
|
50
50
|
define_method "test localize Date: given a format that resolves to a Proc it calls the Proc with the object" do
|
51
|
-
|
51
|
+
if can_store_procs?
|
52
|
+
assert_equal '[Sat, 01 Mar 2008 06:00:00 +0000, {}]', I18n.l(@datetime, :format => :proc, :locale => :de)
|
53
|
+
end
|
52
54
|
end
|
53
55
|
|
56
|
+
# TODO fails, but something along these lines probably should pass
|
54
57
|
# define_method "test localize DateTime: given a format that resolves to a Proc it calls the Proc with the object and extra options" do
|
55
58
|
# assert_equal '1ter März 2008, 06:00 Uhr', I18n.l(@datetime, :long_ordinalized)
|
56
59
|
# end
|
@@ -48,10 +48,12 @@ module Tests
|
|
48
48
|
end
|
49
49
|
|
50
50
|
define_method "test localize Time: given a format that resolves to a Proc it calls the Proc with the object" do
|
51
|
-
|
51
|
+
if can_store_procs?
|
52
|
+
assert_equal '[Sat, 01 Mar 2008 06:00:00 +0000, {}]', I18n.l(@datetime, :format => :proc, :locale => :de)
|
53
|
+
end
|
52
54
|
end
|
53
55
|
|
54
|
-
# TODO fails, but probably should pass
|
56
|
+
# TODO fails, but something along these lines probably should pass
|
55
57
|
# define_method "test localize Time: given a format that resolves to a Proc it calls the Proc with the object and extra options" do
|
56
58
|
# assert_equal '[Sat Mar 01 06:00:00 UTC 2008, {:foo=>"foo"}]', I18n.l(@time, :format => :proc, :foo => 'foo', :locale => :de)
|
57
59
|
# end
|
data/test/api/lookup.rb
CHANGED
@@ -30,8 +30,11 @@ module Tests
|
|
30
30
|
assert_equal 'bar', I18n.t('foo|bar', :separator => '|')
|
31
31
|
end
|
32
32
|
|
33
|
-
|
34
|
-
|
33
|
+
# In fact it probably *should* fail but Rails currently relies on using the default locale instead.
|
34
|
+
# So we'll stick to this for now until we get it fixed in Rails.
|
35
|
+
define_method "test lookup: given nil as a locale it does not raise but use the default locale" do
|
36
|
+
# assert_raises(I18n::InvalidLocale) { I18n.t(:bar, :locale => nil) }
|
37
|
+
assert_nothing_raised { I18n.t(:bar, :locale => nil) }
|
35
38
|
end
|
36
39
|
end
|
37
40
|
end
|
@@ -3,6 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
|
3
3
|
|
4
4
|
setup_active_record
|
5
5
|
|
6
|
+
|
6
7
|
class I18nActiveRecordApiTest < Test::Unit::TestCase
|
7
8
|
def setup
|
8
9
|
I18n.backend = I18n::Backend::ActiveRecord.new
|
@@ -15,14 +16,14 @@ class I18nActiveRecordApiTest < Test::Unit::TestCase
|
|
15
16
|
include Tests::Api::Link
|
16
17
|
include Tests::Api::Lookup
|
17
18
|
include Tests::Api::Pluralization
|
18
|
-
include Tests::Api::Procs
|
19
|
+
include Tests::Api::Procs unless RUBY_VERSION >= '1.9.1'
|
20
|
+
|
19
21
|
include Tests::Api::Localization::Date
|
20
22
|
include Tests::Api::Localization::DateTime
|
21
23
|
include Tests::Api::Localization::Time
|
22
|
-
include Tests::Api::Localization::Procs
|
24
|
+
include Tests::Api::Localization::Procs unless RUBY_VERSION >= '1.9.1'
|
23
25
|
|
24
26
|
define_method "test: make sure we use an ActiveRecord backend" do
|
25
27
|
assert_equal I18n::Backend::ActiveRecord, I18n.backend.class
|
26
28
|
end
|
27
|
-
end
|
28
|
-
|
29
|
+
end if defined?(ActiveRecord)
|
@@ -57,4 +57,4 @@ class I18nActiveRecordMissingTest < Test::Unit::TestCase
|
|
57
57
|
translations = I18n::Backend::ActiveRecord::Translation.locale(:en).find_by_key %w{ foo.zero foo.one foo.other }
|
58
58
|
assert !I18n::Backend::ActiveRecord::Translation.locale(:en).find_by_key("foo")
|
59
59
|
end
|
60
|
-
end
|
60
|
+
end if defined?(ActiveRecord)
|
@@ -3,10 +3,10 @@ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
|
3
3
|
|
4
4
|
setup_active_record
|
5
5
|
|
6
|
+
|
6
7
|
class I18nBackendActiveRecordTest < Test::Unit::TestCase
|
7
8
|
def setup
|
8
9
|
I18n.backend = I18n::Backend::ActiveRecord.new
|
9
|
-
I18n::Backend::ActiveRecord::Translation.send(:include, I18n::Backend::ActiveRecord::StoreProcs)
|
10
10
|
store_translations(:en, :foo => { :bar => 'bar', :baz => 'baz' })
|
11
11
|
end
|
12
12
|
|
@@ -39,12 +39,14 @@ class I18nBackendActiveRecordTest < Test::Unit::TestCase
|
|
39
39
|
assert_equal 'foo', I18n.t(:foo)
|
40
40
|
end
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
with_mocha do
|
43
|
+
def test_missing_translations_table_does_not_cause_available_locales_to_error
|
44
|
+
I18n::Backend::ActiveRecord::Translation.expects(:available_locales).raises(::ActiveRecord::StatementInvalid)
|
45
|
+
assert_equal [], I18n.backend.available_locales
|
46
|
+
end
|
45
47
|
end
|
46
48
|
|
47
49
|
def test_expand_keys
|
48
50
|
assert_equal %w(foo foo.bar foo.bar.baz), I18n.backend.send(:expand_keys, :'foo.bar.baz')
|
49
51
|
end
|
50
|
-
end
|
52
|
+
end if defined?(ActiveRecord)
|
@@ -29,22 +29,25 @@ class I18nBackendCacheTest < Test::Unit::TestCase
|
|
29
29
|
assert I18n.cache_store.is_a?(ActiveSupport::Cache::MemoryStore)
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
with_mocha do
|
33
|
+
define_method "test translate hits the backend and caches the response" do
|
34
|
+
I18n.backend.expects(:lookup).returns('Foo')
|
35
|
+
assert_equal 'Foo', I18n.t(:foo)
|
35
36
|
|
36
|
-
|
37
|
-
|
37
|
+
I18n.backend.expects(:lookup).never
|
38
|
+
assert_equal 'Foo', I18n.t(:foo)
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
40
|
+
I18n.backend.expects(:lookup).returns('Bar')
|
41
|
+
assert_equal 'Bar', I18n.t(:bar)
|
42
|
+
end
|
42
43
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
define_method "test still raises MissingTranslationData but also caches it" do
|
45
|
+
I18n.backend.expects(:lookup).returns(nil)
|
46
|
+
assert_raises(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
|
47
|
+
|
48
|
+
I18n.backend.expects(:lookup).never
|
49
|
+
assert_raises(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
|
50
|
+
end
|
48
51
|
end
|
49
52
|
|
50
53
|
define_method "test uses 'i18n' as a cache key namespace by default" do
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
4
|
+
|
5
|
+
class I18nBackendCascadeTest < Test::Unit::TestCase
|
6
|
+
class Backend
|
7
|
+
include I18n::Backend::Base
|
8
|
+
include I18n::Backend::Cascade
|
9
|
+
end
|
10
|
+
|
11
|
+
def setup
|
12
|
+
I18n.backend = Backend.new
|
13
|
+
store_translations(:en,
|
14
|
+
:foo => 'foo',
|
15
|
+
:bar => { :baz => 'baz' }
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
define_method "test: still returns an existing translation as usual" do
|
20
|
+
assert_equal 'foo', I18n.t(:foo)
|
21
|
+
assert_equal 'baz', I18n.t(:'bar.baz')
|
22
|
+
end
|
23
|
+
|
24
|
+
define_method "test: falls back by cutting keys off the end of the scope" do
|
25
|
+
assert_equal 'foo', I18n.t(:'does_not_exist.foo')
|
26
|
+
assert_equal 'foo', I18n.t(:'does_not_exist.does_not_exist.foo')
|
27
|
+
|
28
|
+
assert_equal 'baz', I18n.t(:'bar.does_not_exist.baz')
|
29
|
+
assert_equal 'baz', I18n.t(:'bar.does_not_exist.does_not_exist.baz')
|
30
|
+
end
|
31
|
+
|
32
|
+
define_method "test: raises I18n::MissingTranslationData exception when no translation was found" do
|
33
|
+
assert_raises(I18n::MissingTranslationData) { I18n.t(:'foo.does_not_exist', :raise => true) }
|
34
|
+
assert_raises(I18n::MissingTranslationData) { I18n.t(:'bar.baz.does_not_exist', :raise => true) }
|
35
|
+
assert_raises(I18n::MissingTranslationData) { I18n.t(:'does_not_exist.bar.baz', :raise => true) }
|
36
|
+
end
|
37
|
+
|
38
|
+
define_method "test: cascades before evaluating the default" do
|
39
|
+
assert_equal 'foo', I18n.t(:foo, :scope => :does_not_exist, :default => 'default')
|
40
|
+
end
|
41
|
+
|
42
|
+
define_method "test: let's us assemble required fallbacks for ActiveRecord validation messages" do
|
43
|
+
store_translations(:en,
|
44
|
+
:errors => {
|
45
|
+
:reply => {
|
46
|
+
:title => {
|
47
|
+
:blank => 'blank on reply title'
|
48
|
+
},
|
49
|
+
:taken => 'taken on reply'
|
50
|
+
},
|
51
|
+
:topic => {
|
52
|
+
:title => {
|
53
|
+
:format => 'format on topic title'
|
54
|
+
},
|
55
|
+
:length => 'length on topic'
|
56
|
+
},
|
57
|
+
:odd => 'odd on errors'
|
58
|
+
}
|
59
|
+
)
|
60
|
+
assert_equal 'blank on reply title', I18n.t(:'errors.reply.title.blank', :default => :'errors.topic.title.blank')
|
61
|
+
assert_equal 'taken on reply', I18n.t(:'errors.reply.title.taken', :default => :'errors.topic.title.taken')
|
62
|
+
assert_equal 'format on topic title', I18n.t(:'errors.reply.title.format', :default => :'errors.topic.title.format')
|
63
|
+
assert_equal 'length on topic', I18n.t(:'errors.reply.title.length', :default => :'errors.topic.title.length')
|
64
|
+
assert_equal 'odd on errors', I18n.t(:'errors.reply.title.odd', :default => :'errors.topic.title.odd')
|
65
|
+
end
|
66
|
+
end
|
data/test/cases/i18n_test.rb
CHANGED
@@ -71,26 +71,28 @@ class I18nTest < Test::Unit::TestCase
|
|
71
71
|
I18n.exception_handler = :default_exception_handler # revert it
|
72
72
|
end
|
73
73
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
74
|
+
with_mocha do
|
75
|
+
def test_uses_custom_exception_handler
|
76
|
+
I18n.exception_handler = :custom_exception_handler
|
77
|
+
I18n.expects(:custom_exception_handler)
|
78
|
+
I18n.translate :bogus
|
79
|
+
I18n.exception_handler = :default_exception_handler # revert it
|
80
|
+
end
|
80
81
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
82
|
+
def test_delegates_translate_to_backend
|
83
|
+
I18n.backend.expects(:translate).with 'de', :foo, {}
|
84
|
+
I18n.translate :foo, :locale => 'de'
|
85
|
+
end
|
85
86
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
87
|
+
def test_delegates_localize_to_backend
|
88
|
+
I18n.backend.expects(:localize).with 'de', :whatever, :default
|
89
|
+
I18n.localize :whatever, :locale => 'de'
|
90
|
+
end
|
90
91
|
|
91
|
-
|
92
|
-
|
93
|
-
|
92
|
+
def test_translate_given_no_locale_uses_i18n_locale
|
93
|
+
I18n.backend.expects(:translate).with :en, :foo, {}
|
94
|
+
I18n.translate :foo
|
95
|
+
end
|
94
96
|
end
|
95
97
|
|
96
98
|
def test_translate_on_nested_symbol_keys_works
|
@@ -117,10 +119,12 @@ class I18nTest < Test::Unit::TestCase
|
|
117
119
|
assert_equal [".", ","], I18n.t(%w(format.separator format.delimiter), :scope => 'currency')
|
118
120
|
end
|
119
121
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
locale.
|
122
|
+
with_mocha do
|
123
|
+
def test_translate_with_options_using_scope_works
|
124
|
+
I18n.backend.expects(:translate).with('de', :precision, :scope => :"currency.format")
|
125
|
+
I18n.with_options :locale => 'de', :scope => :'currency.format' do |locale|
|
126
|
+
locale.t :precision
|
127
|
+
end
|
124
128
|
end
|
125
129
|
end
|
126
130
|
|
data/test/test_helper.rb
CHANGED
@@ -5,12 +5,18 @@ $: << File.expand_path(File.dirname(__FILE__))
|
|
5
5
|
|
6
6
|
require 'rubygems'
|
7
7
|
require 'test/unit'
|
8
|
-
require 'mocha'
|
9
8
|
require 'i18n'
|
10
9
|
require 'i18n/core_ext/object/meta_class'
|
11
10
|
require 'time'
|
12
11
|
require 'yaml'
|
13
12
|
|
13
|
+
begin
|
14
|
+
require 'mocha'
|
15
|
+
rescue LoadError
|
16
|
+
puts "skipping tests using mocha as mocha can't be found"
|
17
|
+
end
|
18
|
+
|
19
|
+
|
14
20
|
Dir[File.dirname(__FILE__) + '/api/**/*.rb'].each do |filename|
|
15
21
|
require filename
|
16
22
|
end
|
@@ -24,11 +30,15 @@ $KCODE = 'u' unless RUBY_VERSION >= '1.9'
|
|
24
30
|
# end
|
25
31
|
# end
|
26
32
|
|
27
|
-
class Test::Unit::TestCase
|
33
|
+
class Test::Unit::TestCase
|
28
34
|
def self.test(name, &block)
|
29
35
|
define_method("test: " + name, &block)
|
30
36
|
end
|
31
37
|
|
38
|
+
def self.with_mocha
|
39
|
+
yield if Object.respond_to?(:expects)
|
40
|
+
end
|
41
|
+
|
32
42
|
def teardown
|
33
43
|
I18n.locale = nil
|
34
44
|
I18n.default_locale = :en
|
@@ -40,13 +50,13 @@ class Test::Unit::TestCase
|
|
40
50
|
def translations
|
41
51
|
I18n.backend.instance_variable_get(:@translations)
|
42
52
|
end
|
43
|
-
|
53
|
+
|
44
54
|
def store_translations(*args)
|
45
55
|
data = args.pop
|
46
56
|
locale = args.pop || :en
|
47
57
|
I18n.backend.store_translations(locale, data)
|
48
58
|
end
|
49
|
-
|
59
|
+
|
50
60
|
def locales_dir
|
51
61
|
File.dirname(__FILE__) + '/fixtures/locales'
|
52
62
|
end
|
@@ -54,27 +64,36 @@ class Test::Unit::TestCase
|
|
54
64
|
def euc_jp(string)
|
55
65
|
string.encode!(Encoding::EUC_JP)
|
56
66
|
end
|
67
|
+
|
68
|
+
def can_store_procs?
|
69
|
+
I18n::Backend::ActiveRecord === I18n.backend and
|
70
|
+
I18n::Backend::ActiveRecord.included_modules.include?(I18n::Backend::ActiveRecord::StoreProcs)
|
71
|
+
end
|
57
72
|
end
|
58
73
|
|
59
74
|
def setup_active_record
|
60
|
-
|
61
|
-
|
75
|
+
begin
|
76
|
+
require 'activerecord'
|
77
|
+
require 'i18n/backend/active_record'
|
78
|
+
require 'i18n/backend/active_record/store_procs'
|
62
79
|
|
63
|
-
|
64
|
-
|
65
|
-
|
80
|
+
if I18n::Backend::Simple.method_defined?(:interpolate_with_deprecated_syntax)
|
81
|
+
I18n::Backend::Simple.send(:remove_method, :interpolate) rescue NameError
|
82
|
+
end
|
66
83
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
84
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
85
|
+
ActiveRecord::Migration.verbose = false
|
86
|
+
ActiveRecord::Schema.define(:version => 1) do
|
87
|
+
create_table :translations do |t|
|
88
|
+
t.string :locale
|
89
|
+
t.string :key
|
90
|
+
t.string :value
|
91
|
+
t.string :interpolations
|
92
|
+
t.boolean :is_proc, :default => false
|
93
|
+
end
|
76
94
|
end
|
77
|
-
end
|
78
95
|
|
79
|
-
|
96
|
+
rescue LoadError
|
97
|
+
puts "skipping tests using activerecord as activerecord can't be found"
|
98
|
+
end
|
80
99
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i18n
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sven Fuchs
|
@@ -13,7 +13,7 @@ autorequire:
|
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
15
|
|
16
|
-
date: 2009-12-
|
16
|
+
date: 2009-12-12 00:00:00 +01:00
|
17
17
|
default_executable:
|
18
18
|
dependencies: []
|
19
19
|
|
@@ -39,6 +39,7 @@ files:
|
|
39
39
|
- lib/i18n/backend/active_record/translation.rb
|
40
40
|
- lib/i18n/backend/base.rb
|
41
41
|
- lib/i18n/backend/cache.rb
|
42
|
+
- lib/i18n/backend/cascade.rb
|
42
43
|
- lib/i18n/backend/chain.rb
|
43
44
|
- lib/i18n/backend/fallbacks.rb
|
44
45
|
- lib/i18n/backend/gettext.rb
|
@@ -79,6 +80,7 @@ files:
|
|
79
80
|
- test/cases/backend/active_record/missing_test.rb
|
80
81
|
- test/cases/backend/active_record_test.rb
|
81
82
|
- test/cases/backend/cache_test.rb
|
83
|
+
- test/cases/backend/cascade_test.rb
|
82
84
|
- test/cases/backend/chain_test.rb
|
83
85
|
- test/cases/backend/fallbacks_test.rb
|
84
86
|
- test/cases/backend/helpers_test.rb
|
@@ -150,6 +152,7 @@ test_files:
|
|
150
152
|
- test/cases/backend/active_record/missing_test.rb
|
151
153
|
- test/cases/backend/active_record_test.rb
|
152
154
|
- test/cases/backend/cache_test.rb
|
155
|
+
- test/cases/backend/cascade_test.rb
|
153
156
|
- test/cases/backend/chain_test.rb
|
154
157
|
- test/cases/backend/fallbacks_test.rb
|
155
158
|
- test/cases/backend/helpers_test.rb
|