Files
mcm-26-b/referee/tests/test_jsonio.py
T
2026-09-11 11:36:08 +08:00

57 lines
2.0 KiB
Python

"""JSON 序列化与解析的规范化行为 [题面 附件2 4.1/5.1]。"""
import json
import pytest
from referee.jsonio import (RequestFormatError, dumps, format_number,
parse_request_object)
@pytest.mark.parametrize("value,text", [
(105, "105"), (0, "0"), (5.0, "5"), (105.5, "105.5"),
(5282.843, "5282.843"), # 微秒时刻的最短表示
(0.300001, "0.300001"),
(123.45, "123.45"), # svd_deg 两位小数
(True, None), # 布尔不是数值,放这里只为参数化完整
])
def test_format_number(value, text):
if text is None:
return
assert format_number(value) == text
def test_dumps_matches_official_number_style():
body = {"accepted": True, "virtual_time_s": 105.0,
"real_timestamp_ms": 1760000000000, "svd_deg": 123.45,
"note": "中文", "ok": False, "none": None, "list": [1, 2.5]}
text = dumps(body)
assert '"virtual_time_s":105' in text # 不输出 105.0
assert '"svd_deg":123.45' in text
assert '"real_timestamp_ms":1760000000000' in text
assert '"note":"中文"' in text # 非 ASCII 不转义
assert json.loads(text) == body # 解析后语义不变
@pytest.mark.parametrize("raw", [
b'{"a":1,"a":2}', # 重复键
b'\xef\xbb\xbf{}', # BOM
b'[]', b'"str"', b'3', b'null', # 非对象
b'{"a":NaN}', b'{"a":Infinity}',
b'{"a":' + b'[' * 17 + b'0' + b']' * 17 + b'}', # 深度 17
b'{"a":', b'', b'\xff',
])
def test_parse_rejections(raw):
with pytest.raises(RequestFormatError):
parse_request_object(raw)
def test_parse_depth_16_is_legal():
payload = json.loads(b'{"extra":' + b'[' * 15 + b'0' + b']' * 15 + b'}')
assert parse_request_object(json.dumps(payload).encode()) == payload
def test_parse_rejects_duplicated_nested_keys():
with pytest.raises(RequestFormatError):
parse_request_object(b'{"position":{"x":1,"x":2}}')