JSON-YY
view release on metacpan or search on metacpan
t/14_unicode.t view on Meta::CPAN
use strict;
use warnings;
use Test::More;
use JSON::YY qw(encode_json decode_json);
use JSON::YY ':doc';
# surrogate pairs (emoji via \uXXXX\uXXXX)
{
my $json = '{"emoji":"\\uD83D\\uDE00"}'; # U+1F600 grinning face
my $data = decode_json($json);
my $emoji = $data->{emoji};
is length($emoji), 1, 'surrogate pair decodes to single char';
ok utf8::is_utf8($emoji), 'emoji has UTF-8 flag';
# roundtrip
my $rt = decode_json(encode_json($data));
is $rt->{emoji}, $emoji, 'emoji roundtrips';
}
# direct UTF-8 emoji (4-byte)
{
my $json = "{\"e\":\"\xF0\x9F\x98\x80\"}"; # raw UTF-8 bytes for U+1F600
my $data = decode_json($json);
ok defined $data->{e}, 'direct 4-byte UTF-8 decodes';
}
# BOM handling
{
# yyjson should handle or reject BOM
my $json_bom = "\xEF\xBB\xBF{\"a\":1}";
my $data = eval { decode_json($json_bom) };
# yyjson may or may not accept BOM â just verify no crash
ok !$@ || $@ =~ /decode error/, 'BOM handling does not crash';
}
# null bytes in strings
{
my $json = '{"s":"hello\\u0000world"}';
my $data = decode_json($json);
is length($data->{s}), 11, 'null byte in string preserves length';
}
# various unicode escapes
{
my $json = '{"a":"\\u00e9","b":"\\u4e16\\u754c","c":"\\u0041"}';
my $data = decode_json($json);
is $data->{c}, 'A', '\\u0041 = A';
}
# Doc API with unicode
{
my $doc = jdoc '{"name":"\\u00e9l\\u00e8ve"}';
my $name = jgetp $doc, "/name";
ok defined $name, 'Doc API unicode jgetp';
ok utf8::is_utf8($name) || length($name) > 0, 'Doc API unicode string valid';
}
# unicode keys in Doc API
{
my $doc = jfrom {"\x{263a}" => "smiley"};
my @k = jkeys $doc, "";
ok utf8::is_utf8($k[0]), 'jfrom unicode key has UTF-8 flag';
}
done_testing;
( run in 1.203 second using v1.01-cache-2.11-cpan-39bf76dae61 )