i18n 0.9.5 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +71 -32
  3. data/lib/i18n/backend/base.rb +75 -31
  4. data/lib/i18n/backend/cache.rb +10 -11
  5. data/lib/i18n/backend/cache_file.rb +36 -0
  6. data/lib/i18n/backend/cascade.rb +3 -1
  7. data/lib/i18n/backend/chain.rb +37 -6
  8. data/lib/i18n/backend/fallbacks.rb +43 -14
  9. data/lib/i18n/backend/flatten.rb +10 -5
  10. data/lib/i18n/backend/gettext.rb +4 -2
  11. data/lib/i18n/backend/interpolation_compiler.rb +3 -1
  12. data/lib/i18n/backend/key_value.rb +31 -4
  13. data/lib/i18n/backend/lazy_loadable.rb +184 -0
  14. data/lib/i18n/backend/memoize.rb +10 -2
  15. data/lib/i18n/backend/metadata.rb +5 -3
  16. data/lib/i18n/backend/pluralization.rb +3 -1
  17. data/lib/i18n/backend/simple.rb +29 -16
  18. data/lib/i18n/backend/transliterator.rb +2 -0
  19. data/lib/i18n/backend.rb +5 -1
  20. data/lib/i18n/config.rb +20 -2
  21. data/lib/i18n/exceptions.rb +60 -17
  22. data/lib/i18n/gettext/helpers.rb +4 -2
  23. data/lib/i18n/gettext/po_parser.rb +7 -7
  24. data/lib/i18n/gettext.rb +2 -0
  25. data/lib/i18n/interpolate/ruby.rb +8 -6
  26. data/lib/i18n/locale/fallbacks.rb +21 -20
  27. data/lib/i18n/locale/tag/parents.rb +8 -6
  28. data/lib/i18n/locale/tag/simple.rb +1 -1
  29. data/lib/i18n/locale.rb +2 -0
  30. data/lib/i18n/middleware.rb +2 -0
  31. data/lib/i18n/tests/basics.rb +3 -5
  32. data/lib/i18n/tests/defaults.rb +1 -1
  33. data/lib/i18n/tests/interpolation.rb +12 -7
  34. data/lib/i18n/tests/link.rb +11 -1
  35. data/lib/i18n/tests/localization/date.rb +32 -10
  36. data/lib/i18n/tests/localization/date_time.rb +28 -7
  37. data/lib/i18n/tests/localization/procs.rb +7 -5
  38. data/lib/i18n/tests/localization/time.rb +27 -5
  39. data/lib/i18n/tests/lookup.rb +4 -4
  40. data/lib/i18n/tests/pluralization.rb +1 -1
  41. data/lib/i18n/tests/procs.rb +12 -1
  42. data/lib/i18n/tests.rb +2 -0
  43. data/lib/i18n/utils.rb +55 -0
  44. data/lib/i18n/version.rb +3 -1
  45. data/lib/i18n.rb +123 -50
  46. metadata +16 -61
  47. data/gemfiles/Gemfile.rails-3.2.x +0 -10
  48. data/gemfiles/Gemfile.rails-4.0.x +0 -10
  49. data/gemfiles/Gemfile.rails-4.1.x +0 -10
  50. data/gemfiles/Gemfile.rails-4.2.x +0 -10
  51. data/gemfiles/Gemfile.rails-5.0.x +0 -10
  52. data/gemfiles/Gemfile.rails-5.1.x +0 -10
  53. data/gemfiles/Gemfile.rails-master +0 -10
  54. data/lib/i18n/core_ext/hash.rb +0 -29
  55. data/lib/i18n/core_ext/kernel/suppress_warnings.rb +0 -8
  56. data/lib/i18n/core_ext/string/interpolate.rb +0 -9
  57. data/test/api/all_features_test.rb +0 -58
  58. data/test/api/cascade_test.rb +0 -28
  59. data/test/api/chain_test.rb +0 -24
  60. data/test/api/fallbacks_test.rb +0 -30
  61. data/test/api/key_value_test.rb +0 -24
  62. data/test/api/memoize_test.rb +0 -56
  63. data/test/api/override_test.rb +0 -42
  64. data/test/api/pluralization_test.rb +0 -30
  65. data/test/api/simple_test.rb +0 -28
  66. data/test/backend/cache_test.rb +0 -109
  67. data/test/backend/cascade_test.rb +0 -86
  68. data/test/backend/chain_test.rb +0 -122
  69. data/test/backend/exceptions_test.rb +0 -36
  70. data/test/backend/fallbacks_test.rb +0 -219
  71. data/test/backend/interpolation_compiler_test.rb +0 -118
  72. data/test/backend/key_value_test.rb +0 -61
  73. data/test/backend/memoize_test.rb +0 -79
  74. data/test/backend/metadata_test.rb +0 -48
  75. data/test/backend/pluralization_test.rb +0 -45
  76. data/test/backend/simple_test.rb +0 -103
  77. data/test/backend/transliterator_test.rb +0 -84
  78. data/test/core_ext/hash_test.rb +0 -36
  79. data/test/gettext/api_test.rb +0 -214
  80. data/test/gettext/backend_test.rb +0 -92
  81. data/test/i18n/exceptions_test.rb +0 -117
  82. data/test/i18n/gettext_plural_keys_test.rb +0 -20
  83. data/test/i18n/interpolate_test.rb +0 -91
  84. data/test/i18n/load_path_test.rb +0 -34
  85. data/test/i18n/middleware_test.rb +0 -24
  86. data/test/i18n_test.rb +0 -462
  87. data/test/locale/fallbacks_test.rb +0 -133
  88. data/test/locale/tag/rfc4646_test.rb +0 -143
  89. data/test/locale/tag/simple_test.rb +0 -32
  90. data/test/run_all.rb +0 -20
  91. data/test/test_data/locales/de.po +0 -82
  92. data/test/test_data/locales/en.rb +0 -3
  93. data/test/test_data/locales/en.yml +0 -3
  94. data/test/test_data/locales/invalid/empty.yml +0 -0
  95. data/test/test_data/locales/invalid/syntax.yml +0 -4
  96. data/test/test_data/locales/plurals.rb +0 -113
  97. data/test/test_helper.rb +0 -61
@@ -52,19 +52,20 @@ module I18n
52
52
  test "localize Time: given a format that resolves to a Proc it calls the Proc with the object" do
53
53
  setup_time_proc_translations
54
54
  time = ::Time.utc(2008, 3, 1, 6, 0)
55
- assert_equal I18n::Tests::Localization::Procs.inspect_args([time, {}]), I18n.l(time, :format => :proc, :locale => :ru)
55
+ assert_equal I18n::Tests::Localization::Procs.inspect_args([time], {}), I18n.l(time, :format => :proc, :locale => :ru)
56
56
  end
57
57
 
58
58
  test "localize Time: given a format that resolves to a Proc it calls the Proc with the object and extra options" do
59
59
  setup_time_proc_translations
60
60
  time = ::Time.utc(2008, 3, 1, 6, 0)
61
61
  options = { :foo => 'foo' }
62
- assert_equal I18n::Tests::Localization::Procs.inspect_args([time, options]), I18n.l(time, options.merge(:format => :proc, :locale => :ru))
62
+ assert_equal I18n::Tests::Localization::Procs.inspect_args([time], options), I18n.l(time, **options.merge(:format => :proc, :locale => :ru))
63
63
  end
64
64
 
65
65
  protected
66
66
 
67
- def self.inspect_args(args)
67
+ def self.inspect_args(args, kwargs)
68
+ args << kwargs
68
69
  args = args.map do |arg|
69
70
  case arg
70
71
  when ::Time, ::DateTime
@@ -73,6 +74,7 @@ module I18n
73
74
  arg.strftime('%a, %d %b %Y')
74
75
  when Hash
75
76
  arg.delete(:fallback_in_progress)
77
+ arg.delete(:fallback_original_locale)
76
78
  arg.inspect
77
79
  else
78
80
  arg.inspect
@@ -85,12 +87,12 @@ module I18n
85
87
  I18n.backend.store_translations :ru, {
86
88
  :time => {
87
89
  :formats => {
88
- :proc => lambda { |*args| I18n::Tests::Localization::Procs.inspect_args(args) }
90
+ :proc => lambda { |*args, **kwargs| I18n::Tests::Localization::Procs.inspect_args(args, kwargs) }
89
91
  }
90
92
  },
91
93
  :date => {
92
94
  :formats => {
93
- :proc => lambda { |*args| I18n::Tests::Localization::Procs.inspect_args(args) }
95
+ :proc => lambda { |*args, **kwargs| I18n::Tests::Localization::Procs.inspect_args(args, kwargs) }
94
96
  },
95
97
  :'day_names' => lambda { |key, options|
96
98
  (options[:format] =~ /^%A/) ?
@@ -12,8 +12,7 @@ module I18n
12
12
  end
13
13
 
14
14
  test "localize Time: given the short format it uses it" do
15
- # TODO should be Mrz, shouldn't it?
16
- assert_equal '01. Mar 06:00', I18n.l(@time, :format => :short, :locale => :de)
15
+ assert_equal '01. Mär 06:00', I18n.l(@time, :format => :short, :locale => :de)
17
16
  end
18
17
 
19
18
  test "localize Time: given the long format it uses it" do
@@ -29,17 +28,40 @@ module I18n
29
28
  assert_equal 'Samstag', I18n.l(@time, :format => '%A', :locale => :de)
30
29
  end
31
30
 
31
+ test "localize Time: given a uppercased day name format it returns the correct day name in upcase" do
32
+ assert_equal 'samstag'.upcase, I18n.l(@time, :format => '%^A', :locale => :de)
33
+ end
34
+
32
35
  test "localize Time: given an abbreviated day name format it returns the correct abbreviated day name" do
33
36
  assert_equal 'Sa', I18n.l(@time, :format => '%a', :locale => :de)
34
37
  end
35
38
 
39
+ test "localize Time: given an abbreviated and uppercased day name format it returns the correct abbreviated day name in upcase" do
40
+ assert_equal 'sa'.upcase, I18n.l(@time, :format => '%^a', :locale => :de)
41
+ end
42
+
36
43
  test "localize Time: given a month name format it returns the correct month name" do
37
44
  assert_equal 'März', I18n.l(@time, :format => '%B', :locale => :de)
38
45
  end
39
46
 
47
+ test "localize Time: given a uppercased month name format it returns the correct month name in upcase" do
48
+ assert_equal 'märz'.upcase, I18n.l(@time, :format => '%^B', :locale => :de)
49
+ end
50
+
40
51
  test "localize Time: given an abbreviated month name format it returns the correct abbreviated month name" do
41
- # TODO should be Mrz, shouldn't it?
42
- assert_equal 'Mar', I18n.l(@time, :format => '%b', :locale => :de)
52
+ assert_equal 'Mär', I18n.l(@time, :format => '%b', :locale => :de)
53
+ end
54
+
55
+ test "localize Time: given an abbreviated and uppercased month name format it returns the correct abbreviated month name in upcase" do
56
+ assert_equal 'mär'.upcase, I18n.l(@time, :format => '%^b', :locale => :de)
57
+ end
58
+
59
+ test "localize Time: given a date format with the month name upcased it returns the correct value" do
60
+ assert_equal '1. FEBRUAR 2008', I18n.l(::Time.utc(2008, 2, 1, 6, 0), :format => "%-d. %^B %Y", :locale => :de)
61
+ end
62
+
63
+ test "localize Time: given missing translations it returns the correct error message" do
64
+ assert_equal 'translation missing: fr.date.abbr_month_names', I18n.l(@time, :format => '%b', :locale => :fr)
43
65
  end
44
66
 
45
67
  test "localize Time: given a meridian indicator format it returns the correct meridian indicator" do
@@ -57,7 +79,7 @@ module I18n
57
79
  end
58
80
 
59
81
  test "localize Time: given a format is missing it raises I18n::MissingTranslationData" do
60
- assert_raise(I18n::MissingTranslationData) { I18n.l(@time, :format => :missing) }
82
+ assert_raises(I18n::MissingTranslationData) { I18n.l(@time, :format => :missing) }
61
83
  end
62
84
 
63
85
  protected
@@ -34,7 +34,7 @@ module I18n
34
34
  end
35
35
 
36
36
  test "lookup: given a missing key, no default and the raise option it raises MissingTranslationData" do
37
- assert_raise(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
37
+ assert_raises(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
38
38
  end
39
39
 
40
40
  test "lookup: does not raise an exception if no translation data is present for the given locale" do
@@ -43,9 +43,9 @@ module I18n
43
43
 
44
44
  test "lookup: does not modify the options hash" do
45
45
  options = {}
46
- assert_equal "a", I18n.t(:string, options)
46
+ assert_equal "a", I18n.t(:string, **options)
47
47
  assert_equal({}, options)
48
- assert_nothing_raised { I18n.t(:string, options.freeze) }
48
+ assert_nothing_raised { I18n.t(:string, **options.freeze) }
49
49
  end
50
50
 
51
51
  test "lookup: given an array of keys it translates all of them" do
@@ -61,7 +61,7 @@ module I18n
61
61
  # In fact it probably *should* fail but Rails currently relies on using the default locale instead.
62
62
  # So we'll stick to this for now until we get it fixed in Rails.
63
63
  test "lookup: given nil as a locale it does not raise but use the default locale" do
64
- # assert_raise(I18n::InvalidLocale) { I18n.t(:bar, :locale => nil) }
64
+ # assert_raises(I18n::InvalidLocale) { I18n.t(:bar, :locale => nil) }
65
65
  assert_nothing_raised { I18n.t(:bar, :locale => nil) }
66
66
  end
67
67
 
@@ -28,7 +28,7 @@ module I18n
28
28
  end
29
29
 
30
30
  test "pluralization: given incomplete pluralization data it raises I18n::InvalidPluralizationData" do
31
- assert_raise(I18n::InvalidPluralizationData) { I18n.t(:default => { :one => 'bar' }, :count => 2) }
31
+ assert_raises(I18n::InvalidPluralizationData) { I18n.t(:default => { :one => 'bar' }, :count => 2) }
32
32
  end
33
33
  end
34
34
  end
@@ -8,6 +8,11 @@ module I18n
8
8
  assert_equal '[:a_lambda, {:foo=>"foo"}]', I18n.t(:a_lambda, :foo => 'foo')
9
9
  end
10
10
 
11
+ test "lookup: given a translation is a proc it passes the interpolation values as keyword arguments" do
12
+ I18n.backend.store_translations(:en, :a_lambda => lambda { |key, foo:, **| I18n::Tests::Procs.filter_args(key, foo: foo) })
13
+ assert_equal '[:a_lambda, {:foo=>"foo"}]', I18n.t(:a_lambda, :foo => 'foo')
14
+ end
15
+
11
16
  test "defaults: given a default is a Proc it calls it with the key and interpolation values" do
12
17
  proc = lambda { |*args| I18n::Tests::Procs.filter_args(*args) }
13
18
  assert_equal '[nil, {:foo=>"foo"}]', I18n.t(nil, :default => proc, :foo => 'foo')
@@ -48,7 +53,13 @@ module I18n
48
53
 
49
54
 
50
55
  def self.filter_args(*args)
51
- args.map {|arg| arg.delete(:fallback_in_progress) if arg.is_a?(Hash) ; arg }.inspect
56
+ args.map do |arg|
57
+ if arg.is_a?(Hash)
58
+ arg.delete(:fallback_in_progress)
59
+ arg.delete(:fallback_original_locale)
60
+ end
61
+ arg
62
+ end.inspect
52
63
  end
53
64
  end
54
65
  end
data/lib/i18n/tests.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module I18n
2
4
  module Tests
3
5
  autoload :Basics, 'i18n/tests/basics'
data/lib/i18n/utils.rb ADDED
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module I18n
4
+ module Utils
5
+ class << self
6
+ if Hash.method_defined?(:except)
7
+ def except(hash, *keys)
8
+ hash.except(*keys)
9
+ end
10
+ else
11
+ def except(hash, *keys)
12
+ hash = hash.dup
13
+ keys.each { |k| hash.delete(k) }
14
+ hash
15
+ end
16
+ end
17
+
18
+ def deep_merge(hash, other_hash, &block)
19
+ deep_merge!(hash.dup, other_hash, &block)
20
+ end
21
+
22
+ def deep_merge!(hash, other_hash, &block)
23
+ hash.merge!(other_hash) do |key, this_val, other_val|
24
+ if this_val.is_a?(Hash) && other_val.is_a?(Hash)
25
+ deep_merge(this_val, other_val, &block)
26
+ elsif block_given?
27
+ yield key, this_val, other_val
28
+ else
29
+ other_val
30
+ end
31
+ end
32
+ end
33
+
34
+ def deep_symbolize_keys(hash)
35
+ hash.each_with_object({}) do |(key, value), result|
36
+ result[key.respond_to?(:to_sym) ? key.to_sym : key] = deep_symbolize_keys_in_object(value)
37
+ result
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def deep_symbolize_keys_in_object(value)
44
+ case value
45
+ when Hash
46
+ deep_symbolize_keys(value)
47
+ when Array
48
+ value.map { |e| deep_symbolize_keys_in_object(e) }
49
+ else
50
+ value
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
data/lib/i18n/version.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module I18n
2
- VERSION = "0.9.5"
4
+ VERSION = "1.10.0"
3
5
  end
data/lib/i18n.rb CHANGED
@@ -1,6 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'concurrent/map'
4
+ require 'concurrent/hash'
2
5
 
3
6
  require 'i18n/version'
7
+ require 'i18n/utils'
4
8
  require 'i18n/exceptions'
5
9
  require 'i18n/interpolate/ruby'
6
10
 
@@ -12,12 +16,39 @@ module I18n
12
16
  autoload :Tests, 'i18n/tests'
13
17
  autoload :Middleware, 'i18n/middleware'
14
18
 
15
- RESERVED_KEYS = [:scope, :default, :separator, :resolve, :object, :fallback, :fallback_in_progress, :format, :cascade, :throw, :raise, :deep_interpolation]
16
- RESERVED_KEYS_PATTERN = /%\{(#{RESERVED_KEYS.join("|")})\}/
17
-
19
+ RESERVED_KEYS = %i[
20
+ cascade
21
+ deep_interpolation
22
+ default
23
+ exception_handler
24
+ fallback
25
+ fallback_in_progress
26
+ fallback_original_locale
27
+ format
28
+ object
29
+ raise
30
+ resolve
31
+ scope
32
+ separator
33
+ throw
34
+ ]
35
+ EMPTY_HASH = {}.freeze
18
36
 
19
37
  def self.new_double_nested_cache # :nodoc:
20
- Concurrent::Map.new { |h,k| h[k] = Concurrent::Map.new }
38
+ Concurrent::Map.new { |h, k| h[k] = Concurrent::Map.new }
39
+ end
40
+
41
+ # Marks a key as reserved. Reserved keys are used internally,
42
+ # and can't also be used for interpolation. If you are using any
43
+ # extra keys as I18n options, you should call I18n.reserve_key
44
+ # before any I18n.translate (etc) calls are made.
45
+ def self.reserve_key(key)
46
+ RESERVED_KEYS << key.to_sym
47
+ @reserved_keys_pattern = nil
48
+ end
49
+
50
+ def self.reserved_keys_pattern # :nodoc:
51
+ @reserved_keys_pattern ||= /%\{(#{RESERVED_KEYS.join("|")})\}/
21
52
  end
22
53
 
23
54
  module Base
@@ -53,6 +84,13 @@ module I18n
53
84
  config.backend.reload!
54
85
  end
55
86
 
87
+ # Tells the backend to load translations now. Used in situations like the
88
+ # Rails production environment. Backends can implement whatever strategy
89
+ # is useful.
90
+ def eager_load!
91
+ config.backend.eager_load!
92
+ end
93
+
56
94
  # Translates, pluralizes and interpolates a given key using a given locale,
57
95
  # scope, and default, as well as interpolation values.
58
96
  #
@@ -92,7 +130,7 @@ module I18n
92
130
  # *PLURALIZATION*
93
131
  #
94
132
  # Translation data can contain pluralized translations. Pluralized translations
95
- # are arrays of singluar/plural versions of translations like <tt>['Foo', 'Foos']</tt>.
133
+ # are arrays of singular/plural versions of translations like <tt>['Foo', 'Foos']</tt>.
96
134
  #
97
135
  # Note that <tt>I18n::Backend::Simple</tt> only supports an algorithm for English
98
136
  # pluralization rules. Other algorithms can be supported by custom backends.
@@ -150,18 +188,32 @@ module I18n
150
188
  #
151
189
  # It is recommended to use/implement lambdas in an "idempotent" way. E.g. when
152
190
  # a cache layer is put in front of I18n.translate it will generate a cache key
153
- # from the argument values passed to #translate. Therefor your lambdas should
191
+ # from the argument values passed to #translate. Therefore your lambdas should
154
192
  # always return the same translations/values per unique combination of argument
155
193
  # values.
156
- def translate(*args)
157
- options = args.last.is_a?(Hash) ? args.pop.dup : {}
158
- key = args.shift
159
- backend = config.backend
160
- locale = options.delete(:locale) || config.locale
161
- handling = options.delete(:throw) && :throw || options.delete(:raise) && :raise # TODO deprecate :raise
162
-
194
+ #
195
+ # *Ruby 2.7+ keyword arguments warning*
196
+ #
197
+ # This method uses keyword arguments.
198
+ # There is a breaking change in ruby that produces warning with ruby 2.7 and won't work as expected with ruby 3.0
199
+ # The "hash" parameter must be passed as keyword argument.
200
+ #
201
+ # Good:
202
+ # I18n.t(:salutation, :gender => 'w', :name => 'Smith')
203
+ # I18n.t(:salutation, **{ :gender => 'w', :name => 'Smith' })
204
+ # I18n.t(:salutation, **any_hash)
205
+ #
206
+ # Bad:
207
+ # I18n.t(:salutation, { :gender => 'w', :name => 'Smith' })
208
+ # I18n.t(:salutation, any_hash)
209
+ #
210
+ def translate(key = nil, throw: false, raise: false, locale: nil, **options) # TODO deprecate :raise
211
+ locale ||= config.locale
212
+ raise Disabled.new('t') if locale == false
163
213
  enforce_available_locales!(locale)
164
214
 
215
+ backend = config.backend
216
+
165
217
  result = catch(:exception) do
166
218
  if key.is_a?(Array)
167
219
  key.map { |k| backend.translate(locale, k, options) }
@@ -169,21 +221,28 @@ module I18n
169
221
  backend.translate(locale, key, options)
170
222
  end
171
223
  end
172
- result.is_a?(MissingTranslation) ? handle_exception(handling, result, locale, key, options) : result
224
+
225
+ if result.is_a?(MissingTranslation)
226
+ handle_exception((throw && :throw || raise && :raise), result, locale, key, options)
227
+ else
228
+ result
229
+ end
173
230
  end
174
231
  alias :t :translate
175
232
 
176
233
  # Wrapper for <tt>translate</tt> that adds <tt>:raise => true</tt>. With
177
234
  # this option, if no translation is found, it will raise <tt>I18n::MissingTranslationData</tt>
178
- def translate!(key, options={})
179
- translate(key, options.merge(:raise => true))
235
+ def translate!(key, **options)
236
+ translate(key, **options, raise: true)
180
237
  end
181
238
  alias :t! :translate!
182
239
 
183
240
  # Returns true if a translation exists for a given key, otherwise returns false.
184
- def exists?(key, locale = config.locale)
241
+ def exists?(key, _locale = nil, locale: _locale, **options)
242
+ locale ||= config.locale
243
+ raise Disabled.new('exists?') if locale == false
185
244
  raise I18n::ArgumentError if key.is_a?(String) && key.empty?
186
- config.backend.exists?(locale, key)
245
+ config.backend.exists?(locale, key, options)
187
246
  end
188
247
 
189
248
  # Transliterates UTF-8 characters to ASCII. By default this method will
@@ -215,14 +274,14 @@ module I18n
215
274
  #
216
275
  # Setting a Hash using Ruby:
217
276
  #
218
- # store_translations(:de, :i18n => {
219
- # :transliterate => {
220
- # :rule => {
221
- # "ü" => "ue",
222
- # "ö" => "oe"
223
- # }
224
- # }
225
- # )
277
+ # store_translations(:de, i18n: {
278
+ # transliterate: {
279
+ # rule: {
280
+ # 'ü' => 'ue',
281
+ # 'ö' => 'oe'
282
+ # }
283
+ # }
284
+ # })
226
285
  #
227
286
  # Setting a Proc:
228
287
  #
@@ -237,37 +296,40 @@ module I18n
237
296
  # I18n.transliterate("Jürgen") # => "Juergen"
238
297
  # I18n.transliterate("Jürgen", :locale => :en) # => "Jurgen"
239
298
  # I18n.transliterate("Jürgen", :locale => :de) # => "Juergen"
240
- def transliterate(*args)
241
- options = args.pop.dup if args.last.is_a?(Hash)
242
- key = args.shift
243
- locale = options && options.delete(:locale) || config.locale
244
- handling = options && (options.delete(:throw) && :throw || options.delete(:raise) && :raise)
245
- replacement = options && options.delete(:replacement)
299
+ def transliterate(key, throw: false, raise: false, locale: nil, replacement: nil, **options)
300
+ locale ||= config.locale
301
+ raise Disabled.new('transliterate') if locale == false
246
302
  enforce_available_locales!(locale)
303
+
247
304
  config.backend.transliterate(locale, key, replacement)
248
305
  rescue I18n::ArgumentError => exception
249
- handle_exception(handling, exception, locale, key, options || {})
306
+ handle_exception((throw && :throw || raise && :raise), exception, locale, key, options)
250
307
  end
251
308
 
252
309
  # Localizes certain objects, such as dates and numbers to local formatting.
253
- def localize(object, options = nil)
254
- options = options ? options.dup : {}
255
- locale = options.delete(:locale) || config.locale
256
- format = options.delete(:format) || :default
310
+ def localize(object, locale: nil, format: nil, **options)
311
+ locale ||= config.locale
312
+ raise Disabled.new('l') if locale == false
257
313
  enforce_available_locales!(locale)
314
+
315
+ format ||= :default
258
316
  config.backend.localize(locale, object, format, options)
259
317
  end
260
318
  alias :l :localize
261
319
 
262
320
  # Executes block with given I18n.locale set.
263
321
  def with_locale(tmp_locale = nil)
264
- if tmp_locale
322
+ if tmp_locale == nil
323
+ yield
324
+ else
265
325
  current_locale = self.locale
266
- self.locale = tmp_locale
326
+ self.locale = tmp_locale
327
+ begin
328
+ yield
329
+ ensure
330
+ self.locale = current_locale
331
+ end
267
332
  end
268
- yield
269
- ensure
270
- self.locale = current_locale if tmp_locale
271
333
  end
272
334
 
273
335
  # Merges the given locale, key and scope into a single array of keys.
@@ -276,11 +338,11 @@ module I18n
276
338
  def normalize_keys(locale, key, scope, separator = nil)
277
339
  separator ||= I18n.default_separator
278
340
 
279
- keys = []
280
- keys.concat normalize_key(locale, separator)
281
- keys.concat normalize_key(scope, separator)
282
- keys.concat normalize_key(key, separator)
283
- keys
341
+ [
342
+ *normalize_key(locale, separator),
343
+ *normalize_key(scope, separator),
344
+ *normalize_key(key, separator)
345
+ ]
284
346
  end
285
347
 
286
348
  # Returns true when the passed locale, which can be either a String or a
@@ -291,7 +353,7 @@ module I18n
291
353
 
292
354
  # Raises an InvalidLocale exception when the passed locale is not available.
293
355
  def enforce_available_locales!(locale)
294
- if config.enforce_available_locales
356
+ if locale != false && config.enforce_available_locales
295
357
  raise I18n::InvalidLocale.new(locale) if !locale_available?(locale)
296
358
  end
297
359
  end
@@ -342,11 +404,22 @@ module I18n
342
404
  @@normalized_key_cache[separator][key] ||=
343
405
  case key
344
406
  when Array
345
- key.map { |k| normalize_key(k, separator) }.flatten
407
+ key.flat_map { |k| normalize_key(k, separator) }
346
408
  else
347
409
  keys = key.to_s.split(separator)
348
410
  keys.delete('')
349
- keys.map! { |k| k.to_sym }
411
+ keys.map! do |k|
412
+ case k
413
+ when /\A[-+]?([1-9]\d*|0)\z/ # integer
414
+ k.to_i
415
+ when 'true'
416
+ true
417
+ when 'false'
418
+ false
419
+ else
420
+ k.to_sym
421
+ end
422
+ end
350
423
  keys
351
424
  end
352
425
  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.9.5
4
+ version: 1.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Fuchs
@@ -10,10 +10,10 @@ authors:
10
10
  - Stephan Soller
11
11
  - Saimon Moore
12
12
  - Ryan Bigg
13
- autorequire:
13
+ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2018-02-13 00:00:00.000000000 Z
16
+ date: 2022-02-14 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: concurrent-ruby
@@ -37,17 +37,11 @@ extra_rdoc_files: []
37
37
  files:
38
38
  - MIT-LICENSE
39
39
  - README.md
40
- - gemfiles/Gemfile.rails-3.2.x
41
- - gemfiles/Gemfile.rails-4.0.x
42
- - gemfiles/Gemfile.rails-4.1.x
43
- - gemfiles/Gemfile.rails-4.2.x
44
- - gemfiles/Gemfile.rails-5.0.x
45
- - gemfiles/Gemfile.rails-5.1.x
46
- - gemfiles/Gemfile.rails-master
47
40
  - lib/i18n.rb
48
41
  - lib/i18n/backend.rb
49
42
  - lib/i18n/backend/base.rb
50
43
  - lib/i18n/backend/cache.rb
44
+ - lib/i18n/backend/cache_file.rb
51
45
  - lib/i18n/backend/cascade.rb
52
46
  - lib/i18n/backend/chain.rb
53
47
  - lib/i18n/backend/fallbacks.rb
@@ -55,15 +49,13 @@ files:
55
49
  - lib/i18n/backend/gettext.rb
56
50
  - lib/i18n/backend/interpolation_compiler.rb
57
51
  - lib/i18n/backend/key_value.rb
52
+ - lib/i18n/backend/lazy_loadable.rb
58
53
  - lib/i18n/backend/memoize.rb
59
54
  - lib/i18n/backend/metadata.rb
60
55
  - lib/i18n/backend/pluralization.rb
61
56
  - lib/i18n/backend/simple.rb
62
57
  - lib/i18n/backend/transliterator.rb
63
58
  - lib/i18n/config.rb
64
- - lib/i18n/core_ext/hash.rb
65
- - lib/i18n/core_ext/kernel/suppress_warnings.rb
66
- - lib/i18n/core_ext/string/interpolate.rb
67
59
  - lib/i18n/exceptions.rb
68
60
  - lib/i18n/gettext.rb
69
61
  - lib/i18n/gettext/helpers.rb
@@ -89,53 +81,17 @@ files:
89
81
  - lib/i18n/tests/lookup.rb
90
82
  - lib/i18n/tests/pluralization.rb
91
83
  - lib/i18n/tests/procs.rb
84
+ - lib/i18n/utils.rb
92
85
  - lib/i18n/version.rb
93
- - test/api/all_features_test.rb
94
- - test/api/cascade_test.rb
95
- - test/api/chain_test.rb
96
- - test/api/fallbacks_test.rb
97
- - test/api/key_value_test.rb
98
- - test/api/memoize_test.rb
99
- - test/api/override_test.rb
100
- - test/api/pluralization_test.rb
101
- - test/api/simple_test.rb
102
- - test/backend/cache_test.rb
103
- - test/backend/cascade_test.rb
104
- - test/backend/chain_test.rb
105
- - test/backend/exceptions_test.rb
106
- - test/backend/fallbacks_test.rb
107
- - test/backend/interpolation_compiler_test.rb
108
- - test/backend/key_value_test.rb
109
- - test/backend/memoize_test.rb
110
- - test/backend/metadata_test.rb
111
- - test/backend/pluralization_test.rb
112
- - test/backend/simple_test.rb
113
- - test/backend/transliterator_test.rb
114
- - test/core_ext/hash_test.rb
115
- - test/gettext/api_test.rb
116
- - test/gettext/backend_test.rb
117
- - test/i18n/exceptions_test.rb
118
- - test/i18n/gettext_plural_keys_test.rb
119
- - test/i18n/interpolate_test.rb
120
- - test/i18n/load_path_test.rb
121
- - test/i18n/middleware_test.rb
122
- - test/i18n_test.rb
123
- - test/locale/fallbacks_test.rb
124
- - test/locale/tag/rfc4646_test.rb
125
- - test/locale/tag/simple_test.rb
126
- - test/run_all.rb
127
- - test/test_data/locales/de.po
128
- - test/test_data/locales/en.rb
129
- - test/test_data/locales/en.yml
130
- - test/test_data/locales/invalid/empty.yml
131
- - test/test_data/locales/invalid/syntax.yml
132
- - test/test_data/locales/plurals.rb
133
- - test/test_helper.rb
134
- homepage: http://github.com/svenfuchs/i18n
86
+ homepage: https://github.com/ruby-i18n/i18n
135
87
  licenses:
136
88
  - MIT
137
- metadata: {}
138
- post_install_message:
89
+ metadata:
90
+ bug_tracker_uri: https://github.com/ruby-i18n/i18n/issues
91
+ changelog_uri: https://github.com/ruby-i18n/i18n/releases
92
+ documentation_uri: https://guides.rubyonrails.org/i18n.html
93
+ source_code_uri: https://github.com/ruby-i18n/i18n
94
+ post_install_message:
139
95
  rdoc_options: []
140
96
  require_paths:
141
97
  - lib
@@ -143,16 +99,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
143
99
  requirements:
144
100
  - - ">="
145
101
  - !ruby/object:Gem::Version
146
- version: 1.9.3
102
+ version: 2.3.0
147
103
  required_rubygems_version: !ruby/object:Gem::Requirement
148
104
  requirements:
149
105
  - - ">="
150
106
  - !ruby/object:Gem::Version
151
107
  version: 1.3.5
152
108
  requirements: []
153
- rubyforge_project: "[none]"
154
- rubygems_version: 2.7.4
155
- signing_key:
109
+ rubygems_version: 3.1.6
110
+ signing_key:
156
111
  specification_version: 4
157
112
  summary: New wave Internationalization support for Ruby
158
113
  test_files: []
@@ -1,10 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec :path => '..'
4
-
5
- gem 'activesupport', '~> 3.2.0'
6
- gem 'mocha'
7
- gem 'test_declarative'
8
- gem 'rake'
9
- gem 'minitest'
10
- gem 'oj'