Skip to content

Commit

Permalink
some tests and fixes for some cache invalidation misses
Browse files Browse the repository at this point in the history
  • Loading branch information
doits committed Sep 8, 2016
1 parent 544488c commit 70e6249
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
32 changes: 32 additions & 0 deletions lib/i18n/globals.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class Config
class CachedGlobals < Hash
def []=(key, val)
clear_cache
annotate_hash(val) if val.is_a?(Hash) # see annotate hash below why whis must be done
super(key, val)
end

Expand All @@ -17,6 +18,17 @@ def for_locale(locale)
end
end

def clear
clear_cache
super
end

def merge!(val)
# see annotate hash below why whis must be done
val.select { |_, v| v.is_a?(Hash) }.each { |_, v| annotate_hash(v) }
super(val)
end

private

def globals_cache
Expand All @@ -26,6 +38,26 @@ def globals_cache
def clear_cache
@globals_cache = {}
end

# This is a little bit cumbersome. It might happen that this is done:
#
# I18n.config.globals[:en][:welcome] = 'Hello'
#
# What this does is changing the locale dependent version of `welcome`.
# Unfortunately we only override `:[]=` for our globals hash so it
# does not detect that the globals have been changed.
#
# To overcome this we annotate every hash that might passed in with this
# method. So when the sub hash is changed like above, the whole cache
# is cleared like it should.
def annotate_hash(hash)
return if hash.instance_variable_get(:@cached_global)
hash.instance_variable_set(:@cached_global, self)
def hash.[]=(key, value)
super(key, value)
@cached_global.send(:clear_cache)
end
end
end

def globals
Expand Down
60 changes: 60 additions & 0 deletions test/test_i18n_globals.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ class TestI18nGlobals < Minitest::Test
def setup
I18n.backend.load_translations 'test/fixtures/translations.yml'
I18n.config = I18n::Config.new
I18n.config.globals = {} # glear globals between runs
I18n.locale = :en
end

def test_that_simple_translations_work
Expand Down Expand Up @@ -70,4 +72,62 @@ def test_that_global_variables_are_shared_between_config_instances

assert_equal I18n.translate('greeting'), 'Hi there, Greg!'
end

def test_that_locale_dependent_variable_overrides_default_one
I18n.config.globals = {
name: 'Greg',
en: { name: 'Debby' }
}

assert_equal 'Hi there, Debby!', I18n.translate('greeting')
end

def test_that_default_variable_is_used_if_no_special_locale_version_is_present
I18n.config.globals = {
name: 'Greg',
fr: { name: 'Debora' }
}

assert_equal 'Hi there, Greg!', I18n.translate('greeting')
end

def test_that_cache_is_cleared_after_setting_a_new_locale_global
I18n.config.globals = {
name: 'Greg',
en: { name: 'Debby' }
}

assert_equal 'Hi there, Debby!', I18n.translate('greeting')

I18n.config.globals[:en][:name] = 'Elisa'

assert_equal 'Hi there, Elisa!', I18n.translate('greeting')
end

def test_that_cache_is_cleared_after_setting_a_new_locale_hash
I18n.config.globals = {
name: 'Greg',
en: { name: 'Debby' }
}

assert_equal 'Hi there, Debby!', I18n.translate('greeting')

I18n.config.globals[:en] = {
name: 'Elisa'
}

assert_equal 'Hi there, Elisa!', I18n.translate('greeting')
end

def test_that_cache_is_cleared_after_setting_a_new_global
I18n.config.globals = {
name: 'Greg'
}

assert_equal 'Hi there, Greg!', I18n.translate('greeting')

I18n.config.globals[:name] = 'Dobby'

assert_equal 'Hi there, Dobby!', I18n.translate('greeting')
end
end

0 comments on commit 70e6249

Please sign in to comment.