i18n 1.0.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +54 -13
  3. data/lib/i18n.rb +53 -27
  4. data/lib/i18n/backend.rb +1 -0
  5. data/lib/i18n/backend/base.rb +36 -9
  6. data/lib/i18n/backend/cache.rb +2 -5
  7. data/lib/i18n/backend/cache_file.rb +36 -0
  8. data/lib/i18n/backend/chain.rb +28 -0
  9. data/lib/i18n/backend/gettext.rb +2 -0
  10. data/lib/i18n/backend/key_value.rb +27 -0
  11. data/lib/i18n/backend/memoize.rb +6 -0
  12. data/lib/i18n/backend/simple.rb +22 -6
  13. data/lib/i18n/config.rb +17 -1
  14. data/lib/i18n/core_ext/hash.rb +42 -24
  15. data/lib/i18n/exceptions.rb +20 -15
  16. data/lib/i18n/interpolate/ruby.rb +5 -3
  17. data/lib/i18n/locale/fallbacks.rb +1 -1
  18. data/lib/i18n/tests/interpolation.rb +1 -1
  19. data/lib/i18n/tests/localization/date.rb +28 -6
  20. data/lib/i18n/tests/localization/date_time.rb +27 -6
  21. data/lib/i18n/tests/localization/time.rb +26 -4
  22. data/lib/i18n/version.rb +1 -1
  23. metadata +24 -58
  24. data/gemfiles/Gemfile.rails-3.2.x +0 -10
  25. data/gemfiles/Gemfile.rails-4.0.x +0 -10
  26. data/gemfiles/Gemfile.rails-4.1.x +0 -10
  27. data/gemfiles/Gemfile.rails-4.2.x +0 -10
  28. data/gemfiles/Gemfile.rails-5.0.x +0 -10
  29. data/gemfiles/Gemfile.rails-5.1.x +0 -10
  30. data/gemfiles/Gemfile.rails-master +0 -10
  31. data/lib/i18n/core_ext/kernel/suppress_warnings.rb +0 -8
  32. data/lib/i18n/core_ext/string/interpolate.rb +0 -9
  33. data/test/api/all_features_test.rb +0 -58
  34. data/test/api/cascade_test.rb +0 -28
  35. data/test/api/chain_test.rb +0 -24
  36. data/test/api/fallbacks_test.rb +0 -30
  37. data/test/api/key_value_test.rb +0 -24
  38. data/test/api/memoize_test.rb +0 -56
  39. data/test/api/override_test.rb +0 -42
  40. data/test/api/pluralization_test.rb +0 -30
  41. data/test/api/simple_test.rb +0 -28
  42. data/test/backend/cache_test.rb +0 -109
  43. data/test/backend/cascade_test.rb +0 -86
  44. data/test/backend/chain_test.rb +0 -122
  45. data/test/backend/exceptions_test.rb +0 -36
  46. data/test/backend/fallbacks_test.rb +0 -219
  47. data/test/backend/interpolation_compiler_test.rb +0 -118
  48. data/test/backend/key_value_test.rb +0 -61
  49. data/test/backend/memoize_test.rb +0 -79
  50. data/test/backend/metadata_test.rb +0 -48
  51. data/test/backend/pluralization_test.rb +0 -45
  52. data/test/backend/simple_test.rb +0 -103
  53. data/test/backend/transliterator_test.rb +0 -84
  54. data/test/core_ext/hash_test.rb +0 -36
  55. data/test/gettext/api_test.rb +0 -214
  56. data/test/gettext/backend_test.rb +0 -92
  57. data/test/i18n/exceptions_test.rb +0 -117
  58. data/test/i18n/gettext_plural_keys_test.rb +0 -20
  59. data/test/i18n/interpolate_test.rb +0 -91
  60. data/test/i18n/load_path_test.rb +0 -34
  61. data/test/i18n/middleware_test.rb +0 -24
  62. data/test/i18n_test.rb +0 -462
  63. data/test/locale/fallbacks_test.rb +0 -133
  64. data/test/locale/tag/rfc4646_test.rb +0 -143
  65. data/test/locale/tag/simple_test.rb +0 -32
  66. data/test/run_all.rb +0 -20
  67. data/test/test_data/locales/de.po +0 -82
  68. data/test/test_data/locales/en.rb +0 -3
  69. data/test/test_data/locales/en.yml +0 -3
  70. data/test/test_data/locales/invalid/empty.yml +0 -0
  71. data/test/test_data/locales/invalid/syntax.yml +0 -4
  72. data/test/test_data/locales/plurals.rb +0 -113
  73. data/test/test_helper.rb +0 -61
@@ -1,56 +0,0 @@
1
- require 'test_helper'
2
-
3
- class I18nMemoizeBackendWithSimpleApiTest < I18n::TestCase
4
- include I18n::Tests::Basics
5
- include I18n::Tests::Defaults
6
- include I18n::Tests::Interpolation
7
- include I18n::Tests::Link
8
- include I18n::Tests::Lookup
9
- include I18n::Tests::Pluralization
10
- include I18n::Tests::Procs
11
- include I18n::Tests::Localization::Date
12
- include I18n::Tests::Localization::DateTime
13
- include I18n::Tests::Localization::Time
14
- include I18n::Tests::Localization::Procs
15
-
16
- class MemoizeBackend < I18n::Backend::Simple
17
- include I18n::Backend::Memoize
18
- end
19
-
20
- def setup
21
- I18n.backend = MemoizeBackend.new
22
- super
23
- end
24
-
25
- test "make sure we use the MemoizeBackend backend" do
26
- assert_equal MemoizeBackend, I18n.backend.class
27
- end
28
- end
29
-
30
- class I18nMemoizeBackendWithKeyValueApiTest < I18n::TestCase
31
- include I18n::Tests::Basics
32
- include I18n::Tests::Defaults
33
- include I18n::Tests::Interpolation
34
- include I18n::Tests::Link
35
- include I18n::Tests::Lookup
36
- include I18n::Tests::Pluralization
37
- include I18n::Tests::Localization::Date
38
- include I18n::Tests::Localization::DateTime
39
- include I18n::Tests::Localization::Time
40
-
41
- # include I18n::Tests::Procs
42
- # include I18n::Tests::Localization::Procs
43
-
44
- class MemoizeBackend < I18n::Backend::KeyValue
45
- include I18n::Backend::Memoize
46
- end
47
-
48
- def setup
49
- I18n.backend = MemoizeBackend.new({})
50
- super
51
- end
52
-
53
- test "make sure we use the MemoizeBackend backend" do
54
- assert_equal MemoizeBackend, I18n.backend.class
55
- end
56
- end if I18n::TestCase.key_value?
@@ -1,42 +0,0 @@
1
- require 'test_helper'
2
-
3
- class I18nOverrideTest < I18n::TestCase
4
- module OverrideInverse
5
- def translate(*args)
6
- super(*args).reverse
7
- end
8
- alias :t :translate
9
- end
10
-
11
- module OverrideSignature
12
- def translate(*args)
13
- args.first + args[1]
14
- end
15
- alias :t :translate
16
- end
17
-
18
- def setup
19
- super
20
- @I18n = I18n.dup
21
- @I18n.backend = I18n::Backend::Simple.new
22
- end
23
-
24
- test "make sure modules can overwrite I18n methods" do
25
- @I18n.extend OverrideInverse
26
- @I18n.backend.store_translations('en', :foo => 'bar')
27
-
28
- assert_equal 'rab', @I18n.translate(:foo, :locale => 'en')
29
- assert_equal 'rab', @I18n.t(:foo, :locale => 'en')
30
- assert_equal 'rab', @I18n.translate!(:foo, :locale => 'en')
31
- assert_equal 'rab', @I18n.t!(:foo, :locale => 'en')
32
- end
33
-
34
- test "make sure modules can overwrite I18n signature" do
35
- exception = catch(:exception) do
36
- @I18n.t('Hello', 'Welcome message on home page', :tokenize => true, :throw => true)
37
- end
38
- assert exception.message
39
- @I18n.extend OverrideSignature
40
- assert_equal 'HelloWelcome message on home page', @I18n.translate('Hello', 'Welcome message on home page', :tokenize => true) # tr8n example
41
- end
42
- end
@@ -1,30 +0,0 @@
1
- require 'test_helper'
2
-
3
- class I18nPluralizationApiTest < I18n::TestCase
4
- class Backend < I18n::Backend::Simple
5
- include I18n::Backend::Pluralization
6
- end
7
-
8
- def setup
9
- I18n.backend = Backend.new
10
- super
11
- end
12
-
13
- include I18n::Tests::Basics
14
- include I18n::Tests::Defaults
15
- include I18n::Tests::Interpolation
16
- include I18n::Tests::Link
17
- include I18n::Tests::Lookup
18
- include I18n::Tests::Pluralization
19
- include I18n::Tests::Procs
20
- include I18n::Tests::Localization::Date
21
- include I18n::Tests::Localization::DateTime
22
- include I18n::Tests::Localization::Time
23
- include I18n::Tests::Localization::Procs
24
-
25
- test "make sure we use a backend with Pluralization included" do
26
- assert_equal Backend, I18n.backend.class
27
- end
28
-
29
- # links: test that keys stored on one backend can link to keys stored on another backend
30
- end
@@ -1,28 +0,0 @@
1
- require 'test_helper'
2
-
3
- class I18nSimpleBackendApiTest < I18n::TestCase
4
- class Backend < I18n::Backend::Simple
5
- include I18n::Backend::Pluralization
6
- end
7
-
8
- def setup
9
- I18n.backend = I18n::Backend::Simple.new
10
- super
11
- end
12
-
13
- include I18n::Tests::Basics
14
- include I18n::Tests::Defaults
15
- include I18n::Tests::Interpolation
16
- include I18n::Tests::Link
17
- include I18n::Tests::Lookup
18
- include I18n::Tests::Pluralization
19
- include I18n::Tests::Procs
20
- include I18n::Tests::Localization::Date
21
- include I18n::Tests::Localization::DateTime
22
- include I18n::Tests::Localization::Time
23
- include I18n::Tests::Localization::Procs
24
-
25
- test "make sure we use the Simple backend" do
26
- assert_equal I18n::Backend::Simple, I18n.backend.class
27
- end
28
- end
@@ -1,109 +0,0 @@
1
- require 'test_helper'
2
- require 'digest/md5'
3
-
4
- begin
5
- require 'active_support'
6
- rescue LoadError
7
- $stderr.puts "Skipping cache tests using ActiveSupport"
8
- else
9
-
10
- class I18nBackendCacheTest < I18n::TestCase
11
- class Backend < I18n::Backend::Simple
12
- include I18n::Backend::Cache
13
- end
14
-
15
- def setup
16
- I18n.backend = Backend.new
17
- super
18
- I18n.cache_store = ActiveSupport::Cache.lookup_store(:memory_store)
19
- I18n.cache_key_digest = nil
20
- end
21
-
22
- def teardown
23
- super
24
- I18n.cache_store = nil
25
- end
26
-
27
- test "it uses the cache" do
28
- assert I18n.cache_store.is_a?(ActiveSupport::Cache::MemoryStore)
29
- end
30
-
31
- test "translate hits the backend and caches the response" do
32
- I18n.backend.expects(:lookup).returns('Foo')
33
- assert_equal 'Foo', I18n.t(:foo)
34
-
35
- I18n.backend.expects(:lookup).never
36
- assert_equal 'Foo', I18n.t(:foo)
37
-
38
- I18n.backend.expects(:lookup).returns('Bar')
39
- assert_equal 'Bar', I18n.t(:bar)
40
- end
41
-
42
- test "translate returns a cached false response" do
43
- I18n.backend.expects(:lookup).never
44
- I18n.cache_store.expects(:read).returns(false)
45
- assert_equal false, I18n.t(:foo)
46
- end
47
-
48
- test "still raises MissingTranslationData but also caches it" do
49
- assert_raise(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
50
- assert_raise(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
51
- assert_equal 1, I18n.cache_store.instance_variable_get(:@data).size
52
-
53
- # I18n.backend.expects(:lookup).returns(nil)
54
- # assert_raise(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
55
- # I18n.backend.expects(:lookup).never
56
- # assert_raise(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
57
- end
58
-
59
- test "uses 'i18n' as a cache key namespace by default" do
60
- assert_equal 0, I18n.backend.send(:cache_key, :en, :foo, {}).index('i18n')
61
- end
62
-
63
- test "adds a custom cache key namespace" do
64
- with_cache_namespace('bar') do
65
- assert_equal 0, I18n.backend.send(:cache_key, :en, :foo, {}).index('i18n/bar/')
66
- end
67
- end
68
-
69
- test "adds locale and hash of key and hash of options" do
70
- options = { :bar=>1 }
71
- options_hash = RUBY_VERSION <= "1.9" ? options.inspect.hash : options.hash
72
- assert_equal "i18n//en/#{:foo.hash}/#{options_hash}", I18n.backend.send(:cache_key, :en, :foo, options)
73
- end
74
-
75
- test "cache_key uses configured digest method" do
76
- md5 = Digest::MD5.new
77
- options = { :bar=>1 }
78
- options_hash = options.inspect
79
- with_cache_key_digest(md5) do
80
- assert_equal "i18n//en/#{md5.hexdigest(:foo.to_s)}/#{md5.hexdigest(options_hash)}", I18n.backend.send(:cache_key, :en, :foo, options)
81
- end
82
- end
83
-
84
- test "keys should not be equal" do
85
- interpolation_values1 = { :foo => 1, :bar => 2 }
86
- interpolation_values2 = { :foo => 2, :bar => 1 }
87
-
88
- key1 = I18n.backend.send(:cache_key, :en, :some_key, interpolation_values1)
89
- key2 = I18n.backend.send(:cache_key, :en, :some_key, interpolation_values2)
90
-
91
- assert key1 != key2
92
- end
93
-
94
- protected
95
-
96
- def with_cache_namespace(namespace)
97
- I18n.cache_namespace = namespace
98
- yield
99
- I18n.cache_namespace = nil
100
- end
101
-
102
- def with_cache_key_digest(digest)
103
- I18n.cache_key_digest = digest
104
- yield
105
- I18n.cache_key_digest = nil
106
- end
107
- end
108
-
109
- end # AS cache check
@@ -1,86 +0,0 @@
1
- require 'test_helper'
2
-
3
- class I18nBackendCascadeTest < I18n::TestCase
4
- class Backend < I18n::Backend::Simple
5
- include I18n::Backend::Cascade
6
- end
7
-
8
- def setup
9
- super
10
- I18n.backend = Backend.new
11
- store_translations(:en, :foo => 'foo', :bar => { :baz => 'baz' })
12
- @cascade_options = { :step => 1, :offset => 1, :skip_root => false }
13
- end
14
-
15
- def lookup(key, options = {})
16
- I18n.t(key, options.merge(:cascade => @cascade_options))
17
- end
18
-
19
- test "still returns an existing translation as usual" do
20
- assert_equal 'foo', lookup(:foo)
21
- assert_equal 'baz', lookup(:'bar.baz')
22
- end
23
-
24
- test "falls back by cutting keys off the end of the scope" do
25
- assert_equal 'foo', lookup(:foo, :scope => :'missing')
26
- assert_equal 'foo', lookup(:foo, :scope => :'missing.missing')
27
- assert_equal 'baz', lookup(:baz, :scope => :'bar.missing')
28
- assert_equal 'baz', lookup(:baz, :scope => :'bar.missing.missing')
29
- end
30
-
31
- test "raises I18n::MissingTranslationData exception when no translation was found" do
32
- assert_raise(I18n::MissingTranslationData) { lookup(:'foo.missing', :raise => true) }
33
- assert_raise(I18n::MissingTranslationData) { lookup(:'bar.baz.missing', :raise => true) }
34
- assert_raise(I18n::MissingTranslationData) { lookup(:'missing.bar.baz', :raise => true) }
35
- end
36
-
37
- test "cascades before evaluating the default" do
38
- assert_equal 'foo', lookup(:foo, :scope => :missing, :default => 'default')
39
- end
40
-
41
- test "cascades defaults, too" do
42
- assert_equal 'foo', lookup(nil, :default => [:'missing.missing', :'missing.foo'])
43
- end
44
-
45
- test "works with :offset => 2 and a single key" do
46
- @cascade_options[:offset] = 2
47
- lookup(:foo)
48
- end
49
-
50
- test "assemble required fallbacks for ActiveRecord validation messages" do
51
- store_translations(:en,
52
- :errors => {
53
- :odd => 'errors.odd',
54
- :reply => { :title => { :blank => 'errors.reply.title.blank' }, :taken => 'errors.reply.taken' },
55
- :topic => { :title => { :format => 'errors.topic.title.format' }, :length => 'errors.topic.length' }
56
- }
57
- )
58
- assert_equal 'errors.reply.title.blank', lookup(:'errors.reply.title.blank', :default => :'errors.topic.title.blank')
59
- assert_equal 'errors.reply.taken', lookup(:'errors.reply.title.taken', :default => :'errors.topic.title.taken')
60
- assert_equal 'errors.topic.title.format', lookup(:'errors.reply.title.format', :default => :'errors.topic.title.format')
61
- assert_equal 'errors.topic.length', lookup(:'errors.reply.title.length', :default => :'errors.topic.title.length')
62
- assert_equal 'errors.odd', lookup(:'errors.reply.title.odd', :default => :'errors.topic.title.odd')
63
- end
64
-
65
- test "assemble action view translation helper lookup cascade" do
66
- @cascade_options[:offset] = 2
67
-
68
- store_translations(:en,
69
- :menu => { :show => 'menu.show' },
70
- :namespace => {
71
- :menu => { :new => 'namespace.menu.new' },
72
- :controller => {
73
- :menu => { :edit => 'namespace.controller.menu.edit' },
74
- :action => {
75
- :menu => { :destroy => 'namespace.controller.action.menu.destroy' }
76
- }
77
- }
78
- }
79
- )
80
-
81
- assert_equal 'menu.show', lookup(:'namespace.controller.action.menu.show')
82
- assert_equal 'namespace.menu.new', lookup(:'namespace.controller.action.menu.new')
83
- assert_equal 'namespace.controller.menu.edit', lookup(:'namespace.controller.action.menu.edit')
84
- assert_equal 'namespace.controller.action.menu.destroy', lookup(:'namespace.controller.action.menu.destroy')
85
- end
86
- end
@@ -1,122 +0,0 @@
1
- require 'test_helper'
2
-
3
- class I18nBackendChainTest < I18n::TestCase
4
- def setup
5
- super
6
- @first = backend(:en => {
7
- :foo => 'Foo', :formats => {
8
- :short => 'short',
9
- :subformats => {:short => 'short'},
10
- },
11
- :plural_1 => { :one => '%{count}' },
12
- :dates => {:a => "A"}
13
- })
14
- @second = backend(:en => {
15
- :bar => 'Bar', :formats => {
16
- :long => 'long',
17
- :subformats => {:long => 'long'},
18
- },
19
- :plural_2 => { :one => 'one' },
20
- :dates => {:a => "B", :b => "B"}
21
- })
22
- @chain = I18n.backend = I18n::Backend::Chain.new(@first, @second)
23
- end
24
-
25
- test "looks up translations from the first chained backend" do
26
- assert_equal 'Foo', @first.send(:translations)[:en][:foo]
27
- assert_equal 'Foo', I18n.t(:foo)
28
- end
29
-
30
- test "looks up translations from the second chained backend" do
31
- assert_equal 'Bar', @second.send(:translations)[:en][:bar]
32
- assert_equal 'Bar', I18n.t(:bar)
33
- end
34
-
35
- test "defaults only apply to lookups on the last backend in the chain" do
36
- assert_equal 'Foo', I18n.t(:foo, :default => 'Bah')
37
- assert_equal 'Bar', I18n.t(:bar, :default => 'Bah')
38
- assert_equal 'Bah', I18n.t(:bah, :default => 'Bah') # default kicks in only here
39
- end
40
-
41
- test "default" do
42
- assert_equal 'Fuh', I18n.t(:default => 'Fuh')
43
- assert_equal 'Zero', I18n.t(:default => { :zero => 'Zero' }, :count => 0)
44
- assert_equal({ :zero => 'Zero' }, I18n.t(:default => { :zero => 'Zero' }))
45
- assert_equal 'Foo', I18n.t(:default => :foo)
46
- end
47
-
48
- test 'default is returned if translation is missing' do
49
- assert_equal({}, I18n.t(:'i18n.transliterate.rule', :locale => 'en', :default => {}))
50
- end
51
-
52
- test "namespace lookup collects results from all backends and merges deep hashes" do
53
- assert_equal({:long=>"long", :subformats=>{:long=>"long", :short=>"short"}, :short=>"short"}, I18n.t(:formats))
54
- end
55
-
56
- test "namespace lookup collects results from all backends and lets leftmost backend take priority" do
57
- assert_equal({ :a => "A", :b => "B" }, I18n.t(:dates))
58
- end
59
-
60
- test "namespace lookup with only the first backend returning a result" do
61
- assert_equal({ :one => '%{count}' }, I18n.t(:plural_1))
62
- end
63
-
64
- test "pluralization still works" do
65
- assert_equal '1', I18n.t(:plural_1, :count => 1)
66
- assert_equal 'one', I18n.t(:plural_2, :count => 1)
67
- end
68
-
69
- test "bulk lookup collects results from all backends" do
70
- assert_equal ['Foo', 'Bar'], I18n.t([:foo, :bar])
71
- assert_equal ['Foo', 'Bar', 'Bah'], I18n.t([:foo, :bar, :bah], :default => 'Bah')
72
- assert_equal [{
73
- :long=>"long",
74
- :subformats=>{:long=>"long", :short=>"short"},
75
- :short=>"short"}, {:one=>"one"},
76
- "Bah"], I18n.t([:formats, :plural_2, :bah], :default => 'Bah')
77
- end
78
-
79
- test "store_translations options are not dropped while transfering to backend" do
80
- @first.expects(:store_translations).with(:foo, {:bar => :baz}, {:option => 'persists'})
81
- I18n.backend.store_translations :foo, {:bar => :baz}, {:option => 'persists'}
82
- end
83
-
84
- protected
85
-
86
- def backend(translations)
87
- backend = I18n::Backend::Simple.new
88
- translations.each { |locale, data| backend.store_translations(locale, data) }
89
- backend
90
- end
91
- end
92
-
93
- class I18nBackendChainWithKeyValueTest < I18n::TestCase
94
- def setup_backend!(subtrees = true)
95
- first = I18n::Backend::KeyValue.new({}, subtrees)
96
- first.store_translations(:en, :plural_1 => { :one => '%{count}' })
97
-
98
- second = I18n::Backend::Simple.new
99
- second.store_translations(:en, :plural_2 => { :one => 'one' })
100
- I18n.backend = I18n::Backend::Chain.new(first, second)
101
- end
102
-
103
- test "subtrees enabled: looks up pluralization translations from the first chained backend" do
104
- setup_backend!
105
- assert_equal '1', I18n.t(:plural_1, count: 1)
106
- end
107
-
108
- test "subtrees disabled: looks up pluralization translations from the first chained backend" do
109
- setup_backend!(false)
110
- assert_equal '1', I18n.t(:plural_1, count: 1)
111
- end
112
-
113
- test "subtrees enabled: looks up translations from the second chained backend" do
114
- setup_backend!
115
- assert_equal 'one', I18n.t(:plural_2, count: 1)
116
- end
117
-
118
- test "subtrees disabled: looks up translations from the second chained backend" do
119
- setup_backend!(false)
120
- assert_equal 'one', I18n.t(:plural_2, count: 1)
121
- end
122
- end if I18n::TestCase.key_value?