<?php
declare(strict_types=1);
require __DIR__.'/ReceiptJson.php';
$checks = 0;
$oldPrecision = ini_get('serialize_precision');
ini_set('serialize_precision', '3');
foreach ([30.0, 0.0, -0.0, 1.2300000190734863, PHP_INT_MAX,
          '9007199254740993.01', '0.00', null, true, [],
          ['a'=>30.0,'nested'=>[1,1.0,'1','中文🚀']]] as $value) {
    $json = DmReceiptJson::encode($value);
    $decoded = json_decode($json, true);
    if (gettype($decoded)!==gettype($value)) throw new RuntimeException('Type changed');
    if (is_float($value) && pack('d',$value)!==pack('d',$decoded)) throw new RuntimeException('Float changed');
    if (ini_get('serialize_precision')!=='3') throw new RuntimeException('Process JSON precision not restored');
    ++$checks;
}
foreach ([INF,NAN,new stdClass()] as $invalid) {
    try { DmReceiptJson::encode($invalid); throw new LogicException('Unsafe value accepted'); }
    catch (InvalidArgumentException $expected) { ++$checks; }
}
try { DmReceiptJson::encode("\xFF"); throw new LogicException('Invalid UTF8 accepted'); }
catch (JsonException $expected) { ++$checks; }
if (ini_get('serialize_precision')!=='3') throw new RuntimeException('Exception failed to restore precision');
ini_set('serialize_precision',(string)$oldPrecision);
echo json_encode(['assertions'=>$checks,'passed'=>true,'database_operations'=>0,'filesystem_operations'=>0]),PHP_EOL;
