-
-
Notifications
You must be signed in to change notification settings - Fork 417
Description
What I tried to do
When using I18n::Locale::Tag::Rfc4646, I18n::Locale::Fallbacks#[] will throw a NoMethodError exception if the locale isn't an RFC 4646 locale.
What I expected to happen
I expected it to return the locale itself with no fallbacks, similar to the behaviour of I18n::Locale::Tag::Simple.
Alternatively, raise an exception related to the locale.
What actually happened
NoMethodError: undefined method `self_and_parents' for nil:NilClass
lib/i18n/locale/fallbacks.rb:95:in `block in compute'
lib/i18n/locale/fallbacks.rb:94:in `each'
lib/i18n/locale/fallbacks.rb:94:in `compute'
lib/i18n/locale/fallbacks.rb:64:in `[]'
test/locale/fallbacks_test.rb:19:in `block in <class:I18nFallbacksDefaultsTest>'
This is due to I18n::Locale::Fallbacks assuming that I18n::Locale::Tag#tag cannot return nil, which is the case for I18n::Locale::Tag::Simple, but not I18n::Locale::Tag::Rfc4646.
There's a type mismatch. Which case is wrong is up for debate: is the return type of I18n::Locale::Tag#tag String or T.nilable(String) (using Sorbet type syntax)?
Versions of i18n, rails, and anything else you think is necessary
Latest Ruby and i18n, but the problematic code goes back to the 2009-07 (when both of these files were introduced):
➜ i18n git:(master) ruby --version
ruby 3.3.4 (2024-07-09 revision be1089c8ec) [arm64-darwin23]
➜ i18n git:(master) bundle list
Gems included by the bundle:
* concurrent-ruby (1.3.4)
* i18n (1.14.6)
* json (2.9.1)
* minitest (5.25.4)
* mocha (2.1.0)
* racc (1.8.1)
* rake (13.2.1)
* ruby2_keywords (0.0.5)
* test_declarative (0.0.6)
Potential tests for test/locale/fallbacks_test.rb:
test "handles invalid RFC 4646 locales with I18n::Locale::Tag::Simple" do
I18n::Locale::Tag.implementation = I18n::Locale::Tag::Simple
fallbacks = Fallbacks.new
invalid_locale = :"123" # Invalid RFC 4646 locale
assert_equal([:"123"], fallbacks[invalid_locale])
end
test "handles invalid RFC 4646 locales with I18n::Locale::Tag::Rfc4646" do
I18n::Locale::Tag.implementation = I18n::Locale::Tag::Rfc4646
fallbacks = Fallbacks.new
invalid_locale = :"123" # Invalid RFC 4646 locale
assert_equal([:"123"], fallbacks[invalid_locale])
end