i18n 1.4.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8261641c6a20a87755f261c21a4148f5b414577c2fbc127b31ffaf59e93bb88e
4
- data.tar.gz: 8710ff18593cdab6cdd2388f3726d3da41d5a1129eade70b3cac8e8d100c804b
3
+ metadata.gz: dd80c4dac859bf40aa5a70cab46357ea469fe054757dc747d8976a243e619bb0
4
+ data.tar.gz: f396a7f27e9295a336dbccc489828439816de7dbc7b7fd5f8bd7863c907d813a
5
5
  SHA512:
6
- metadata.gz: 3a74081f5e0ad3d800857b64541ec97e0d48602bfc81b5d1e54a72ede4e8244599f9d1f3b07a0ed33eb6f2e5730c80f468e1097815fadde9f9c0c1edd63f1b10
7
- data.tar.gz: 3ff46b06293eaa68353b15a64645323da870e6afa0f8a2b5f3559983966166a950e74cf2ade96cf3a3d22cb7940d01b448feecb71ad052bf43433ebbe1da2c3c
6
+ metadata.gz: 1be60c0724e1bb2054dfaecc1f732d3a6d52e2eaa600947899938f591b0cbb3af43614d57e2157d9f6a35f18b8b3119e65cba605b32cef33c4e361be2e84f9aa
7
+ data.tar.gz: 973b4f37394853d37b10a8801cc6d3b33f934601ccd492a1c93df6f05c13cb780068403c4e12216d0a831489babd0fcec9eb04ad0c68ebbaf57a94b76ad24ed2
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Ruby I18n
2
2
 
3
- [![Build Status](https://api.travis-ci.org/svenfuchs/i18n.svg?branch=master)](https://travis-ci.org/svenfuchs/i18n)
3
+ [![Build Status](https://api.travis-ci.org/ruby-i18n/i18n.svg?branch=master)](https://travis-ci.org/ruby-i18n/i18n)
4
4
 
5
5
  Ruby Internationalization and localization solution.
6
6
 
@@ -67,7 +67,7 @@ I18n.t(:test) # => "Dies ist ein Test"
67
67
  * Cache
68
68
  * Pluralization: lambda pluralizers stored as translation data
69
69
  * Locale fallbacks, RFC4647 compliant (optionally: RFC4646 locale validation)
70
- * [Gettext support](https://github.com/svenfuchs/i18n/wiki/Gettext)
70
+ * [Gettext support](https://github.com/ruby-i18n/i18n/wiki/Gettext)
71
71
  * Translation metadata
72
72
 
73
73
  ## Alternative Backend
@@ -76,7 +76,7 @@ I18n.t(:test) # => "Dies ist ein Test"
76
76
  * ActiveRecord (optionally: ActiveRecord::Missing and ActiveRecord::StoreProcs)
77
77
  * KeyValue (uses active_support/json and cannot store procs)
78
78
 
79
- For more information and lots of resources see [the 'Resources' page on the wiki](https://github.com/svenfuchs/i18n/wiki/Resources).
79
+ For more information and lots of resources see [the 'Resources' page on the wiki](https://github.com/ruby-i18n/i18n/wiki/Resources).
80
80
 
81
81
  ## Tests
82
82
 
@@ -95,7 +95,7 @@ particular tests in different test cases.
95
95
  The reason for this is that we need to enforce the I18n API across various
96
96
  combinations of extensions. E.g. the Simple backend alone needs to support
97
97
  the same API as any combination of feature and/or optimization modules included
98
- to the Simple backend. We test this by reusing the same API defition (implemented
98
+ to the Simple backend. We test this by reusing the same API definition (implemented
99
99
  as test methods) in test cases with different setups.
100
100
 
101
101
  You can find the test cases that enforce the API in test/api. And you can find
@@ -69,6 +69,13 @@ module I18n
69
69
  config.backend.reload!
70
70
  end
71
71
 
72
+ # Tells the backend to load translations now. Used in situations like the
73
+ # Rails production environment. Backends can implement whatever strategy
74
+ # is useful.
75
+ def eager_load!
76
+ config.backend.eager_load!
77
+ end
78
+
72
79
  # Translates, pluralizes and interpolates a given key using a given locale,
73
80
  # scope, and default, as well as interpolation values.
74
81
  #
@@ -108,7 +115,7 @@ module I18n
108
115
  # *PLURALIZATION*
109
116
  #
110
117
  # Translation data can contain pluralized translations. Pluralized translations
111
- # are arrays of singluar/plural versions of translations like <tt>['Foo', 'Foos']</tt>.
118
+ # are arrays of singular/plural versions of translations like <tt>['Foo', 'Foos']</tt>.
112
119
  #
113
120
  # Note that <tt>I18n::Backend::Simple</tt> only supports an algorithm for English
114
121
  # pluralization rules. Other algorithms can be supported by custom backends.
@@ -166,18 +173,16 @@ module I18n
166
173
  #
167
174
  # It is recommended to use/implement lambdas in an "idempotent" way. E.g. when
168
175
  # a cache layer is put in front of I18n.translate it will generate a cache key
169
- # from the argument values passed to #translate. Therefor your lambdas should
176
+ # from the argument values passed to #translate. Therefore your lambdas should
170
177
  # always return the same translations/values per unique combination of argument
171
178
  # values.
172
- def translate(*args)
173
- options = args.last.is_a?(Hash) ? args.pop.dup : {}
174
- key = args.shift
175
- backend = config.backend
176
- locale = options.delete(:locale) || config.locale
177
- handling = options.delete(:throw) && :throw || options.delete(:raise) && :raise # TODO deprecate :raise
178
-
179
+ def translate(key = nil, *, throw: false, raise: false, locale: nil, **options) # TODO deprecate :raise
180
+ locale ||= config.locale
181
+ raise Disabled.new('t') if locale == false
179
182
  enforce_available_locales!(locale)
180
183
 
184
+ backend = config.backend
185
+
181
186
  result = catch(:exception) do
182
187
  if key.is_a?(Array)
183
188
  key.map { |k| backend.translate(locale, k, options) }
@@ -185,19 +190,26 @@ module I18n
185
190
  backend.translate(locale, key, options)
186
191
  end
187
192
  end
188
- result.is_a?(MissingTranslation) ? handle_exception(handling, result, locale, key, options) : result
193
+
194
+ if result.is_a?(MissingTranslation)
195
+ handle_exception((throw && :throw || raise && :raise), result, locale, key, options)
196
+ else
197
+ result
198
+ end
189
199
  end
190
200
  alias :t :translate
191
201
 
192
202
  # Wrapper for <tt>translate</tt> that adds <tt>:raise => true</tt>. With
193
203
  # this option, if no translation is found, it will raise <tt>I18n::MissingTranslationData</tt>
194
204
  def translate!(key, options = EMPTY_HASH)
195
- translate(key, options.merge(:raise => true))
205
+ translate(key, **options.merge(:raise => true))
196
206
  end
197
207
  alias :t! :translate!
198
208
 
199
209
  # Returns true if a translation exists for a given key, otherwise returns false.
200
- def exists?(key, locale = config.locale)
210
+ def exists?(key, _locale = nil, locale: _locale)
211
+ locale ||= config.locale
212
+ raise Disabled.new('exists?') if locale == false
201
213
  raise I18n::ArgumentError if key.is_a?(String) && key.empty?
202
214
  config.backend.exists?(locale, key)
203
215
  end
@@ -253,37 +265,40 @@ module I18n
253
265
  # I18n.transliterate("Jürgen") # => "Juergen"
254
266
  # I18n.transliterate("Jürgen", :locale => :en) # => "Jurgen"
255
267
  # I18n.transliterate("Jürgen", :locale => :de) # => "Juergen"
256
- def transliterate(*args)
257
- options = args.pop.dup if args.last.is_a?(Hash)
258
- key = args.shift
259
- locale = options && options.delete(:locale) || config.locale
260
- handling = options && (options.delete(:throw) && :throw || options.delete(:raise) && :raise)
261
- replacement = options && options.delete(:replacement)
268
+ def transliterate(key, *, throw: false, raise: false, locale: nil, replacement: nil, **options)
269
+ locale ||= config.locale
270
+ raise Disabled.new('transliterate') if locale == false
262
271
  enforce_available_locales!(locale)
272
+
263
273
  config.backend.transliterate(locale, key, replacement)
264
274
  rescue I18n::ArgumentError => exception
265
- handle_exception(handling, exception, locale, key, options || {})
275
+ handle_exception((throw && :throw || raise && :raise), exception, locale, key, options)
266
276
  end
267
277
 
268
278
  # Localizes certain objects, such as dates and numbers to local formatting.
269
- def localize(object, options = nil)
270
- options = options ? options.dup : {}
271
- locale = options.delete(:locale) || config.locale
272
- format = options.delete(:format) || :default
279
+ def localize(object, locale: nil, format: nil, **options)
280
+ locale ||= config.locale
281
+ raise Disabled.new('l') if locale == false
273
282
  enforce_available_locales!(locale)
283
+
284
+ format ||= :default
274
285
  config.backend.localize(locale, object, format, options)
275
286
  end
276
287
  alias :l :localize
277
288
 
278
289
  # Executes block with given I18n.locale set.
279
290
  def with_locale(tmp_locale = nil)
280
- if tmp_locale
291
+ if tmp_locale == nil
292
+ yield
293
+ else
281
294
  current_locale = self.locale
282
- self.locale = tmp_locale
295
+ self.locale = tmp_locale
296
+ begin
297
+ yield
298
+ ensure
299
+ self.locale = current_locale
300
+ end
283
301
  end
284
- yield
285
- ensure
286
- self.locale = current_locale if tmp_locale
287
302
  end
288
303
 
289
304
  # Merges the given locale, key and scope into a single array of keys.
@@ -307,7 +322,7 @@ module I18n
307
322
 
308
323
  # Raises an InvalidLocale exception when the passed locale is not available.
309
324
  def enforce_available_locales!(locale)
310
- if config.enforce_available_locales
325
+ if locale != false && config.enforce_available_locales
311
326
  raise I18n::InvalidLocale.new(locale) if !locale_available?(locale)
312
327
  end
313
328
  end
@@ -364,7 +379,7 @@ module I18n
364
379
  keys.delete('')
365
380
  keys.map! do |k|
366
381
  case k
367
- when /\A[-+]?\d+\z/ # integer
382
+ when /\A[-+]?[1-9]\d*\z/ # integer
368
383
  k.to_i
369
384
  when 'true'
370
385
  true
@@ -81,7 +81,7 @@ module I18n
81
81
  key = format
82
82
  type = object.respond_to?(:sec) ? 'time' : 'date'
83
83
  options = options.merge(:raise => true, :object => object, :locale => locale)
84
- format = I18n.t(:"#{type}.formats.#{key}", options)
84
+ format = I18n.t(:"#{type}.formats.#{key}", **options)
85
85
  end
86
86
 
87
87
  format = translate_localization_format(locale, object, format, options)
@@ -95,10 +95,19 @@ module I18n
95
95
  end
96
96
 
97
97
  def reload!
98
+ eager_load! if eager_loaded?
99
+ end
100
+
101
+ def eager_load!
102
+ @eager_loaded = true
98
103
  end
99
104
 
100
105
  protected
101
106
 
107
+ def eager_loaded?
108
+ @eager_loaded ||= false
109
+ end
110
+
102
111
  # The method which actually looks up for the translation in the store.
103
112
  def lookup(locale, key, scope = [], options = EMPTY_HASH)
104
113
  raise NotImplementedError
@@ -113,7 +122,7 @@ module I18n
113
122
  # first translation that can be resolved. Otherwise it tries to resolve
114
123
  # the translation directly.
115
124
  def default(locale, object, subject, options = EMPTY_HASH)
116
- options = options.dup.reject { |key, value| key == :default }
125
+ options = options.reject { |key, value| key == :default }
117
126
  case subject
118
127
  when Array
119
128
  subject.each do |item|
@@ -134,7 +143,7 @@ module I18n
134
143
  result = catch(:exception) do
135
144
  case subject
136
145
  when Symbol
137
- I18n.translate(subject, options.merge(:locale => locale, :throw => true))
146
+ I18n.translate(subject, **options.merge(:locale => locale, :throw => true))
138
147
  when Proc
139
148
  date_or_time = options.delete(:object) || object
140
149
  resolve(locale, object, subject.call(date_or_time, options))
@@ -248,16 +257,22 @@ module I18n
248
257
  end
249
258
 
250
259
  def translate_localization_format(locale, object, format, options)
251
- format.to_s.gsub(/%[aAbBpP]/) do |match|
260
+ format.to_s.gsub(/%(|\^)[aAbBpP]/) do |match|
252
261
  case match
253
- when '%a' then I18n.t(:"date.abbr_day_names", :locale => locale, :format => format)[object.wday]
254
- when '%A' then I18n.t(:"date.day_names", :locale => locale, :format => format)[object.wday]
255
- when '%b' then I18n.t(:"date.abbr_month_names", :locale => locale, :format => format)[object.mon]
256
- when '%B' then I18n.t(:"date.month_names", :locale => locale, :format => format)[object.mon]
257
- when '%p' then I18n.t(:"time.#{object.hour < 12 ? :am : :pm}", :locale => locale, :format => format).upcase if object.respond_to? :hour
258
- when '%P' then I18n.t(:"time.#{object.hour < 12 ? :am : :pm}", :locale => locale, :format => format).downcase if object.respond_to? :hour
262
+ when '%a' then I18n.t!(:"date.abbr_day_names", :locale => locale, :format => format)[object.wday]
263
+ when '%^a' then I18n.t!(:"date.abbr_day_names", :locale => locale, :format => format)[object.wday].upcase
264
+ when '%A' then I18n.t!(:"date.day_names", :locale => locale, :format => format)[object.wday]
265
+ when '%^A' then I18n.t!(:"date.day_names", :locale => locale, :format => format)[object.wday].upcase
266
+ when '%b' then I18n.t!(:"date.abbr_month_names", :locale => locale, :format => format)[object.mon]
267
+ when '%^b' then I18n.t!(:"date.abbr_month_names", :locale => locale, :format => format)[object.mon].upcase
268
+ when '%B' then I18n.t!(:"date.month_names", :locale => locale, :format => format)[object.mon]
269
+ when '%^B' then I18n.t!(:"date.month_names", :locale => locale, :format => format)[object.mon].upcase
270
+ when '%p' then I18n.t!(:"time.#{object.hour < 12 ? :am : :pm}", :locale => locale, :format => format).upcase if object.respond_to? :hour
271
+ when '%P' then I18n.t!(:"time.#{object.hour < 12 ? :am : :pm}", :locale => locale, :format => format).downcase if object.respond_to? :hour
259
272
  end
260
273
  end
274
+ rescue MissingTranslationData => e
275
+ e.message
261
276
  end
262
277
 
263
278
  def pluralization_key(entry, count)
@@ -100,16 +100,13 @@ module I18n
100
100
 
101
101
  def cache_key(locale, key, options)
102
102
  # This assumes that only simple, native Ruby values are passed to I18n.translate.
103
- "i18n/#{I18n.cache_namespace}/#{locale}/#{digest_item(key)}/#{USE_INSPECT_HASH ? digest_item(options.inspect) : digest_item(options)}"
103
+ "i18n/#{I18n.cache_namespace}/#{locale}/#{digest_item(key)}/#{digest_item(options)}"
104
104
  end
105
105
 
106
106
  private
107
- # In Ruby < 1.9 the following is true: { :foo => 1, :bar => 2 }.hash == { :foo => 2, :bar => 1 }.hash
108
- # Therefore we must use the hash of the inspect string instead to avoid cache key colisions.
109
- USE_INSPECT_HASH = RUBY_VERSION <= "1.9"
110
107
 
111
108
  def digest_item(key)
112
- I18n.cache_key_digest ? I18n.cache_key_digest.hexdigest(key.to_s) : key.hash
109
+ I18n.cache_key_digest ? I18n.cache_key_digest.hexdigest(key.to_s) : key.to_s.hash
113
110
  end
114
111
  end
115
112
  end
@@ -41,6 +41,10 @@ module I18n
41
41
  backends.each { |backend| backend.reload! }
42
42
  end
43
43
 
44
+ def eager_load!
45
+ backends.each { |backend| backend.eager_load! }
46
+ end
47
+
44
48
  def store_translations(locale, data, options = EMPTY_HASH)
45
49
  backends.first.store_translations(locale, data, options)
46
50
  end
@@ -92,9 +96,13 @@ module I18n
92
96
  end
93
97
 
94
98
  def translations
95
- backends.first.instance_eval do
96
- init_translations unless initialized?
97
- translations
99
+ backends.reverse.each_with_object({}) do |backend, memo|
100
+ partial_translations = backend.instance_eval do
101
+ init_translations unless initialized?
102
+ translations
103
+ end
104
+
105
+ memo.deep_merge!(partial_translations)
98
106
  end
99
107
  end
100
108
 
@@ -26,6 +26,12 @@ module I18n
26
26
  super
27
27
  end
28
28
 
29
+ def eager_load!
30
+ memoized_lookup
31
+ available_locales
32
+ super
33
+ end
34
+
29
35
  protected
30
36
 
31
37
  def lookup(locale, key, scope = nil, options = EMPTY_HASH)
@@ -21,8 +21,6 @@ module I18n
21
21
  class Simple
22
22
  using I18n::HashRefinements
23
23
 
24
- (class << self; self; end).class_eval { public :include }
25
-
26
24
  module Implementation
27
25
  include Base
28
26
 
@@ -63,6 +61,11 @@ module I18n
63
61
  super
64
62
  end
65
63
 
64
+ def eager_load!
65
+ init_translations unless initialized?
66
+ super
67
+ end
68
+
66
69
  def translations(do_init: false)
67
70
  # To avoid returning empty translations,
68
71
  # call `init_translations`
@@ -7,7 +7,7 @@ module I18n
7
7
  # The only configuration value that is not global and scoped to thread is :locale.
8
8
  # It defaults to the default_locale.
9
9
  def locale
10
- defined?(@locale) && @locale ? @locale : default_locale
10
+ defined?(@locale) && @locale != nil ? @locale : default_locale
11
11
  end
12
12
 
13
13
  # Sets the current locale pseudo-globally, i.e. in the Thread.current hash.
@@ -15,6 +15,20 @@ module I18n
15
15
 
16
16
  class ArgumentError < ::ArgumentError; end
17
17
 
18
+ class Disabled < ArgumentError
19
+ def initialize(method)
20
+ super(<<~MESSAGE)
21
+ I18n.#{method} is currently disabled, likely because your application is still in its loading phase.
22
+
23
+ This method is meant to display text in the user locale, so calling it before the user locale has
24
+ been set is likely to display text from the wrong locale to some users.
25
+
26
+ If you have a legitimate reason to access i18n data outside of the user flow, you can do so by passing
27
+ the desired locale explictly with the `locale` argument, e.g. `I18n.#{method}(..., locale: :en)`
28
+ MESSAGE
29
+ end
30
+ end
31
+
18
32
  class InvalidLocale < ArgumentError
19
33
  attr_reader :locale
20
34
  def initialize(locale)
@@ -19,7 +19,7 @@ module I18n
19
19
  end
20
20
 
21
21
  def gettext(msgid, options = EMPTY_HASH)
22
- I18n.t(msgid, { :default => msgid, :separator => '|' }.merge(options))
22
+ I18n.t(msgid, **{:default => msgid, :separator => '|'}.merge(options))
23
23
  end
24
24
  alias _ gettext
25
25
 
@@ -4,7 +4,7 @@
4
4
  module I18n
5
5
  DEFAULT_INTERPOLATION_PATTERNS = [
6
6
  /%%/,
7
- /%\{(\w+)\}/, # matches placeholders like "%{foo}"
7
+ /%\{([\w|]+)\}/, # matches placeholders like "%{foo} or %{foo|word}"
8
8
  /%<(\w+)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/ # matches placeholders like "%<foo>.d"
9
9
  ].freeze
10
10
  INTERPOLATION_PATTERN = Regexp.union(DEFAULT_INTERPOLATION_PATTERNS)
@@ -66,6 +66,7 @@ module I18n
66
66
 
67
67
  def [](locale)
68
68
  raise InvalidLocale.new(locale) if locale.nil?
69
+ raise Disabled.new('fallback#[]') if locale == false
69
70
  locale = locale.to_sym
70
71
  super || store(locale, compute(locale))
71
72
  end
@@ -24,6 +24,10 @@ module I18n
24
24
  assert_equal 'Hi David!', interpolate(:default => 'Hi %{name}!', :name => 'David')
25
25
  end
26
26
 
27
+ test "interpolation: works with a pipe" do
28
+ assert_equal 'Hi david!', interpolate(:default => 'Hi %{name|lowercase}!', :'name|lowercase' => 'david')
29
+ end
30
+
27
31
  test "interpolation: given a nil value it still interpolates it into the string" do
28
32
  assert_equal 'Hi !', interpolate(:default => 'Hi %{name}!', :name => nil)
29
33
  end
@@ -11,8 +11,7 @@ module I18n
11
11
  end
12
12
 
13
13
  test "localize Date: given the short format it uses it" do
14
- # TODO should be Mrz, shouldn't it?
15
- assert_equal '01. Mar', I18n.l(@date, :format => :short, :locale => :de)
14
+ assert_equal '01. Mär', I18n.l(@date, :format => :short, :locale => :de)
16
15
  end
17
16
 
18
17
  test "localize Date: given the long format it uses it" do
@@ -27,17 +26,40 @@ module I18n
27
26
  assert_equal 'Samstag', I18n.l(@date, :format => '%A', :locale => :de)
28
27
  end
29
28
 
29
+ test "localize Date: given a uppercased day name format it returns the correct day name in upcase" do
30
+ assert_equal 'samstag'.upcase, I18n.l(@date, :format => '%^A', :locale => :de)
31
+ end
32
+
30
33
  test "localize Date: given an abbreviated day name format it returns the correct abbreviated day name" do
31
34
  assert_equal 'Sa', I18n.l(@date, :format => '%a', :locale => :de)
32
35
  end
33
36
 
37
+ test "localize Date: given an abbreviated and uppercased day name format it returns the correct abbreviated day name in upcase" do
38
+ assert_equal 'sa'.upcase, I18n.l(@date, :format => '%^a', :locale => :de)
39
+ end
40
+
34
41
  test "localize Date: given a month name format it returns the correct month name" do
35
42
  assert_equal 'März', I18n.l(@date, :format => '%B', :locale => :de)
36
43
  end
37
44
 
45
+ test "localize Date: given a uppercased month name format it returns the correct month name in upcase" do
46
+ assert_equal 'märz'.upcase, I18n.l(@date, :format => '%^B', :locale => :de)
47
+ end
48
+
38
49
  test "localize Date: given an abbreviated month name format it returns the correct abbreviated month name" do
39
- # TODO should be Mrz, shouldn't it?
40
- assert_equal 'Mar', I18n.l(@date, :format => '%b', :locale => :de)
50
+ assert_equal 'Mär', I18n.l(@date, :format => '%b', :locale => :de)
51
+ end
52
+
53
+ test "localize Date: given an abbreviated and uppercased month name format it returns the correct abbreviated month name in upcase" do
54
+ assert_equal 'mär'.upcase, I18n.l(@date, :format => '%^b', :locale => :de)
55
+ end
56
+
57
+ test "localize Date: given a date format with the month name upcased it returns the correct value" do
58
+ assert_equal '1. FEBRUAR 2008', I18n.l(::Date.new(2008, 2, 1), :format => "%-d. %^B %Y", :locale => :de)
59
+ end
60
+
61
+ test "localize Date: given missing translations it returns the correct error message" do
62
+ assert_equal 'translation missing: fr.date.abbr_month_names', I18n.l(@date, :format => '%b', :locale => :fr)
41
63
  end
42
64
 
43
65
  test "localize Date: given an unknown format it does not fail" do
@@ -46,9 +68,9 @@ module I18n
46
68
 
47
69
  test "localize Date: does not modify the options hash" do
48
70
  options = { :format => '%b', :locale => :de }
49
- assert_equal 'Mar', I18n.l(@date, options)
71
+ assert_equal 'Mär', I18n.l(@date, **options)
50
72
  assert_equal({ :format => '%b', :locale => :de }, options)
51
- assert_nothing_raised { I18n.l(@date, options.freeze) }
73
+ assert_nothing_raised { I18n.l(@date, **options.freeze) }
52
74
  end
53
75
 
54
76
  test "localize Date: given nil with default value it returns default" do
@@ -85,7 +107,7 @@ module I18n
85
107
  :day_names => %w(Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag),
86
108
  :abbr_day_names => %w(So Mo Di Mi Do Fr Sa),
87
109
  :month_names => %w(Januar Februar März April Mai Juni Juli August September Oktober November Dezember).unshift(nil),
88
- :abbr_month_names => %w(Jan Feb Mar Apr Mai Jun Jul Aug Sep Okt Nov Dez).unshift(nil)
110
+ :abbr_month_names => %w(Jan Feb Mär Apr Mai Jun Jul Aug Sep Okt Nov Dez).unshift(nil)
89
111
  }
90
112
  }
91
113
  end
@@ -12,8 +12,7 @@ module I18n
12
12
  end
13
13
 
14
14
  test "localize DateTime: 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(@datetime, :format => :short, :locale => :de)
15
+ assert_equal '01. Mär 06:00', I18n.l(@datetime, :format => :short, :locale => :de)
17
16
  end
18
17
 
19
18
  test "localize DateTime: given the long format it uses it" do
@@ -21,25 +20,47 @@ module I18n
21
20
  end
22
21
 
23
22
  test "localize DateTime: given the default format it uses it" do
24
- # TODO should be Mrz, shouldn't it?
25
- assert_equal 'Sa, 01. Mar 2008 06:00:00 +0000', I18n.l(@datetime, :format => :default, :locale => :de)
23
+ assert_equal 'Sa, 01. Mär 2008 06:00:00 +0000', I18n.l(@datetime, :format => :default, :locale => :de)
26
24
  end
27
25
 
28
26
  test "localize DateTime: given a day name format it returns the correct day name" do
29
27
  assert_equal 'Samstag', I18n.l(@datetime, :format => '%A', :locale => :de)
30
28
  end
31
29
 
30
+ test "localize DateTime: given a uppercased day name format it returns the correct day name in upcase" do
31
+ assert_equal 'samstag'.upcase, I18n.l(@datetime, :format => '%^A', :locale => :de)
32
+ end
33
+
32
34
  test "localize DateTime: given an abbreviated day name format it returns the correct abbreviated day name" do
33
35
  assert_equal 'Sa', I18n.l(@datetime, :format => '%a', :locale => :de)
34
36
  end
35
37
 
38
+ test "localize DateTime: given an abbreviated and uppercased day name format it returns the correct abbreviated day name in upcase" do
39
+ assert_equal 'sa'.upcase, I18n.l(@datetime, :format => '%^a', :locale => :de)
40
+ end
41
+
36
42
  test "localize DateTime: given a month name format it returns the correct month name" do
37
43
  assert_equal 'März', I18n.l(@datetime, :format => '%B', :locale => :de)
38
44
  end
39
45
 
46
+ test "localize DateTime: given a uppercased month name format it returns the correct month name in upcase" do
47
+ assert_equal 'märz'.upcase, I18n.l(@datetime, :format => '%^B', :locale => :de)
48
+ end
49
+
40
50
  test "localize DateTime: 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(@datetime, :format => '%b', :locale => :de)
51
+ assert_equal 'Mär', I18n.l(@datetime, :format => '%b', :locale => :de)
52
+ end
53
+
54
+ test "localize DateTime: given an abbreviated and uppercased month name format it returns the correct abbreviated month name in upcase" do
55
+ assert_equal 'mär'.upcase, I18n.l(@datetime, :format => '%^b', :locale => :de)
56
+ end
57
+
58
+ test "localize DateTime: given a date format with the month name upcased it returns the correct value" do
59
+ assert_equal '1. FEBRUAR 2008', I18n.l(::DateTime.new(2008, 2, 1, 6), :format => "%-d. %^B %Y", :locale => :de)
60
+ end
61
+
62
+ test "localize DateTime: given missing translations it returns the correct error message" do
63
+ assert_equal 'translation missing: fr.date.abbr_month_names', I18n.l(@datetime, :format => '%b', :locale => :fr)
43
64
  end
44
65
 
45
66
  test "localize DateTime: given a meridian indicator format it returns the correct meridian indicator" do
@@ -59,7 +59,7 @@ module I18n
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
@@ -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
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module I18n
4
- VERSION = "1.4.0"
4
+ VERSION = "1.7.0"
5
5
  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: 1.4.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Fuchs
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2019-01-01 00:00:00.000000000 Z
16
+ date: 2019-10-04 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: concurrent-ruby
@@ -82,7 +82,7 @@ files:
82
82
  - lib/i18n/tests/pluralization.rb
83
83
  - lib/i18n/tests/procs.rb
84
84
  - lib/i18n/version.rb
85
- homepage: http://github.com/svenfuchs/i18n
85
+ homepage: https://github.com/ruby-i18n/i18n
86
86
  licenses:
87
87
  - MIT
88
88
  metadata:
@@ -110,15 +110,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
110
110
  requirements:
111
111
  - - ">="
112
112
  - !ruby/object:Gem::Version
113
- version: 2.0.0
113
+ version: 2.3.0
114
114
  required_rubygems_version: !ruby/object:Gem::Requirement
115
115
  requirements:
116
116
  - - ">="
117
117
  - !ruby/object:Gem::Version
118
118
  version: 1.3.5
119
119
  requirements: []
120
- rubyforge_project: "[none]"
121
- rubygems_version: 2.7.6
120
+ rubygems_version: 3.0.3
122
121
  signing_key:
123
122
  specification_version: 4
124
123
  summary: New wave Internationalization support for Ruby