blob: 0fe2044e545cb351dec29c8ac1c56be0d332c865 [file] [log] [blame]
#[macro_use]
extern crate json;
use json::number::Number;
use json::{ parse, JsonValue, Null };
#[test]
fn parse_true() {
assert_eq!(parse("true").unwrap(), true);
}
#[test]
fn parse_false() {
assert_eq!(parse("false").unwrap(), false);
}
#[test]
fn parse_null() {
assert!(parse("null").unwrap().is_null());
}
#[test]
fn parse_number() {
assert_eq!(parse("3.141592653589793").unwrap(), 3.141592653589793);
}
#[test]
fn uncode_identifier() {
assert!(parse("[C3A9] <=> [é]").is_err());
}
#[test]
fn parse_period_requires_digit() {
assert!(parse("[1.]").is_err());
}
#[test]
fn parse_small_number() {
assert_eq!(parse("0.05").unwrap(), 0.05);
}
#[test]
fn parse_very_long_float() {
let parsed = parse("2.22507385850720113605740979670913197593481954635164564e-308").unwrap();
// Handles convertion correctly
assert_eq!(parsed.as_f64().unwrap(), 2.225073858507201e-308);
// Exhausts u64
assert_eq!(parsed, unsafe { Number::from_parts_unchecked(true, 2225073858507201136, -326) });
}
#[test]
fn parse_very_long_exponent() {
let parsed = parse("1e999999999999999999999999999999999999999999999999999999999999").unwrap();
assert_eq!(parsed, unsafe { Number::from_parts_unchecked(true, 1, 32767) });
}
#[test]
fn parse_integer() {
assert_eq!(parse("42").unwrap(), 42);
}
#[test]
fn parse_negative_zero() {
assert_eq!(parse("-0").unwrap(), JsonValue::from(-0f64));
}
#[test]
fn parse_negative_integer() {
assert_eq!(parse("-42").unwrap(), -42);
}
#[test]
fn parse_number_with_leading_zero() {
assert!(parse("01").is_err());
}
#[test]
fn parse_negative_number_with_leading_zero() {
assert!(parse("-01").is_err());
}
#[test]
fn parse_number_with_e() {
assert_eq!(parse("5e2").unwrap(), 500);
assert_eq!(parse("5E2").unwrap(), 500);
}
#[test]
fn parse_number_with_positive_e() {
assert_eq!(parse("5e+2").unwrap(), 500);
assert_eq!(parse("5E+2").unwrap(), 500);
}
#[test]
fn parse_number_with_negative_e() {
assert_eq!(parse("5e-2").unwrap(), 0.05);
assert_eq!(parse("5E-2").unwrap(), 0.05);
}
#[test]
fn parse_number_with_invalid_e() {
assert!(parse("0e").is_err());
}
#[test]
fn parse_large_number() {
assert_eq!(parse("18446744073709551616").unwrap(), 18446744073709552000f64);
}
#[test]
fn parse_array() {
assert_eq!(parse(r#"[10, "foo", true, null]"#).unwrap(), array![
10,
"foo",
true,
Null
]);
assert_eq!(parse("[]").unwrap(), array![]);
assert_eq!(parse("[[]]").unwrap(), array![array![]]);
}
#[test]
fn parse_object() {
// Without trailing comma
assert_eq!(parse(r#"
{
"foo": "bar",
"num": 10
}
"#).unwrap(), object!{
"foo" => "bar",
"num" => 10
});
// Trailing comma in macro
assert_eq!(parse(r#"
{
"foo": "bar",
"num": 10
}
"#).unwrap(), object!{
"foo" => "bar",
"num" => 10,
});
}
#[test]
fn parse_object_duplicate_fields() {
assert_eq!(parse(r#"
{
"foo": 0,
"bar": 1,
"foo": 2
}
"#).unwrap(), object!{
"foo" => 2,
"bar" => 1
});
}
#[test]
fn parse_object_with_array(){
assert_eq!(parse(r#"
{
"foo": [1, 2, 3]
}
"#).unwrap(), object!{
"foo" => array![1, 2, 3]
});
}
#[test]
fn parse_nested_object() {
assert_eq!(parse(r#"
{
"l10n": [ {
"product": {
"inStock": {
"DE": "Lieferung innerhalb von 1-3 Werktagen"
}
}
} ]
}
"#).unwrap(), object!{
"l10n" => array![ object!{
"product" => object!{
"inStock" => object!{
"DE" => "Lieferung innerhalb von 1-3 Werktagen"
}
}
} ]
});
}
#[test]
fn parse_and_index_from_object() {
let data = parse("{ \"pi\": 3.14 }").unwrap();
let ref pi = data["pi"];
assert_eq!(pi, 3.14);
}
#[test]
fn parse_and_index_mut_from_object() {
let mut data = parse(r#"
{
"foo": 100
}
"#).unwrap();
assert_eq!(data["foo"], 100);
data["foo"] = 200.into();
assert_eq!(data["foo"], 200);
}
#[test]
fn parse_and_index_mut_from_null() {
let mut data = parse("null").unwrap();
assert!(data["foo"]["bar"].is_null());
// test that data didn't coerece to object
assert!(data.is_null());
data["foo"]["bar"] = 100.into();
assert!(data.is_object());
assert_eq!(data["foo"]["bar"], 100);
assert_eq!(data.dump(), r#"{"foo":{"bar":100}}"#);
}
#[test]
fn parse_and_index_from_array() {
let data = parse(r#"[100, 200, false, null, "foo"]"#).unwrap();
assert_eq!(data[0], Number::from(100));
assert_eq!(data[1], 200);
assert_eq!(data[2], false);
assert_eq!(data[3], Null);
assert_eq!(data[4], "foo");
assert_eq!(data[5], Null);
}
#[test]
fn parse_and_index_mut_from_array() {
let mut data = parse(r#"[100, 200, false, null, "foo"]"#).unwrap();
assert!(data[3].is_null());
assert!(data[5].is_null());
data[3] = "modified".into();
data[5] = "implicid push".into();
assert_eq!(data[3], "modified");
assert_eq!(data[5], "implicid push");
}
#[test]
fn parse_escaped_characters() {
let data = parse(r#"
"\r\n\t\b\f\\\/\""
"#).unwrap();
assert!(data.is_string());
assert_eq!(data, "\r\n\t\u{8}\u{c}\\/\"");
}
#[test]
fn parse_escaped_unicode() {
let data = parse(r#"
"\u2764\ufe0f"
"#).unwrap();
assert_eq!(data, "❤️");
}
#[test]
fn parse_escaped_unicode_surrogate() {
let data = parse(r#"
"\uD834\uDD1E"
"#).unwrap();
assert_eq!(data, "𝄞");
}
#[test]
fn parse_escaped_unicode_surrogate_fail() {
let err = parse(r#"
"\uD834 \uDD1E"
"#);
assert!(err.is_err());
}
#[test]
fn parse_deeply_nested_arrays_and_objects() {
let depth = 256;
let mut text = String::new();
for _ in 0..depth {
text.push_str("[{\"a\":");
}
text.push_str("null");
for _ in 0..depth {
text.push_str("}]");
}
parse(&text).unwrap();
assert!(true);
}
#[test]
fn parse_error_after_depth_limit() {
let depth = 5000;
let mut text = String::new();
for _ in 0..depth {
text.push_str("[{\"a\":");
}
text.push_str("null");
for _ in 0..depth {
text.push_str("}]");
}
assert_eq!(parse(&text), Err(json::Error::ExceededDepthLimit));
}
#[test]
fn does_not_panic_on_single_unicode_char() {
let bytes = vec![0xC3, 0xA5];
let string = String::from_utf8(bytes).unwrap();
assert!(parse(&string).is_err());
}
#[test]
fn does_not_panic_on_single_zero() {
let source = "0";
parse(source).unwrap();
}
#[test]
fn does_not_panic_on_huge_numbers() {
let mut string = String::from("8");
for _ in 1..32787 {
string.push('0');
}
let _ = json::parse(&string);
}