jsonparse: Add basic JSON parser
Some TODO's left and this needs benchmarking.
This commit is contained in:
parent
aebe5a93dc
commit
7cdc02e399
8 changed files with 508 additions and 21 deletions
172
t/json_parse.t
Normal file
172
t/json_parse.t
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
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;
|
||||
Loading…
Add table
Add a link
Reference in a new issue