i18n 0.8.6 → 0.9.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
  SHA1:
3
- metadata.gz: 9edfdb04f9f18e15e4cf08fd28360a80c0ce7a22
4
- data.tar.gz: 855de9451e9b408c46f42d9105e6a31d1f2c9018
3
+ metadata.gz: dacd9a4d17f9bead5f815c49595c00d1531ed4d7
4
+ data.tar.gz: 1e4d2ba2b94da73f8dbde1957508a849f7162172
5
5
  SHA512:
6
- metadata.gz: efb2ecd003577c7b663969ca3849631e3e9ccdb64adf97b0616d99f62da2d29028a3cb0f194479861a8d5133b30e263eca1f5061a830047822d894f7f2dd56ba
7
- data.tar.gz: 474bb30ec7bf4f78ce176a8e3410b72cf1f4edd32b5a7b45389e80c3fe6de2dcff5a48739a432c369959aa5008079a896d7bd4ba418529d64082d7ecbe90d837
6
+ metadata.gz: f59e2cfebd1627b138d763d6b035078729cc62104697189e8781003aeb6537e8682e5f4f0ea0ad68e30f36873d895fdb863d8fca3abece2c48cb229e170ccb92
7
+ data.tar.gz: cd5c4bc9940ccfe400eda8696d8d9bf7630da4c4e67f46a0a6be9f799f64a54fb8d2bdcb9c80dfdeeb3dfc9e14f10d1af715d45dc230415e3491c7b6a187d3e6
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec :path => '..'
4
+
5
+ gem 'activesupport', '~> 5.1.0'
6
+ gem 'mocha'
7
+ gem 'test_declarative'
8
+ gem 'rake'
9
+ gem 'minitest'
@@ -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
- default = extract_non_symbol_default!(options) if options[:default]
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 if (result.nil? && options.key?(:default) && options[:default].nil?) || !result.nil?
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 => default)) if 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
 
@@ -43,7 +43,7 @@ module I18n
43
43
 
44
44
  # Store flattened links.
45
45
  def links
46
- @links ||= Hash.new { |h,k| h[k] = {} }
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].each do |from, to|
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
@@ -34,7 +34,7 @@ module I18n
34
34
  end
35
35
 
36
36
  def memoized_lookup
37
- @memoized_lookup ||= Hash.new { |h, k| h[k] = {} }
37
+ @memoized_lookup ||= I18n.new_double_nested_cache
38
38
  end
39
39
 
40
40
  def reset_memoizations!(locale=nil)
@@ -0,0 +1,15 @@
1
+ module I18n
2
+ class Middleware
3
+
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ @app.call(env)
10
+ ensure
11
+ Thread.current[:i18n_config] = I18n::Config.new
12
+ end
13
+
14
+ end
15
+ end
@@ -1,3 +1,3 @@
1
1
  module I18n
2
- VERSION = "0.8.6"
2
+ VERSION = "0.9.0"
3
3
  end
@@ -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
@@ -53,3 +53,9 @@ class I18n::TestCase < TEST_CASE
53
53
  File.dirname(__FILE__) + '/test_data/locales'
54
54
  end
55
55
  end
56
+
57
+ class DummyRackApp
58
+ def call(env)
59
+ I18n.locale = :es
60
+ end
61
+ 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.8.6
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-07-10 00:00:00.000000000 Z
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.10
153
+ rubygems_version: 2.6.11
137
154
  signing_key:
138
155
  specification_version: 4
139
156
  summary: New wave Internationalization support for Ruby