Skip Menu |

This queue is for tickets about the Math-Currency CPAN distribution.

Report information
The Basics
Id: 74323
Status: resolved
Priority: 0/
Queue: Math-Currency

People
Owner: Nobody in particular
Requestors: matt.lawrence [...] virgin.net
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.47
Fixed in: 0.49



Subject: Test failure with unicode locale
t/004-localize.t is failing for me: t/004_localize.t .. 1/32 # Failed test ' '£' = '�'' # at t/004_localize.t line 45. # Looks like you failed 1 test of 32. This is a UTF-8 pound sign being compared to an iso-8859-1 character. This arises because the only en_GB locale available on this system is en_GB.utf8 $ locale -a | grep ^en_GB en_GB.utf8 In this situation, localeconv produces UTF-8 bytes for currency_symbol, so to meaningfully compare this to the single-byte version found in Math::Currency::en_GB, both values need to be decoded from the appropriate character set. The attached patch addresses this in the tests, along with a relatively minor warning about deprecated syntax and a POD formatting problem (see http://search.cpan.org/~jpeacock/Math-Currency-0.47/lib/Math/Currency.pm#Format_Parameters). I've run the tests on an environment with access to a non-unicode en_GB locale and they continue to pass after the patch. It might be preferable for the class itself to produce unicode output where appropriate, although this would probably be best provided optionally to maintain backwards compatibility.
Subject: Math-Currency-0.47.patch
diff --git a/lib/Math/Currency.pm b/lib/Math/Currency.pm index eb3b029..3170a16 100644 --- a/lib/Math/Currency.pm +++ b/lib/Math/Currency.pm @@ -681,6 +681,7 @@ like this: The format must contains all of the commonly configured LC_MONETARY Locale settings. For example, these are the values of the default US format (with comments): + { INT_CURR_SYMBOL => 'USD', # ISO currency text CURRENCY_SYMBOL => '$', # Local currency character diff --git a/t/002_basic.t b/t/002_basic.t index 3bc4cf8..f116702 100644 --- a/t/002_basic.t +++ b/t/002_basic.t @@ -41,12 +41,12 @@ sub run_tests { ok ( defined $FORMAT, "format defaults configured" ); - foreach $param qw( INT_CURR_SYMBOL CURRENCY_SYMBOL MON_DECIMAL_POINT + foreach $param (qw( INT_CURR_SYMBOL CURRENCY_SYMBOL MON_DECIMAL_POINT MON_THOUSANDS_SEP MON_GROUPING POSITIVE_SIGN NEGATIVE_SIGN INT_FRAC_DIGITS FRAC_DIGITS P_CS_PRECEDES P_SEP_BY_SPACE N_CS_PRECEDES N_SEP_BY_SPACE P_SIGN_POSN N_SIGN_POSN - ) # hardcoded keys to be sure they are all there + )) # hardcoded keys to be sure they are all there { ok ( defined $CLASS->format($param), sprintf(" \t%-20s = '%s'",$param,$CLASS->format($param)) ); } diff --git a/t/004_localize.t b/t/004_localize.t index 227d2b9..602cc5c 100644 --- a/t/004_localize.t +++ b/t/004_localize.t @@ -1,6 +1,8 @@ #!/usr/bin/perl -w use Test::More tests => 32; use Math::Currency qw($LC_MONETARY); +use Encode qw( is_utf8 decode ); +use I18N::Langinfo qw( langinfo CODESET ); # monetary_locale testing use POSIX qw( locale_h ); @@ -8,22 +10,36 @@ my $locale = setlocale( LC_ALL, "en_GB" ); my $format = {}; Math::Currency->localize( \$format ); +# hardcoded keys to be sure they are all there +my @format_keys = qw( + INT_CURR_SYMBOL + CURRENCY_SYMBOL + MON_DECIMAL_POINT + MON_THOUSANDS_SEP + MON_GROUPING + POSITIVE_SIGN + NEGATIVE_SIGN + INT_FRAC_DIGITS + FRAC_DIGITS + + P_CS_PRECEDES + P_SEP_BY_SPACE + P_SIGN_POSN + + N_CS_PRECEDES + N_SEP_BY_SPACE + N_SIGN_POSN +); + + SKIP: { skip ("No locale support", 16) unless Math::Currency->localize(); pass("Re-initialized locale with en_GB"); - foreach my $param qw( - INT_CURR_SYMBOL CURRENCY_SYMBOL MON_DECIMAL_POINT - MON_THOUSANDS_SEP MON_GROUPING POSITIVE_SIGN - NEGATIVE_SIGN INT_FRAC_DIGITS FRAC_DIGITS - P_CS_PRECEDES P_SEP_BY_SPACE N_CS_PRECEDES - N_SEP_BY_SPACE P_SIGN_POSN N_SIGN_POSN - ) # hardcoded keys to be sure they are all there - { + foreach my $param (@format_keys) { ok( defined $format->{$param}, sprintf( " \t%-20s = '%s'", $param, $format->{$param} ) ); - } - + } } SKIP: { @@ -33,18 +49,14 @@ SKIP: { unless $format->{INT_CURR_SYMBOL} =~ /GBP/; use_ok("Math::Currency::en_GB"); - foreach my $param qw( - INT_CURR_SYMBOL CURRENCY_SYMBOL MON_DECIMAL_POINT - MON_THOUSANDS_SEP MON_GROUPING POSITIVE_SIGN - NEGATIVE_SIGN INT_FRAC_DIGITS FRAC_DIGITS - P_CS_PRECEDES P_SEP_BY_SPACE N_CS_PRECEDES - N_SEP_BY_SPACE P_SIGN_POSN N_SIGN_POSN - ) # hardcoded keys to be sure they are all there - { + foreach my $param (@format_keys) { my $global_param = $LC_MONETARY->{'en_GB'}->{$param}; - ok( $format->{$param} eq $global_param, + $global_param = decode('ISO-8859-1', $global_param); + $format->{$param} = decode(langinfo(CODESET), $format->{$param}); + + is($format->{$param}, $global_param, sprintf( " \t'%s'\t= '%s'", $format->{$param}, $global_param ) ); - } + } } SKIP: { my $mckensie = Math::Currency->new("4.56","CAD");
Hi. I have just uploaded Math::Currency v0.48 to CPAN which I believe fixes this issue. Can you please let me know if you are still experiencing this error with v0.48 (which it hits the mirrors)? -- Regards, Michael Schout
Hi. I have just uploaded Math::Currency v0.48 to CPAN which I believe fixes this issue. Can you please let me know if you are still experiencing this error with v0.48 (which it hits the mirrors)? -- Regards, Michael Schout
This has been corrected in v0.49 which has just been uploaded to CPAN. The issue is really that POSIX::localeconv() returns data that is encoded in whatever the current locale setting is set to. Sometimes this is UTF-8, but it could be any other charset depending on what the locale is. In addition, perl 5.22 and later now automatically turn on the UTF8 flag if localeconv() returned UTF-8 encoded data. Math::Currency now decodes correctly (unless the UTF8 flag is already on, in which case we leave it as-is) in all of these cases, tested on 5.8.9 through 5.24.0 with tests in t/009_localeconv_encoding.t. -- Regards, Michael Schout