Skip to content

Commit

Permalink
Return (data, keys_symbolized) array from load_* methods instead
Browse files Browse the repository at this point in the history
  • Loading branch information
paarthmadan committed Dec 9, 2021
1 parent 820be73 commit 86f9919
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 29 deletions.
35 changes: 10 additions & 25 deletions lib/i18n/backend/base.rb
Expand Up @@ -216,51 +216,35 @@ def deep_interpolate(locale, data, values = EMPTY_HASH)
end
end

class LocaleDataDecorator < SimpleDelegator
def initialize(*)
super
@names_symbolized = false
end

def mark_keys_as_symbolized!
@names_symbolized = true
self
end

def keys_symbolized?
@names_symbolized
end
end

# Loads a single translations file by delegating to #load_rb or
# #load_yml depending on the file extension and directly merges the
# data to the existing translations. Raises I18n::UnknownFileType
# for all other file extensions.
def load_file(filename)
type = File.extname(filename).tr('.', '').downcase
raise UnknownFileType.new(type, filename) unless respond_to?(:"load_#{type}", true)
locale_data = send(:"load_#{type}", filename)
unless locale_data.__getobj__.is_a?(Hash)
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
locale_data.each { |locale, d| store_translations(locale, d || {}, skip_symbolize_keys: locale_data.keys_symbolized?) }
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)
translations = eval(IO.read(filename), binding, filename)
LocaleDataDecorator.new(translations)
[translations, false]
end

# Loads a YAML translations file. The data must have locales as
# toplevel keys.
def load_yml(filename)
begin
if YAML.respond_to?(:unsafe_load_file) # Psych 4.0 way
LocaleDataDecorator.new(YAML.unsafe_load_file(filename))
[YAML.unsafe_load_file(filename), false]
else
LocaleDataDecorator.new(YAML.load_file(filename))
[YAML.load_file(filename), false]
end
rescue TypeError, ScriptError, StandardError => e
raise InvalidLocaleData.new(filename, e.inspect)
Expand All @@ -272,9 +256,10 @@ def load_yml(filename)
# toplevel keys.
def load_json(filename)
begin
LocaleDataDecorator.new(
::JSON.parse(File.read(filename), symbolize_names: true, freeze: true),
).mark_keys_as_symbolized!
[
::JSON.parse(File.read(filename), symbolize_names: true, freeze: true),
true,
]
rescue TypeError, StandardError => e
raise InvalidLocaleData.new(filename, e.inspect)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/i18n/backend/gettext.rb
Expand Up @@ -43,7 +43,7 @@ def set_comment(msgid_or_sym, comment)
def load_po(filename)
locale = ::File.basename(filename, '.po').to_sym
data = normalize(locale, parse(filename))
Backend::Base::LocaleDataDecorator.new({ locale => data })
[{ locale => data }, false]
end

def parse(filename)
Expand Down
6 changes: 3 additions & 3 deletions test/backend/simple_test.rb
Expand Up @@ -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)
end

Expand Down

0 comments on commit 86f9919

Please sign in to comment.