i18n 1.8.2 → 1.8.3

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.
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