diff --git a/lib/money/formatting.rb b/lib/money/formatting.rb index cd160beff..9c4df8f58 100644 --- a/lib/money/formatting.rb +++ b/lib/money/formatting.rb @@ -31,7 +31,35 @@ module Money::Formatting end def locale_options(locale) - case [ currency.iso_code, locale.to_sym ] + locale_sym = (locale || I18n.locale || :en).to_sym + + # French locale: symbol after number with non-breaking space, comma as decimal separator + if locale_sym == :fr + return { delimiter: "\u00A0", separator: ",", format: "%n\u00A0%u" } + end + + # German locale: symbol after number with space, comma as decimal separator + if locale_sym == :de + return { delimiter: ".", separator: ",", format: "%n %u" } + end + + # Spanish locale: symbol after number with space, comma as decimal separator + if locale_sym == :es + return { delimiter: ".", separator: ",", format: "%n %u" } + end + + # Italian locale: symbol after number with space, comma as decimal separator + if locale_sym == :it + return { delimiter: ".", separator: ",", format: "%n %u" } + end + + # Portuguese (Brazil) locale: symbol before, comma as decimal separator + if locale_sym == :"pt-BR" + return { delimiter: ".", separator: ",", format: "%u %n" } + end + + # Currency-specific overrides for remaining locales + case [ currency.iso_code, locale_sym ] when [ "EUR", :nl ], [ "EUR", :pt ] { delimiter: ".", separator: ",", format: "%u %n" } when [ "EUR", :en ], [ "EUR", :en_IE ] diff --git a/test/lib/money_test.rb b/test/lib/money_test.rb index 699a1ab38..7acf814c9 100644 --- a/test/lib/money_test.rb +++ b/test/lib/money_test.rb @@ -90,6 +90,29 @@ class MoneyTest < ActiveSupport::TestCase assert_equal "€ 1.000,12", Money.new(1000.12, :eur).format(locale: :nl) end + test "formats correctly for French locale" do + # French uses non-breaking spaces (NBSP = \u00A0) between thousands and before currency symbol + assert_equal "1\u00A0000,12\u00A0€", Money.new(1000.12, :eur).format(locale: :fr) + assert_equal "1\u00A0000,12\u00A0$", Money.new(1000.12, :usd).format(locale: :fr) + end + + test "formats correctly for German locale" do + assert_equal "1.000,12 €", Money.new(1000.12, :eur).format(locale: :de) + assert_equal "1.000,12 $", Money.new(1000.12, :usd).format(locale: :de) + end + + test "formats correctly for Spanish locale" do + assert_equal "1.000,12 €", Money.new(1000.12, :eur).format(locale: :es) + end + + test "formats correctly for Italian locale" do + assert_equal "1.000,12 €", Money.new(1000.12, :eur).format(locale: :it) + end + + test "formats correctly for Portuguese (Brazil) locale" do + assert_equal "R$ 1.000,12", Money.new(1000.12, :brl).format(locale: :"pt-BR") + end + test "converts currency when rate available" do ExchangeRate.expects(:find_or_fetch_rate).returns(OpenStruct.new(rate: 1.2))