diff --git a/lib/i18n/backend/lazy_loadable.rb b/lib/i18n/backend/lazy_loadable.rb index f519960f..f5ac7788 100644 --- a/lib/i18n/backend/lazy_loadable.rb +++ b/lib/i18n/backend/lazy_loadable.rb @@ -118,14 +118,17 @@ def available_locales # Load translations from files that belong to the current locale. def init_translations + invalid_files = [] + if lazy_load? - load_translations(filenames_for_current_locale) + load_translations(filenames_for_current_locale) { |file, translations| invalid_files << file unless file_named_correctly?(file, translations) } initialized_locales[I18n.locale] = true else - super - filenames_named_incorrectly = I18n.load_path.reject { |path| file_named_correctly?(path) } - raise InvalidFilenames.new(filenames_named_incorrectly) unless filenames_named_incorrectly.empty? + load_translations { |file, translations| invalid_files << file unless file_named_correctly?(file, translations) } + @initialized = true end + + raise InvalidFilenames.new(invalid_files) unless invalid_files.empty? end def initialized_locales @@ -144,9 +147,13 @@ def supported_extension?(path) path.end_with?(*SUPPORTED_EXTENSIONS) end - def file_named_correctly?(path) - extracted_locale = LocaleExtractor.locale_from_path(path) - available_locales.include?(extracted_locale) + # Checks if a filename is named in correspondence to the translations it loaded. + # The locale extracted from the path must be the single locale loaded in the translations. + def file_named_correctly?(path, translations) + locales = translations.keys.map(&:to_sym) + return false unless locales.one? + + LocaleExtractor.locale_from_path(path) == locales.first end end end diff --git a/test/backend/lazy_loadable_test.rb b/test/backend/lazy_loadable_test.rb index 50076c66..7d655bd8 100644 --- a/test/backend/lazy_loadable_test.rb +++ b/test/backend/lazy_loadable_test.rb @@ -111,6 +111,30 @@ def setup end end + test "lazy mode: raises error if translations loaded don't correspond to locale extracted from filename" do + filename = ["en_", ".yml"] + file_contents = { fr: { dog: "chien" } }.to_yaml + + with_lazy_mode do + with_translation_file_in_load_path(filename, nil, file_contents) do |file_path| + exception = assert_raises(I18n::InvalidFilenames) { I18n.t("foo.bar") } + assert_equal "Locales cannot be extracted from the following paths: #{[file_path]}", exception.message + end + end + end + + test "lazy mode: raises error if translations for more than one locale are loaded from a single file" do + filename = ["en_", ".yml"] + file_contents = { en: { alice: "bob" }, fr: { dog: "chien" } }.to_yaml + + with_lazy_mode do + with_translation_file_in_load_path(filename, nil, file_contents) do |file_path| + exception = assert_raises(I18n::InvalidFilenames) { I18n.t("foo.bar") } + assert_equal "Locales cannot be extracted from the following paths: #{[file_path]}", exception.message + end + end + end + test "eager mode: load all translations, irrespective of locale" do with_eager_mode do @backend.reload!