#![allow(non_snake_case)]
use goish::prelude::*;
use goish::encoding::json::{self, Value};
struct EsT { r#in: &'static str, out: &'static str }
test!{ fn TestEncodeString(t) {
let tests = vec![
EsT { r#in: "\x00", out: "\"\\u0000\"" },
EsT { r#in: "\x01", out: "\"\\u0001\"" },
EsT { r#in: "\x02", out: "\"\\u0002\"" },
EsT { r#in: "\x07", out: "\"\\u0007\"" },
EsT { r#in: "\x08", out: "\"\\b\"" },
EsT { r#in: "\t", out: "\"\\t\"" },
EsT { r#in: "\n", out: "\"\\n\"" },
EsT { r#in: "\x0b", out: "\"\\u000b\"" },
EsT { r#in: "\x0c", out: "\"\\f\"" },
EsT { r#in: "\r", out: "\"\\r\"" },
EsT { r#in: "\x0e", out: "\"\\u000e\"" },
EsT { r#in: "\x1f", out: "\"\\u001f\"" },
];
for tt in &tests {
let (bytes_, err) = json::Marshal(&Value::String(tt.r#in.into()));
if err != nil { t.Errorf(Sprintf!("Marshal(%q) error: %s", tt.r#in, err)); continue; }
let got = String::from_utf8(bytes_).unwrap();
if got != tt.out {
t.Errorf(Sprintf!("Marshal(%q) = %q, want %q", tt.r#in, got, tt.out));
}
}
}}
test!{ fn TestHTMLEscape(t) {
let m = "{\"M\":\"<html>foo &\u{2028} \u{2029}</html>\"}";
let want = "{\"M\":\"\\u003chtml\\u003efoo \\u0026\\u2028 \\u2029\\u003c/html\\u003e\"}";
let mut b: Vec<u8> = Vec::new();
json::HTMLEscape(&mut b, m.as_bytes());
let got = String::from_utf8(b).unwrap();
if got != want {
t.Errorf(Sprintf!("HTMLEscape:\n\tgot: %s\n\twant: %s", got, want));
}
}}
test!{ fn TestMarshalNull(t) {
let (b, err) = json::Marshal(&Value::Null);
if err != nil { t.Errorf(Sprintf!("Marshal(Null) error: %s", err)); }
let s = String::from_utf8(b).unwrap();
if s != "null" {
t.Errorf(Sprintf!("Marshal(Null) = %q, want null", s));
}
}}
test!{ fn TestMarshalBool(t) {
let (b, _) = json::Marshal(&Value::Bool(true));
assert_eq_s(t, &String::from_utf8(b).unwrap(), "true");
let (b, _) = json::Marshal(&Value::Bool(false));
assert_eq_s(t, &String::from_utf8(b).unwrap(), "false");
}}
test!{ fn TestMarshalNumber(t) {
let (b, _) = json::Marshal(&Value::Number(42.0));
assert_eq_s(t, &String::from_utf8(b).unwrap(), "42");
let (b, _) = json::Marshal(&Value::Number(3.14));
let s = String::from_utf8(b).unwrap();
if !s.starts_with("3.14") {
t.Errorf(Sprintf!("Marshal(3.14) = %q, want starts with 3.14", s));
}
let (b, _) = json::Marshal(&Value::Number(-0.5));
assert_eq_s(t, &String::from_utf8(b).unwrap(), "-0.5");
}}
test!{ fn TestMarshalArray(t) {
let v = Value::Array(vec![
Value::Number(1.0), Value::Number(2.0), Value::Number(3.0),
]);
let (b, _) = json::Marshal(&v);
assert_eq_s(t, &String::from_utf8(b).unwrap(), "[1,2,3]");
}}
test!{ fn TestMarshalObjectPreservesInsertionOrder(t) {
let mut v = Value::Object(vec![]);
v.Set("a", Value::Number(1.0));
v.Set("b", Value::Number(2.0));
v.Set("c", Value::Number(3.0));
let (b, _) = json::Marshal(&v);
let s = String::from_utf8(b).unwrap();
if s != "{\"a\":1,\"b\":2,\"c\":3}" {
t.Errorf(Sprintf!("Marshal(ordered) = %q, want a,b,c ordered", s));
}
}}
test!{ fn TestUnsupportedValues(t) {
let (_, err) = json::Marshal(&Value::Number(f64::NAN));
let (b, err2) = json::Marshal(&Value::Number(f64::INFINITY));
if err == nil && err2 == nil {
let s = String::from_utf8(b).unwrap();
if s != "null" {
t.Errorf(Sprintf!("Marshal(+Inf) = %q, want null or error", s));
}
}
}}
test!{ fn TestMarshalIndent(t) {
let mut v = Value::Object(vec![]);
v.Set("x", Value::Number(1.0));
v.Set("y", Value::Number(2.0));
let (b, err) = json::MarshalIndent(&v, "", " ");
if err != nil { t.Errorf(Sprintf!("MarshalIndent error: %s", err)); }
let s = String::from_utf8(b).unwrap();
if !s.contains("\n \"x\"") || !s.contains("\n \"y\"") {
t.Errorf(Sprintf!("MarshalIndent output missing expected lines: %q", s));
}
}}
test!{ fn TestCompact(t) {
let pretty = b"{\n \"x\" : 1,\n \"y\" : 2\n}";
let mut out = Vec::new();
let err = json::Compact(&mut out, pretty);
if err != nil { t.Errorf(Sprintf!("Compact error: %s", err)); }
let got = String::from_utf8(out).unwrap();
if got != "{\"x\":1,\"y\":2}" {
t.Errorf(Sprintf!("Compact = %q, want compact form", got));
}
}}
test!{ fn TestIndent(t) {
let compact = b"{\"a\":1,\"b\":[2,3]}";
let mut out = Vec::new();
let err = json::Indent(&mut out, compact, "", " ");
if err != nil { t.Errorf(Sprintf!("Indent error: %s", err)); }
let got = String::from_utf8(out).unwrap();
if !got.contains("\n \"a\"") {
t.Errorf(Sprintf!("Indent did not produce pretty output: %q", got));
}
}}
test!{ fn TestMarshalRawMessageValue(t) {
let mut v = Value::Object(vec![]);
v.Set("Answer", Value::Number(42.0));
let (b, _) = json::Marshal(&v);
let s = String::from_utf8(b).unwrap();
if s != "{\"Answer\":42}" {
t.Errorf(Sprintf!("got %q want %q", s, "{\"Answer\":42}"));
}
}}
test!{ fn TestMarshalNestedObject(t) {
let inner = Value::Object(vec![
("k".into(), Value::String("v".into())),
]);
let outer = Value::Object(vec![
("inner".into(), inner),
("n".into(), Value::Number(7.0)),
]);
let (b, _) = json::Marshal(&outer);
assert_eq_s(t, &String::from_utf8(b).unwrap(),
"{\"inner\":{\"k\":\"v\"},\"n\":7}");
}}
test!{ fn TestMarshalEmpties(t) {
let cases = vec![
(Value::Array(vec![]), "[]"),
(Value::Object(vec![]), "{}"),
(Value::String("".into()), "\"\""),
];
for (v, want) in cases {
let (b, _) = json::Marshal(&v);
assert_eq_s(t, &String::from_utf8(b).unwrap(), want);
}
}}
fn assert_eq_s(t: &testing::T, got: &str, want: &str) {
if got != want {
t.Errorf(Sprintf!("got %q want %q", got, want));
}
}