use forma_derive::{Deserialize, Serialize};
use forma_json::value::{from_value, to_value, Number};
use forma_json::{from_str, to_string, to_string_pretty, Value};
use std::collections::BTreeMap;
#[test]
fn test_parse_null() {
let v: Value = from_str("null").unwrap();
assert_eq!(v, Value::Null);
assert!(v.is_null());
}
#[test]
fn test_parse_bool() {
let v: Value = from_str("true").unwrap();
assert_eq!(v, Value::Bool(true));
assert_eq!(v.as_bool(), Some(true));
let v: Value = from_str("false").unwrap();
assert_eq!(v.as_bool(), Some(false));
}
#[test]
fn test_parse_number_positive() {
let v: Value = from_str("42").unwrap();
assert_eq!(v.as_u64(), Some(42));
assert_eq!(v.as_i64(), Some(42));
}
#[test]
fn test_parse_number_negative() {
let v: Value = from_str("-7").unwrap();
assert_eq!(v.as_i64(), Some(-7));
}
#[test]
fn test_parse_number_float() {
let v: Value = from_str("3.14").unwrap();
assert!((v.as_f64().unwrap() - 3.14).abs() < f64::EPSILON);
}
#[test]
fn test_parse_string() {
let v: Value = from_str("\"hello\"").unwrap();
assert_eq!(v.as_str(), Some("hello"));
}
#[test]
fn test_parse_array() {
let v: Value = from_str("[1, 2, 3]").unwrap();
assert!(v.is_array());
assert_eq!(v.as_array().unwrap().len(), 3);
assert_eq!(v[0].as_u64(), Some(1));
assert_eq!(v[1].as_u64(), Some(2));
assert_eq!(v[2].as_u64(), Some(3));
}
#[test]
fn test_parse_object() {
let v: Value = from_str("{\"name\":\"Alice\",\"age\":30}").unwrap();
assert!(v.is_object());
assert_eq!(v["name"].as_str(), Some("Alice"));
assert_eq!(v["age"].as_u64(), Some(30));
}
#[test]
fn test_parse_nested() {
let v: Value = from_str(r#"{"users":[{"name":"Alice"},{"name":"Bob"}]}"#).unwrap();
assert_eq!(v["users"][0]["name"].as_str(), Some("Alice"));
assert_eq!(v["users"][1]["name"].as_str(), Some("Bob"));
}
#[test]
fn test_serialize_null() {
assert_eq!(to_string(&Value::Null).unwrap(), "null");
}
#[test]
fn test_serialize_bool() {
assert_eq!(to_string(&Value::Bool(true)).unwrap(), "true");
}
#[test]
fn test_serialize_number() {
assert_eq!(
to_string(&Value::Number(Number::PosInt(42))).unwrap(),
"42"
);
assert_eq!(
to_string(&Value::Number(Number::NegInt(-7))).unwrap(),
"-7"
);
assert_eq!(
to_string(&Value::Number(Number::Float(3.14))).unwrap(),
"3.14"
);
}
#[test]
fn test_serialize_string() {
assert_eq!(
to_string(&Value::String("hello".into())).unwrap(),
"\"hello\""
);
}
#[test]
fn test_serialize_array() {
let v = Value::Array(vec![Value::from(1i64), Value::from(2i64), Value::from(3i64)]);
assert_eq!(to_string(&v).unwrap(), "[1,2,3]");
}
#[test]
fn test_serialize_object() {
let mut m = BTreeMap::new();
m.insert("a".to_string(), Value::from(1i64));
m.insert("b".to_string(), Value::from(2i64));
assert_eq!(to_string(&Value::Object(m)).unwrap(), "{\"a\":1,\"b\":2}");
}
#[test]
fn test_value_roundtrip() {
let input = r#"{"array":[1,2,3],"bool":true,"null":null,"number":42,"string":"hello"}"#;
let v: Value = from_str(input).unwrap();
let output = to_string(&v).unwrap();
assert_eq!(output, input);
}
#[test]
fn test_value_pretty() {
let mut m = BTreeMap::new();
m.insert("x".to_string(), Value::from(1i64));
m.insert("y".to_string(), Value::from(2i64));
let v = Value::Object(m);
let pretty = to_string_pretty(&v).unwrap();
assert_eq!(pretty, "{\n \"x\": 1,\n \"y\": 2\n}");
}
#[test]
fn test_from_bool() {
assert_eq!(Value::from(true), Value::Bool(true));
}
#[test]
fn test_from_i64() {
assert_eq!(Value::from(42i64), Value::Number(Number::PosInt(42)));
assert_eq!(Value::from(-1i64), Value::Number(Number::NegInt(-1)));
}
#[test]
fn test_from_u64() {
assert_eq!(Value::from(42u64), Value::Number(Number::PosInt(42)));
}
#[test]
fn test_from_f64() {
assert_eq!(Value::from(3.14f64), Value::Number(Number::Float(3.14)));
}
#[test]
fn test_from_string() {
assert_eq!(Value::from("hello"), Value::String("hello".into()));
}
#[test]
fn test_from_vec() {
let v: Value = vec![1i64, 2, 3].into();
assert!(v.is_array());
assert_eq!(v[0].as_i64(), Some(1));
}
#[test]
fn test_from_option() {
assert_eq!(Value::from(Some(42i64)), Value::Number(Number::PosInt(42)));
assert_eq!(Value::from(None::<i64>), Value::Null);
}
#[test]
fn test_index_missing_key() {
let v: Value = from_str("{}").unwrap();
assert!(v["missing"].is_null());
}
#[test]
fn test_index_out_of_bounds() {
let v: Value = from_str("[1]").unwrap();
assert!(v[99].is_null());
}
#[test]
fn test_index_wrong_type() {
let v = Value::from(42i64);
assert!(v["key"].is_null());
assert!(v[0].is_null());
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Point {
x: i32,
y: i32,
}
#[test]
fn test_to_value() {
let p = Point { x: 1, y: 2 };
let v = to_value(&p).unwrap();
assert_eq!(v["x"].as_i64(), Some(1));
assert_eq!(v["y"].as_i64(), Some(2));
}
#[test]
fn test_from_value() {
let mut m = BTreeMap::new();
m.insert("x".to_string(), Value::from(10i64));
m.insert("y".to_string(), Value::from(20i64));
let v = Value::Object(m);
let p: Point = from_value(v).unwrap();
assert_eq!(p, Point { x: 10, y: 20 });
}
#[test]
fn test_display() {
let v = Value::from("hello");
assert_eq!(format!("{v}"), "\"hello\"");
}