fu/t/json_parse.t
Yorhel 7cdc02e399 jsonparse: Add basic JSON parser
Some TODO's left and this needs benchmarking.
2025-01-31 07:29:06 +01:00

172 lines
3.2 KiB
Perl

use v5.36;
use Test::More;
use FU::Util 'json_parse';
no warnings 'experimental::builtin';
use builtin 'is_bool', 'created_as_number';
my @error = (
'',
'tru',
'nul',
'fals',
'true,',
'"',
"\"\x00\"",
'"\x"',
'"\u',
'" \u123',
'"\\',
'"\ud812"',
'"\u123g"',
'"\udc12"',
'"\udc12\u1234"',
"\"\x{110000}\"",
'1.',
'01',
'1e',
'1e+',
'1x',
'1e-',
'--1',
'+1',
'0x1',
'1..1',
'1ee1',
'1e1.1',
' [ ',
'[,true]',
'[true,]',
'[,]',
' { ',
'{1:2}',
'{""}',
'{"":}',
'{"":1',
'{"":1,}',
'{,}',
'{"":1,"":2}',
);
for my $s (@error) {
ok !eval { json_parse($s); 1 };
}
my $v;
ok !defined json_parse " null ";
$v = json_parse " true \t\r\n ";
ok is_bool $v;
ok $v;
$v = json_parse " false ";
ok is_bool $v;
ok !$v;
sub str($in, $exp) {
utf8::encode(my $str = $in);
my $out = json_parse($in);
is $out, $exp, $str;
ok utf8::is_utf8($out);
$out = json_parse($str, utf8 => 1);
is $out, $exp, $str;
ok utf8::is_utf8($out);
}
str '""', '';
str '"hello, world"', 'hello, world';
str '"\u0000\u0099\u0234\u1234"', "\x{00}\x{99}\x{234}\x{1234}";
str "\"\x{7f}\x{99}\x{234}\x{1234}\x{12345}\"", "\x{7f}\x{99}\x{234}\x{1234}\x{12345}";
str '"\/\"\\\\\b\t\n\f\r"', "/\"\\\x{08}\x{09}\x{0a}\x{0c}\x{0d}";
str '"\uD83D\uDE03"', "\x{1F603}";
sub num($in, $exp=$in) {
my $out = json_parse($in);
is $out, $exp;
ok created_as_number $out;
}
num 0;
num ' -0 ', 0;
num '-9223372036854775808';
num '9223372036854775807';
num '18446744073709551615';
num '-9223372036854775809', -9.22337203685478e+18;
num '18446744073709551616', 1.84467440737096e+19;
num '1.234';
num '1e5', 100000;
num '1e+5', 100000;
num '1e-5', 0.00001;
num '2.5e-5', 0.000025;
num '2.5e5', 250000;
num '2.5E5', 250000;
num '-0.000000000000000000000000000000000000000000000000000000000000000000000000000001', -1e-78;
$v = json_parse ' [ ] ';
is ref $v, 'ARRAY';
is scalar @$v, 0;
$v = json_parse ' [ true , null , false ] ';
is ref $v, 'ARRAY';
is scalar @$v, 3;
ok $v->[0];
ok !defined $v->[1];
ok !$v->[2];
$v = json_parse ' [true,null,false] ';
is ref $v, 'ARRAY';
is scalar @$v, 3;
ok $v->[0];
ok !defined $v->[1];
ok !$v->[2];
$v = json_parse ' [ [] ] ';
is ref $v, 'ARRAY';
is scalar @$v, 1;
is ref $v->[0], 'ARRAY';
is scalar $v->[0]->@*, 0;
$v = json_parse '{}';
is ref $v, 'HASH';
is keys %$v, 0;
$v = json_parse '{"a":1}';
is ref $v, 'HASH';
is keys %$v, 1;
is $v->{a}, 1;
sub large($s) {
$v = json_parse $s;
is ref $v, 'HASH';
is keys %$v, 3;
ok exists $v->{a};
is ref $v->{a}, 'ARRAY';
is scalar $v->{a}->@*, 5;
ok created_as_number $v->{a}[0];
is $v->{a}[0], 1;
ok created_as_number $v->{a}[1];
is $v->{a}[1], 0.1;
ok is_bool $v->{a}[2];
ok $v->{a}[2];
ok !defined $v->{a}[3];
is ref $v->{a}[4], 'HASH';
is keys $v->{a}[4]->%*, 0;
ok exists $v->{''};
ok created_as_number $v->{''};
is $v->{''}, 0;
ok exists $v->{'ë'};
is ref $v->{'ë'}, 'ARRAY';
is scalar $v->{'ë'}->@*, 0;
}
large '{"a":[1,0.1,true,null,{}],"":-0,"ë":[]}';
large ' {
"a" : [ 1 , 0.1 , true , null , { } ] ,
"" : -0 ,
"ë" : [ ]
} ';
done_testing;