diff --git a/test/backend/memoize_test.rb b/test/backend/memoize_test.rb index 0fb9f904..5b63f23f 100644 --- a/test/backend/memoize_test.rb +++ b/test/backend/memoize_test.rb @@ -44,4 +44,39 @@ def test_resets_available_locales_on_store_translations assert I18n.available_locales.include?(:copa) assert_equal 1, I18n.backend.spy_calls end + + module TestLookup + def lookup(locale, key, scope = [], options = {}) + keys = I18n.normalize_keys(locale, key, scope, options[:separator]) + keys.inspect + end + end + + def test_lookup_concurrent_consistency + backend_impl = Class.new(I18n::Backend::Simple) do + include TestLookup + include I18n::Backend::Memoize + end + backend = backend_impl.new + + memoized_lookup = backend.send(:memoized_lookup) + # make the 'default_proc' execution artificially slower to help reproduce : + default_proc = memoized_lookup.default_proc + memoized_lookup.default_proc = Proc.new { |h, k| sleep 0.1; default_proc.call(h, k) } + + assert_equal "[:foo, :scoped, :sample]", backend.translate('foo', scope = [:scoped, :sample]) + + results = [] + 30.times.inject([]) do |memo, i| + memo << Thread.new do + backend.translate('bar', scope); backend.translate(:baz, scope) + end + end.each(&:join) + + memoized_lookup = backend.send(:memoized_lookup) + puts memoized_lookup.inspect if $VERBOSE + assert_equal 3, memoized_lookup.size, "NON-THREAD-SAFE lookup memoization backend: #{memoized_lookup.class}" + # if a plain Hash is used might eventually end up in a weird (inconsistent) state + end + end