diff --git a/lib/i18n/backend/base.rb b/lib/i18n/backend/base.rb index 73c34315..9f9df168 100644 --- a/lib/i18n/backend/base.rb +++ b/lib/i18n/backend/base.rb @@ -221,17 +221,18 @@ def deep_interpolate(locale, data, values = EMPTY_HASH) def load_file(filename) type = File.extname(filename).tr('.', '').downcase raise UnknownFileType.new(type, filename) unless respond_to?(:"load_#{type}", true) - data = send(:"load_#{type}", filename) + data, keys_symbolized = send(:"load_#{type}", filename) unless data.is_a?(Hash) raise InvalidLocaleData.new(filename, 'expects it to return a hash, but does not') end - data.each { |locale, d| store_translations(locale, d || {}) } + data.each { |locale, d| store_translations(locale, d || {}, skip_symbolize_keys: keys_symbolized) } end # Loads a plain Ruby translations file. eval'ing the file must yield # a Hash containing translation data with locales as toplevel keys. def load_rb(filename) - eval(IO.read(filename), binding, filename) + translations = eval(IO.read(filename), binding, filename) + [translations, false] end # Loads a YAML translations file. The data must have locales as @@ -239,9 +240,9 @@ def load_rb(filename) def load_yml(filename) begin if YAML.respond_to?(:unsafe_load_file) # Psych 4.0 way - YAML.unsafe_load_file(filename) + [YAML.unsafe_load_file(filename), false] else - YAML.load_file(filename) + [YAML.load_file(filename), false] end rescue TypeError, ScriptError, StandardError => e raise InvalidLocaleData.new(filename, e.inspect) @@ -255,9 +256,9 @@ def load_json(filename) begin # Use #load_file as a proxy for a version of JSON where symbolize_names and freeze are supported. if JSON.respond_to?(:load_file) - ::JSON.load_file(filename, symbolize_names: true, freeze: true) + [::JSON.load_file(filename, symbolize_names: true, freeze: true), true] else - ::JSON.parse(File.read(filename)) + [::JSON.parse(File.read(filename)), false] end rescue TypeError, StandardError => e raise InvalidLocaleData.new(filename, e.inspect) diff --git a/lib/i18n/backend/gettext.rb b/lib/i18n/backend/gettext.rb index 93a43637..07696463 100644 --- a/lib/i18n/backend/gettext.rb +++ b/lib/i18n/backend/gettext.rb @@ -41,7 +41,7 @@ def set_comment(msgid_or_sym, comment) def load_po(filename) locale = ::File.basename(filename, '.po').to_sym data = normalize(locale, parse(filename)) - { locale => data } + [{ locale => data }, false] end def parse(filename) diff --git a/lib/i18n/backend/simple.rb b/lib/i18n/backend/simple.rb index fe0ef863..687c1154 100644 --- a/lib/i18n/backend/simple.rb +++ b/lib/i18n/backend/simple.rb @@ -38,7 +38,7 @@ def store_translations(locale, data, options = EMPTY_HASH) end locale = locale.to_sym translations[locale] ||= Concurrent::Hash.new - data = Utils.deep_symbolize_keys(data) + data = Utils.deep_symbolize_keys(data) unless options.fetch(:skip_symbolize_keys, false) Utils.deep_merge!(translations[locale], data) end diff --git a/test/backend/simple_test.rb b/test/backend/simple_test.rb index d26b672f..2bafd7cd 100644 --- a/test/backend/simple_test.rb +++ b/test/backend/simple_test.rb @@ -66,17 +66,17 @@ def setup end test "simple load_rb: loads data from a Ruby file" do - data = I18n.backend.send(:load_rb, "#{locales_dir}/en.rb") + data, _ = I18n.backend.send(:load_rb, "#{locales_dir}/en.rb") assert_equal({ :en => { :fuh => { :bah => 'bas' } } }, data) end test "simple load_yml: loads data from a YAML file" do - data = I18n.backend.send(:load_yml, "#{locales_dir}/en.yml") + data, _ = I18n.backend.send(:load_yml, "#{locales_dir}/en.yml") assert_equal({ 'en' => { 'foo' => { 'bar' => 'baz' } } }, data) end test "simple load_json: loads data from a JSON file" do - data = I18n.backend.send(:load_json, "#{locales_dir}/en.json") + data, _ = I18n.backend.send(:load_json, "#{locales_dir}/en.json") assert_equal({ :en => { :foo => { :bar => 'baz' } } }, data) if JSON.respond_to?(:load_file) @@ -144,6 +144,20 @@ def setup assert_equal 'foo', I18n.t(:'1') end + test "simple store_translations: store translations doesn't deep symbolize keys if skip_symbolize_keys is true" do + data = { :foo => {'bar' => 'barfr', 'baz' => 'bazfr'} } + + # symbolized by default + store_translations(:fr, data) + assert_equal Hash[:foo, {:bar => 'barfr', :baz => 'bazfr'}], translations[:fr] + + I18n.backend.reload! + + # not deep symbolized when configured + store_translations(:fr, data, skip_symbolize_keys: true) + assert_equal Hash[:foo, {'bar' => 'barfr', 'baz' => 'bazfr'}], translations[:fr] + end + # reloading translations test "simple reload_translations: unloads translations" do diff --git a/test/test_helper.rb b/test/test_helper.rb index 1f4217e5..1b8daba3 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -45,8 +45,8 @@ def translations I18n.backend.instance_variable_get(:@translations) end - def store_translations(locale, data) - I18n.backend.store_translations(locale, data) + def store_translations(locale, data, options = I18n::EMPTY_HASH) + I18n.backend.store_translations(locale, data, options) end def locales_dir