1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
use strict;
use Cpanel::JSON::XS;
use Test::More;
use Config;
plan skip_all => "Yet unhandled inf/nan with $^O" if $^O eq 'dec_osf';
plan tests => 24;
# infnan_mode = 0:
is encode_json([9**9**9]), '[null]', "inf -> null stringify_infnan(0)";
is encode_json([-sin(9**9**9)]), '[null]', "nan -> null";
is encode_json([-9**9**9]), '[null]', "-inf -> null";
is encode_json([sin(9**9**9)]), '[null]', "-nan -> null";
is encode_json([9**9**9/9**9**9]), '[null]', "-nan -> null";
# infnan_mode = 1: # platform specific strings
my $json = Cpanel::JSON::XS->new->stringify_infnan;
my $have_qnan = ($^O eq 'MSWin32' || $^O eq 'aix') ? 1 : 0;
# TODO dec_osf
my ($inf, $nan) =
($^O eq 'MSWin32') ? ('1.#INF','1.#QNAN') :
($^O eq 'solaris') ? ('Infinity','NaN') :
($^O eq 'aix') ? ('inf','NANQ') :
($^O eq 'hpux') ? ('++','-?') :
('inf','nan');
my $neg_nan =
($^O eq 'MSWin32') ? "-1.#IND" :
($^O eq 'hpux') ? "?" :
"-".$nan;
my $neg_inf =
($^O eq 'hpux') ? "---" :
"-".$inf;
if ($^O eq 'MSWin32'
and $Config{ccflags} =~ /-D__USE_MINGW_ANSI_STDIO/
and $Config{uselongdouble})
{
$have_qnan = 0;
($inf, $neg_inf, $nan, $neg_nan) = ('inf','-inf','nan','-nan');
}
# newlib and glibc 2.5 have no -nan support, just nan. The BSD's neither, but they might
# come up with it lateron, as darwin did.
#if ($^O eq 'cygwin' or ($Config{glibc_version} && $Config{glibc_version} < 2.6)) {
# $neg_nan = $nan;
#}
my $r = $json->encode([9**9**9]);
$r =~ s/\.0$// if $^O eq 'MSWin32';
is $r, "[\"$inf\"]", "inf -> \"inf\" stringify_infnan(1)";
$r = $json->encode([-9**9**9]);
$r =~ s/\.0$// if $^O eq 'MSWin32';
is $r, "[\"$neg_inf\"]", "-inf -> \"-inf\"";
# The concept of negative nan is not portable and varies too much.
# Windows even emits neg_nan for the first test sometimes. HP-UX has all tests reverse.
like $json->encode([-sin(9**9**9)]), qr/\[\"(\Q$neg_nan\E|\Q$nan\E)\"\]/, "nan -> \"nan\"";
like $json->encode([sin(9**9**9)]), qr/\[\"(\Q$neg_nan\E|\Q$nan\E)\"\]/, "-nan -> \"-nan\"";
like $json->encode([9**9**9/9**9**9]), qr/\[\"(\Q$neg_nan\E|\Q$nan\E)\"\]/, "-nan -> \"-nan\"";
# infnan_mode = 2: # inf/nan values, as in JSON::XS and older releases.
$json = Cpanel::JSON::XS->new->stringify_infnan(2);
is $json->encode([9**9**9]), "[$inf]", "inf stringify_infnan(2)";
is $json->encode([-9**9**9]), "[$neg_inf]", "-inf";
like $json->encode([-sin(9**9**9)]), qr/\[(\Q$neg_nan\E|\Q$nan\E)\]/, "nan";
like $json->encode([sin(9**9**9)]), qr/\[(\Q$neg_nan\E|\Q$nan\E)\]/, "-nan";
like $json->encode([9**9**9/9**9**9]), qr/\[(\Q$neg_nan\E|\Q$nan\E)\]/, "-nan";
# infnan_mode = 3: # inf/nan values unified to inf/-inf/nan strings. no qnan/snan/negative nan
$json = Cpanel::JSON::XS->new->stringify_infnan(3);
is $json->encode([9**9**9]), '["inf"]', "inf stringify_infnan(3)";
is $json->encode([-9**9**9]), '["-inf"]', "-inf";
is $json->encode([-sin(9**9**9)]), '["nan"]', "nan";
is $json->encode([9**9**9/9**9**9]), '["nan"]', "nan or -nan";
is $json->encode([sin(9**9**9)]), '["nan"]', "nan or -nan";
my $num = 3;
my $str = "$num";
is encode_json({test => [$num, $str]}), '{"test":[3,"3"]}', 'int dualvar';
$num = 3.21;
$str = "$num";
is encode_json({test => [$num, $str]}), '{"test":[3.21,"3.21"]}', 'numeric dualvar';
$str = '0 but true';
$num = 1 + $str;
# 5.6 is broken, converts $num (IV+PV) to pure NV
my $resnum = ($] < 5.007) ? '1.0' : '1';
is encode_json({test => [$num, $str]}), qq|{"test":[$resnum,"0 but true"]}|,
'int/string dualvar';
$str = 'bar';
{ no warnings "numeric"; $num = 23 + $str }
# 5.6 and >5.10 is also arguably broken:
# converts $num (IV+PV) to pure NOK+POK, not IOK+POK.
$resnum = ($] > 5.007 && $] <= 5.010) ? '23' : '23.0';
is encode_json({test => [$num, $str]}), qq|{"test":[$resnum,"bar"]}|,
'int/string dualvar';
|