i18n 1.8.2 → 1.8.3

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: 633b59a1d482d2e8dee6baa5a22bcf93eaba9ec941fa38991576cc977e4037c8
4
- data.tar.gz: 45d65177fa4c32288c396f6f845bb489cbb46b7c5397180a1042da73d7e72b08
3
+ metadata.gz: 461ee8866033d12fb5dd2daaa85703916b83ba58c225afd5bfe31e30c3231aa6
4
+ data.tar.gz: 9bd10034e9629c3fb72c07974fef0b069047b269dbab165ecbd5b8c38c9c5567
5
5
  SHA512:
6
- metadata.gz: b3af86a4ed93947c57bfa9d70da30350fc353e57e12a79a5ae50a230ea5a86c90be9e376103f0ecfc849a23fb76e0281fff0226025d32e918e89a68b47d88336
7
- data.tar.gz: 492e7c5fe9e27b6208faa5cf02880440d138ce8d4b2b261832608345b97a5cc1dc0d0d23dbf8bbfc9f5d6e81934ea579ceece446e554cdb2d3d7c3ded697822e
6
+ metadata.gz: feb783a73598b1ab9e319f5569d71b14c061816bdb8e7d887262fed6531ec0a3c77afa36a4257080bbc7a1ec5239963a08b2f37a3dd449db82f9e402c5f57fbc
7
+ data.tar.gz: fdb2f914e53484a8cf925b71de1004a4d0c1bfa3da4b7d50bd14fcda1ab036ae12d773e692cbf85ade5e78906af24fcc05b22156e280a4615e26430f8929eb75
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![Build Status](https://github.com/ruby-i18n/i18n/workflows/Ruby/badge.svg)](https://github.com/ruby-i18n/i18n/actions?query=workflow%3ARuby)
4
4
 
5
- Ruby Internationalization and localization solution.
5
+ Ruby internationalization and localization (i18n) solution.
6
6
 
7
7
  Currently maintained by @radar.
8
8
 
@@ -12,7 +12,7 @@ Currently maintained by @radar.
12
12
 
13
13
  You will most commonly use this library within a Rails app.
14
14
 
15
- [See the Rails Guide](http://guides.rubyonrails.org/i18n.html) for an example of its usage.
15
+ [See the Rails Guide](https://guides.rubyonrails.org/i18n.html) for an example of its usage.
16
16
 
17
17
  ### Ruby (without Rails)
18
18
 
@@ -51,16 +51,16 @@ I18n.t(:test) # => "Dies ist ein Test"
51
51
 
52
52
  ## Features
53
53
 
54
- * translation and localization
55
- * interpolation of values to translations (Ruby 1.9 compatible syntax)
56
- * pluralization (CLDR compatible)
57
- * customizable transliteration to ASCII
58
- * flexible defaults
59
- * bulk lookup
60
- * lambdas as translation data
61
- * custom key/scope separator
62
- * custom exception handlers
63
- * extensible architecture with a swappable backend
54
+ * Translation and localization
55
+ * Interpolation of values to translations
56
+ * Pluralization (CLDR compatible)
57
+ * Customizable transliteration to ASCII
58
+ * Flexible defaults
59
+ * Bulk lookup
60
+ * Lambdas as translation data
61
+ * Custom key/scope separator
62
+ * Custom exception handlers
63
+ * Extensible architecture with a swappable backend
64
64
 
65
65
  ## Pluggable Features
66
66
 
@@ -106,19 +106,16 @@ follow the usual test setup and should be easy to grok.
106
106
 
107
107
  ## More Documentation
108
108
 
109
- Additional documentation can be found here: https://github.com/svenfuchs/i18n/wiki
110
-
111
- ## Authors
112
-
113
- * [Sven Fuchs](http://www.artweb-design.de)
114
- * [Joshua Harvey](http://www.workingwithrails.com/person/759-joshua-harvey)
115
- * [Stephan Soller](http://www.arkanis-development.de)
116
- * [Saimon Moore](http://saimonmoore.net)
117
- * [Matt Aimonetti](https://matt.aimonetti.net/)
109
+ Additional documentation can be found here: https://github.com/ruby-i18n/i18n/wiki
118
110
 
119
111
  ## Contributors
120
112
 
121
- https://github.com/svenfuchs/i18n/graphs/contributors
113
+ * @radar
114
+ * @carlosantoniodasilva
115
+ * @josevalim
116
+ * @knapo
117
+ * @tigrish
118
+ * [and many more](https://github.com/ruby-i18n/i18n/graphs/contributors)
122
119
 
123
120
  ## License
124
121
 
@@ -223,11 +223,11 @@ module I18n
223
223
  alias :t! :translate!
224
224
 
225
225
  # Returns true if a translation exists for a given key, otherwise returns false.
226
- def exists?(key, _locale = nil, locale: _locale)
226
+ def exists?(key, _locale = nil, locale: _locale, **options)
227
227
  locale ||= config.locale
228
228
  raise Disabled.new('exists?') if locale == false
229
229
  raise I18n::ArgumentError if key.is_a?(String) && key.empty?
230
- config.backend.exists?(locale, key)
230
+ config.backend.exists?(locale, key, options)
231
231
  end
232
232
 
233
233
  # Transliterates UTF-8 characters to ASCII. By default this method will
@@ -389,7 +389,7 @@ module I18n
389
389
  @@normalized_key_cache[separator][key] ||=
390
390
  case key
391
391
  when Array
392
- key.map { |k| normalize_key(k, separator) }.flatten
392
+ key.flat_map { |k| normalize_key(k, separator) }
393
393
  else
394
394
  keys = key.to_s.split(separator)
395
395
  keys.delete('')
@@ -64,7 +64,7 @@ module I18n
64
64
  entry
65
65
  end
66
66
 
67
- def exists?(locale, key)
67
+ def exists?(locale, key, options = EMPTY_HASH)
68
68
  lookup(locale, key) != nil
69
69
  end
70
70
 
@@ -146,7 +146,7 @@ module I18n
146
146
  I18n.translate(subject, **options.merge(:locale => locale, :throw => true))
147
147
  when Proc
148
148
  date_or_time = options.delete(:object) || object
149
- resolve(locale, object, subject.call(date_or_time, options))
149
+ resolve(locale, object, subject.call(date_or_time, **options))
150
150
  else
151
151
  subject
152
152
  end
@@ -163,6 +163,7 @@ module I18n
163
163
  # not standard with regards to the CLDR pluralization rules.
164
164
  # Other backends can implement more flexible or complex pluralization rules.
165
165
  def pluralize(locale, entry, count)
166
+ entry = entry.reject { |k, _v| k == :attributes } if entry.is_a?(Hash)
166
167
  return entry unless entry.is_a?(Hash) && count && entry.values.none? { |v| v.is_a?(Hash) }
167
168
 
168
169
  key = pluralization_key(entry, count)
@@ -73,9 +73,9 @@ module I18n
73
73
  throw(:exception, I18n::MissingTranslation.new(locale, key, options))
74
74
  end
75
75
 
76
- def exists?(locale, key)
76
+ def exists?(locale, key, options = EMPTY_HASH)
77
77
  backends.any? do |backend|
78
- backend.exists?(locale, key)
78
+ backend.exists?(locale, key, options)
79
79
  end
80
80
  end
81
81
 
@@ -101,8 +101,7 @@ module I18n
101
101
  init_translations unless initialized?
102
102
  translations
103
103
  end
104
-
105
- memo.deep_merge!(partial_translations)
104
+ memo.deep_merge!(partial_translations) { |_, a, b| b || a }
106
105
  end
107
106
  end
108
107
 
@@ -46,7 +46,10 @@ module I18n
46
46
  begin
47
47
  catch(:exception) do
48
48
  result = super(fallback, key, fallback_options)
49
- return result unless result.nil?
49
+ unless result.nil?
50
+ on_fallback(locale, fallback, key, options) if locale != fallback
51
+ return result
52
+ end
50
53
  end
51
54
  rescue I18n::InvalidLocale
52
55
  # we do nothing when the locale is invalid, as this is a fallback anyways.
@@ -68,7 +71,8 @@ module I18n
68
71
  return first_non_symbol_default
69
72
  end
70
73
 
71
- def exists?(locale, key)
74
+ def exists?(locale, key, options = EMPTY_HASH)
75
+ return super unless options.fetch(:fallback, true)
72
76
  I18n.fallbacks[locale].each do |fallback|
73
77
  begin
74
78
  return true if super(fallback, key)
@@ -79,6 +83,13 @@ module I18n
79
83
 
80
84
  false
81
85
  end
86
+
87
+ private
88
+
89
+ # Overwrite on_fallback to add specified logic when the fallback succeeds.
90
+ def on_fallback(_original_locale, _fallback_locale, _key, _optoins)
91
+ nil
92
+ end
82
93
  end
83
94
  end
84
95
  end
@@ -18,14 +18,17 @@ module I18n
18
18
  # and creates way less objects than the one at I18n.normalize_keys.
19
19
  # It also handles escaping the translation keys.
20
20
  def self.normalize_flat_keys(locale, key, scope, separator)
21
- keys = [scope, key].flatten.compact
21
+ keys = [scope, key]
22
+ keys.flatten!
23
+ keys.compact!
24
+
22
25
  separator ||= I18n.default_separator
23
26
 
24
27
  if separator != FLATTEN_SEPARATOR
25
- keys.map! do |k|
26
- k.to_s.tr("#{FLATTEN_SEPARATOR}#{separator}",
27
- "#{SEPARATOR_ESCAPE_CHAR}#{FLATTEN_SEPARATOR}")
28
- end
28
+ from_str = "#{FLATTEN_SEPARATOR}#{separator}"
29
+ to_str = "#{SEPARATOR_ESCAPE_CHAR}#{FLATTEN_SEPARATOR}"
30
+
31
+ keys.map! { |k| k.to_s.tr from_str, to_str }
29
32
  end
30
33
 
31
34
  keys.join(".")
@@ -18,12 +18,24 @@ module I18n
18
18
  end
19
19
  end
20
20
 
21
- # deep_merge_hash! by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
22
- def deep_merge!(data)
23
- merger = lambda do |_key, v1, v2|
24
- Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2
21
+ # deep_merge from activesupport 5
22
+ # Copyright (c) 2005-2019 David Heinemeier Hansson
23
+ def deep_merge(other_hash, &block)
24
+ dup.deep_merge!(other_hash, &block)
25
+ end
26
+
27
+ # deep_merge! from activesupport 5
28
+ # Copyright (c) 2005-2019 David Heinemeier Hansson
29
+ def deep_merge!(other_hash, &block)
30
+ merge!(other_hash) do |key, this_val, other_val|
31
+ if this_val.is_a?(Hash) && other_val.is_a?(Hash)
32
+ this_val.deep_merge(other_val, &block)
33
+ elsif block_given?
34
+ block.call(key, this_val, other_val)
35
+ else
36
+ other_val
37
+ end
25
38
  end
26
- merge!(data, &merger)
27
39
  end
28
40
 
29
41
  def symbolize_key(key)
@@ -60,7 +60,7 @@ module I18n
60
60
  end
61
61
 
62
62
  def defaults=(defaults)
63
- @defaults = defaults.map { |default| compute(default, false) }.flatten
63
+ @defaults = defaults.flat_map { |default| compute(default, false) }
64
64
  end
65
65
  attr_reader :defaults
66
66
 
@@ -84,13 +84,15 @@ module I18n
84
84
  protected
85
85
 
86
86
  def compute(tags, include_defaults = true, exclude = [])
87
- result = Array(tags).collect do |tag|
87
+ result = Array(tags).flat_map do |tag|
88
88
  tags = I18n::Locale::Tag.tag(tag).self_and_parents.map! { |t| t.to_sym } - exclude
89
89
  tags.each { |_tag| tags += compute(@map[_tag], false, exclude + tags) if @map[_tag] }
90
90
  tags
91
- end.flatten
91
+ end
92
92
  result.push(*defaults) if include_defaults
93
- result.uniq.compact
93
+ result.uniq!
94
+ result.compact!
95
+ result
94
96
  end
95
97
  end
96
98
  end
@@ -3,18 +3,20 @@ module I18n
3
3
  module Tag
4
4
  module Parents
5
5
  def parent
6
- @parent ||= begin
7
- segs = to_a.compact
8
- segs.length > 1 ? self.class.tag(*segs[0..(segs.length-2)].join('-')) : nil
9
- end
6
+ @parent ||=
7
+ begin
8
+ segs = to_a
9
+ segs.compact!
10
+ segs.length > 1 ? self.class.tag(*segs[0..(segs.length - 2)].join('-')) : nil
11
+ end
10
12
  end
11
13
 
12
14
  def self_and_parents
13
- @self_and_parents ||= [self] + parents
15
+ @self_and_parents ||= [self].concat parents
14
16
  end
15
17
 
16
18
  def parents
17
- @parents ||= ([parent] + (parent ? parent.parents : [])).compact
19
+ @parents ||= parent ? [parent].concat(parent.parents) : []
18
20
  end
19
21
  end
20
22
  end
@@ -19,7 +19,7 @@ module I18n
19
19
  end
20
20
 
21
21
  def subtags
22
- @subtags = tag.to_s.split('-').map { |subtag| subtag.to_s }
22
+ @subtags = tag.to_s.split('-').map!(&:to_s)
23
23
  end
24
24
 
25
25
  def to_sym
@@ -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
@@ -85,12 +86,12 @@ module I18n
85
86
  I18n.backend.store_translations :ru, {
86
87
  :time => {
87
88
  :formats => {
88
- :proc => lambda { |*args| I18n::Tests::Localization::Procs.inspect_args(args) }
89
+ :proc => lambda { |*args, **kwargs| I18n::Tests::Localization::Procs.inspect_args(args, kwargs) }
89
90
  }
90
91
  },
91
92
  :date => {
92
93
  :formats => {
93
- :proc => lambda { |*args| I18n::Tests::Localization::Procs.inspect_args(args) }
94
+ :proc => lambda { |*args, **kwargs| I18n::Tests::Localization::Procs.inspect_args(args, kwargs) }
94
95
  },
95
96
  :'day_names' => lambda { |key, options|
96
97
  (options[:format] =~ /^%A/) ?
@@ -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')
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module I18n
4
- VERSION = "1.8.2"
4
+ VERSION = "1.8.3"
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.8.2
4
+ version: 1.8.3
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: 2020-01-13 00:00:00.000000000 Z
16
+ date: 2020-06-05 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: concurrent-ruby
@@ -121,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
121
  - !ruby/object:Gem::Version
122
122
  version: 1.3.5
123
123
  requirements: []
124
- rubygems_version: 3.0.3
124
+ rubygems_version: 3.1.2
125
125
  signing_key:
126
126
  specification_version: 4
127
127
  summary: New wave Internationalization support for Ruby