From ed3623f1a9a8eedd968ac5fd7040faccbb171547 Mon Sep 17 00:00:00 2001 From: Sage Ross Date: Mon, 5 Jun 2017 13:17:18 -0700 Subject: [PATCH] Improve error message for missing pluralization key The error message for InvalidPluralizationData should include the missing key that triggered the error. For non-default pluralization rules like the CLDR rules for many languages, the sought-for key will not be obvious from the count. Also, the force_invalid_pluralization_data method in exceptions_test was not actually raising an exception, so a few assertions that relied on it were not being tested. --- lib/i18n/backend/base.rb | 4 ++-- lib/i18n/backend/pluralization.rb | 2 +- lib/i18n/exceptions.rb | 8 ++++---- test/i18n/exceptions_test.rb | 15 +++++++++------ 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/lib/i18n/backend/base.rb b/lib/i18n/backend/base.rb index 124d9ef5..c8bb070f 100644 --- a/lib/i18n/backend/base.rb +++ b/lib/i18n/backend/base.rb @@ -136,14 +136,14 @@ def resolve(locale, object, subject, options = {}) # - It will pick the :other subkey otherwise. # - It will pick the :zero subkey in the special case where count is # equal to 0 and there is a :zero subkey present. This behaviour is - # not stand with regards to the CLDR pluralization rules. + # not standard with regards to the CLDR pluralization rules. # Other backends can implement more flexible or complex pluralization rules. def pluralize(locale, entry, count) return entry unless entry.is_a?(Hash) && count key = :zero if count == 0 && entry.has_key?(:zero) key ||= count == 1 ? :one : :other - raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key) + raise InvalidPluralizationData.new(entry, count, key) unless entry.has_key?(key) entry[key] end diff --git a/lib/i18n/backend/pluralization.rb b/lib/i18n/backend/pluralization.rb index c73a009a..01e68d27 100644 --- a/lib/i18n/backend/pluralization.rb +++ b/lib/i18n/backend/pluralization.rb @@ -32,7 +32,7 @@ def pluralize(locale, entry, count) pluralizer = pluralizer(locale) if pluralizer.respond_to?(:call) key = count == 0 && entry.has_key?(:zero) ? :zero : pluralizer.call(count) - raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key) + raise InvalidPluralizationData.new(entry, count, key) unless entry.has_key?(key) entry[key] else super diff --git a/lib/i18n/exceptions.rb b/lib/i18n/exceptions.rb index c0d7477c..7e8b0d69 100644 --- a/lib/i18n/exceptions.rb +++ b/lib/i18n/exceptions.rb @@ -71,10 +71,10 @@ class MissingTranslationData < ArgumentError end class InvalidPluralizationData < ArgumentError - attr_reader :entry, :count - def initialize(entry, count) - @entry, @count = entry, count - super "translation data #{entry.inspect} can not be used with :count => #{count}" + attr_reader :entry, :count, :key + def initialize(entry, count, key) + @entry, @count, @key = entry, count, key + super "translation data #{entry.inspect} can not be used with :count => #{count}. key '#{key}' is missing." end end diff --git a/test/i18n/exceptions_test.rb b/test/i18n/exceptions_test.rb index 3e528c64..84e1c8fc 100644 --- a/test/i18n/exceptions_test.rb +++ b/test/i18n/exceptions_test.rb @@ -32,16 +32,19 @@ def test_invalid_locale_stores_locale end end - test "InvalidPluralizationData stores entry and count" do + test "InvalidPluralizationData stores entry, count and key" do force_invalid_pluralization_data do |exception| - assert_equal [:bar], exception.entry + assert_equal({:other => "bar"}, exception.entry) assert_equal 1, exception.count + assert_equal :one, exception.key end end - test "InvalidPluralizationData message contains count and data" do + test "InvalidPluralizationData message contains count, data and missing key" do force_invalid_pluralization_data do |exception| - assert_equal 'translation data [:bar] can not be used with :count => 1', exception.message + assert_match '1', exception.message + assert_match '{:other=>"bar"}', exception.message + assert_match 'one', exception.message end end @@ -71,7 +74,7 @@ def test_invalid_locale_stores_locale assert_equal 'reserved key :scope used in "%{scope}"', exception.message end end - + test "MissingTranslationData#new can be initialized with just two arguments" do assert I18n::MissingTranslationData.new('en', 'key') end @@ -92,7 +95,7 @@ def force_missing_translation_data(options = {}) end def force_invalid_pluralization_data - store_translations('de', :foo => [:bar]) + store_translations('de', :foo => { :other => 'bar' }) I18n.translate(:foo, :count => 1, :locale => :de) rescue I18n::ArgumentError => e block_given? ? yield(e) : raise(e)