///|
test "serializer emits fixed standard member order" {
let p = unwrap_problem(
"{\"instance\":\"/i\",\"detail\":\"D\",\"status\":400,\"title\":\"T\",\"type\":\"urn:x\"}",
)
assert_str_eq(
serialize_problem(p),
"{\"type\":\"urn:x\",\"title\":\"T\",\"status\":400,\"detail\":\"D\",\"instance\":\"/i\"}",
)
}
///|
test "serializer sorts extensions lexically" {
assert_str_eq(
serialize_problem(unwrap_problem("{\"z\":1,\"a\":2}")),
"{\"a\":2,\"z\":1}",
)
}
///|
test "serializer does not synthesize about blank" {
assert_str_eq(serialize_problem(unwrap_problem("{}")), "{}")
}
///|
test "serializer escapes strings through core json" {
assert_str_eq(
serialize_problem(unwrap_problem("{\"title\":\"a\\nb\\\"c\"}")),
"{\"title\":\"a\\nb\\\"c\"}",
)
}
///|
test "serializer preserves extension number" {
assert_str_eq(
serialize_problem(unwrap_problem("{\"x\":12.5}")),
"{\"x\":12.5}",
)
}
///|
test "serializer preserves extension null" {
assert_str_eq(
serialize_problem(unwrap_problem("{\"x\":null}")),
"{\"x\":null}",
)
}
///|
test "serializer preserves extension array" {
assert_str_eq(
serialize_problem(unwrap_problem("{\"x\":[1,true,null]}")),
"{\"x\":[1,true,null]}",
)
}
///|
test "canonicalization is idempotent" {
let first = canonicalize_problem_json("{\"z\":1,\"title\":\"T\"}").unwrap()
assert_str_eq(canonicalize_problem_json(first).unwrap(), first)
}
///|
test "semantic roundtrip includes nested extension values" {
let p = unwrap_problem("{\"meta\":{\"a\":[1,false,null]},\"status\":422}")
assert_true(unwrap_problem(serialize_problem(p)) == p)
}
///|
test "canonicalization reports errors" {
assert_true(canonicalize_problem_json("[") is Err(_))
}