i18n 0.8.6 → 0.9.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.
- checksums.yaml +4 -4
- data/gemfiles/Gemfile.rails-5.1.x +9 -0
- data/lib/i18n.rb +11 -5
- data/lib/i18n/backend/fallbacks.rb +4 -3
- data/lib/i18n/backend/flatten.rb +3 -3
- data/lib/i18n/backend/memoize.rb +1 -1
- data/lib/i18n/middleware.rb +15 -0
- data/lib/i18n/version.rb +1 -1
- data/test/backend/fallbacks_test.rb +10 -1
- data/test/backend/memoize_test.rb +32 -0
- data/test/i18n/middleware_test.rb +24 -0
- data/test/test_helper.rb +6 -0
- metadata +21 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dacd9a4d17f9bead5f815c49595c00d1531ed4d7
|
4
|
+
data.tar.gz: 1e4d2ba2b94da73f8dbde1957508a849f7162172
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f59e2cfebd1627b138d763d6b035078729cc62104697189e8781003aeb6537e8682e5f4f0ea0ad68e30f36873d895fdb863d8fca3abece2c48cb229e170ccb92
|
7
|
+
data.tar.gz: cd5c4bc9940ccfe400eda8696d8d9bf7630da4c4e67f46a0a6be9f799f64a54fb8d2bdcb9c80dfdeeb3dfc9e14f10d1af715d45dc230415e3491c7b6a187d3e6
|
data/lib/i18n.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'concurrent/map'
|
2
|
+
|
1
3
|
require 'i18n/version'
|
2
4
|
require 'i18n/exceptions'
|
3
5
|
require 'i18n/interpolate/ruby'
|
@@ -8,10 +10,16 @@ module I18n
|
|
8
10
|
autoload :Gettext, 'i18n/gettext'
|
9
11
|
autoload :Locale, 'i18n/locale'
|
10
12
|
autoload :Tests, 'i18n/tests'
|
13
|
+
autoload :Middleware, 'i18n/middleware'
|
11
14
|
|
12
15
|
RESERVED_KEYS = [:scope, :default, :separator, :resolve, :object, :fallback, :fallback_in_progress, :format, :cascade, :throw, :raise, :deep_interpolation]
|
13
16
|
RESERVED_KEYS_PATTERN = /%\{(#{RESERVED_KEYS.join("|")})\}/
|
14
17
|
|
18
|
+
|
19
|
+
def self.new_double_nested_cache # :nodoc:
|
20
|
+
Concurrent::Map.new { |h,k| h[k] = Concurrent::Map.new }
|
21
|
+
end
|
22
|
+
|
15
23
|
module Base
|
16
24
|
# Gets I18n configuration object.
|
17
25
|
def config
|
@@ -321,8 +329,10 @@ module I18n
|
|
321
329
|
end
|
322
330
|
end
|
323
331
|
|
332
|
+
@@normalized_key_cache = I18n.new_double_nested_cache
|
333
|
+
|
324
334
|
def normalize_key(key, separator)
|
325
|
-
normalized_key_cache[separator][key] ||=
|
335
|
+
@@normalized_key_cache[separator][key] ||=
|
326
336
|
case key
|
327
337
|
when Array
|
328
338
|
key.map { |k| normalize_key(k, separator) }.flatten
|
@@ -333,10 +343,6 @@ module I18n
|
|
333
343
|
keys
|
334
344
|
end
|
335
345
|
end
|
336
|
-
|
337
|
-
def normalized_key_cache
|
338
|
-
@normalized_key_cache ||= Hash.new { |h,k| h[k] = {} }
|
339
|
-
end
|
340
346
|
end
|
341
347
|
|
342
348
|
extend Base
|
@@ -37,7 +37,8 @@ module I18n
|
|
37
37
|
def translate(locale, key, options = {})
|
38
38
|
return super unless options.fetch(:fallback, true)
|
39
39
|
return super if options[:fallback_in_progress]
|
40
|
-
|
40
|
+
original_default = options[:default]
|
41
|
+
extract_non_symbol_default!(options)
|
41
42
|
|
42
43
|
begin
|
43
44
|
options[:fallback_in_progress] = true
|
@@ -45,7 +46,7 @@ module I18n
|
|
45
46
|
begin
|
46
47
|
catch(:exception) do
|
47
48
|
result = super(fallback, key, options)
|
48
|
-
return result
|
49
|
+
return result unless result.nil?
|
49
50
|
end
|
50
51
|
rescue I18n::InvalidLocale
|
51
52
|
# we do nothing when the locale is invalid, as this is a fallback anyways.
|
@@ -55,7 +56,7 @@ module I18n
|
|
55
56
|
options.delete(:fallback_in_progress)
|
56
57
|
end
|
57
58
|
|
58
|
-
return super(locale, nil, options.merge(:default =>
|
59
|
+
return super(locale, nil, options.merge(:default => original_default)) if options.key?(:default)
|
59
60
|
throw(:exception, I18n::MissingTranslation.new(locale, key, options))
|
60
61
|
end
|
61
62
|
|
data/lib/i18n/backend/flatten.rb
CHANGED
@@ -43,7 +43,7 @@ module I18n
|
|
43
43
|
|
44
44
|
# Store flattened links.
|
45
45
|
def links
|
46
|
-
@links ||=
|
46
|
+
@links ||= I18n.new_double_nested_cache
|
47
47
|
end
|
48
48
|
|
49
49
|
# Flatten keys for nested Hashes by chaining up keys:
|
@@ -99,7 +99,7 @@ module I18n
|
|
99
99
|
end
|
100
100
|
|
101
101
|
def find_link(locale, key) #:nodoc:
|
102
|
-
links[locale].
|
102
|
+
links[locale].each_pair do |from, to|
|
103
103
|
return [from, to] if key[0, from.length] == from
|
104
104
|
end && nil
|
105
105
|
end
|
@@ -110,4 +110,4 @@ module I18n
|
|
110
110
|
|
111
111
|
end
|
112
112
|
end
|
113
|
-
end
|
113
|
+
end
|
data/lib/i18n/backend/memoize.rb
CHANGED
data/lib/i18n/version.rb
CHANGED
@@ -8,7 +8,7 @@ class I18nBackendFallbacksTranslateTest < I18n::TestCase
|
|
8
8
|
def setup
|
9
9
|
super
|
10
10
|
I18n.backend = Backend.new
|
11
|
-
store_translations(:en, :foo => 'Foo in :en', :bar => 'Bar in :en', :buz => 'Buz in :en')
|
11
|
+
store_translations(:en, :foo => 'Foo in :en', :bar => 'Bar in :en', :buz => 'Buz in :en', :interpolate => 'Interpolate %{value}')
|
12
12
|
store_translations(:de, :bar => 'Bar in :de', :baz => 'Baz in :de')
|
13
13
|
store_translations(:'de-DE', :baz => 'Baz in :de-DE')
|
14
14
|
store_translations(:'pt-BR', :baz => 'Baz in :pt-BR')
|
@@ -20,6 +20,10 @@ class I18nBackendFallbacksTranslateTest < I18n::TestCase
|
|
20
20
|
assert_equal 'Baz in :de-DE', I18n.t(:baz, :locale => :'de-DE')
|
21
21
|
end
|
22
22
|
|
23
|
+
test "returns interpolated value if no key provided" do
|
24
|
+
assert_equal 'Interpolate %{value}', I18n.t(:interpolate)
|
25
|
+
end
|
26
|
+
|
23
27
|
test "returns the :en translation for a missing :de translation" do
|
24
28
|
assert_equal 'Foo in :en', I18n.t(:foo, :locale => :de)
|
25
29
|
end
|
@@ -55,6 +59,11 @@ class I18nBackendFallbacksTranslateTest < I18n::TestCase
|
|
55
59
|
assert_equal({}, I18n.t(:missing_bar, :locale => :'de-DE', :default => {}))
|
56
60
|
end
|
57
61
|
|
62
|
+
test "returns the :de translation for a missing :'de-DE' when :default is nil" do
|
63
|
+
assert_equal 'Bar in :de', I18n.t(:bar, :locale => :'de-DE', :default => nil)
|
64
|
+
assert_nil I18n.t(:missing_bar, :locale => :'de-DE', :default => nil)
|
65
|
+
end
|
66
|
+
|
58
67
|
test "returns the :'de-DE' default :baz translation for a missing :'de-DE' when defaults contains Symbol" do
|
59
68
|
assert_equal 'Baz in :de-DE', I18n.t(:missing_foo, :locale => :'de-DE', :default => [:baz, "Default Bar"])
|
60
69
|
end
|
@@ -44,4 +44,36 @@ class I18nBackendMemoizeTest < I18nBackendSimpleTest
|
|
44
44
|
assert I18n.available_locales.include?(:copa)
|
45
45
|
assert_equal 1, I18n.backend.spy_calls
|
46
46
|
end
|
47
|
+
|
48
|
+
module TestLookup
|
49
|
+
def lookup(locale, key, scope = [], options = {})
|
50
|
+
keys = I18n.normalize_keys(locale, key, scope, options[:separator])
|
51
|
+
keys.inspect
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_lookup_concurrent_consistency
|
56
|
+
backend_impl = Class.new(I18n::Backend::Simple) do
|
57
|
+
include TestLookup
|
58
|
+
include I18n::Backend::Memoize
|
59
|
+
end
|
60
|
+
backend = backend_impl.new
|
61
|
+
|
62
|
+
memoized_lookup = backend.send(:memoized_lookup)
|
63
|
+
|
64
|
+
assert_equal "[:foo, :scoped, :sample]", backend.translate('foo', scope = [:scoped, :sample])
|
65
|
+
|
66
|
+
results = []
|
67
|
+
30.times.inject([]) do |memo, i|
|
68
|
+
memo << Thread.new do
|
69
|
+
backend.translate('bar', scope); backend.translate(:baz, scope)
|
70
|
+
end
|
71
|
+
end.each(&:join)
|
72
|
+
|
73
|
+
memoized_lookup = backend.send(:memoized_lookup)
|
74
|
+
puts memoized_lookup.inspect if $VERBOSE
|
75
|
+
assert_equal 3, memoized_lookup.size, "NON-THREAD-SAFE lookup memoization backend: #{memoized_lookup.class}"
|
76
|
+
# if a plain Hash is used might eventually end up in a weird (inconsistent) state
|
77
|
+
end
|
78
|
+
|
47
79
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class I18nMiddlewareTest < I18n::TestCase
|
4
|
+
def setup
|
5
|
+
super
|
6
|
+
I18n.default_locale = :fr
|
7
|
+
@app = DummyRackApp.new
|
8
|
+
@middleware = I18n::Middleware.new(@app)
|
9
|
+
end
|
10
|
+
|
11
|
+
test "middleware initializes new config object after request" do
|
12
|
+
old_i18n_config_object_id = Thread.current[:i18n_config].object_id
|
13
|
+
@middleware.call({})
|
14
|
+
|
15
|
+
updated_i18n_config_object_id = Thread.current[:i18n_config].object_id
|
16
|
+
assert_not_equal updated_i18n_config_object_id, old_i18n_config_object_id
|
17
|
+
end
|
18
|
+
|
19
|
+
test "succesfully resets i18n locale to default locale by defining new config" do
|
20
|
+
@middleware.call({})
|
21
|
+
|
22
|
+
assert_equal :fr, I18n.locale
|
23
|
+
end
|
24
|
+
end
|
data/test/test_helper.rb
CHANGED
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.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sven Fuchs
|
@@ -12,8 +12,22 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2017-
|
16
|
-
dependencies:
|
15
|
+
date: 2017-10-15 00:00:00.000000000 Z
|
16
|
+
dependencies:
|
17
|
+
- !ruby/object:Gem::Dependency
|
18
|
+
name: concurrent-ruby
|
19
|
+
requirement: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - "~>"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '1.0'
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
requirements:
|
28
|
+
- - "~>"
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '1.0'
|
17
31
|
description: New wave Internationalization support for Ruby.
|
18
32
|
email: rails-i18n@googlegroups.com
|
19
33
|
executables: []
|
@@ -27,6 +41,7 @@ files:
|
|
27
41
|
- gemfiles/Gemfile.rails-4.1.x
|
28
42
|
- gemfiles/Gemfile.rails-4.2.x
|
29
43
|
- gemfiles/Gemfile.rails-5.0.x
|
44
|
+
- gemfiles/Gemfile.rails-5.1.x
|
30
45
|
- gemfiles/Gemfile.rails-master
|
31
46
|
- lib/i18n.rb
|
32
47
|
- lib/i18n/backend.rb
|
@@ -59,6 +74,7 @@ files:
|
|
59
74
|
- lib/i18n/locale/tag/parents.rb
|
60
75
|
- lib/i18n/locale/tag/rfc4646.rb
|
61
76
|
- lib/i18n/locale/tag/simple.rb
|
77
|
+
- lib/i18n/middleware.rb
|
62
78
|
- lib/i18n/tests.rb
|
63
79
|
- lib/i18n/tests/basics.rb
|
64
80
|
- lib/i18n/tests/defaults.rb
|
@@ -101,6 +117,7 @@ files:
|
|
101
117
|
- test/i18n/gettext_plural_keys_test.rb
|
102
118
|
- test/i18n/interpolate_test.rb
|
103
119
|
- test/i18n/load_path_test.rb
|
120
|
+
- test/i18n/middleware_test.rb
|
104
121
|
- test/i18n_test.rb
|
105
122
|
- test/locale/fallbacks_test.rb
|
106
123
|
- test/locale/tag/rfc4646_test.rb
|
@@ -133,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
150
|
version: 1.3.5
|
134
151
|
requirements: []
|
135
152
|
rubyforge_project: "[none]"
|
136
|
-
rubygems_version: 2.6.
|
153
|
+
rubygems_version: 2.6.11
|
137
154
|
signing_key:
|
138
155
|
specification_version: 4
|
139
156
|
summary: New wave Internationalization support for Ruby
|