use serde_json::json;
use value_ext::{AsType, JsonValueExt};
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
#[test]
fn test_value_insert_ok() -> Result<()> {
let mut value = json!({"tokens": 3});
let fx_node_value = "hello";
value.x_insert("/happy/word", fx_node_value)?;
let actual_value: String = value.x_get("/happy/word")?;
assert_eq!(actual_value.as_str(), fx_node_value);
Ok(())
}
#[test]
fn test_value_walk_ok() -> Result<()> {
let mut root_value = json!(
{
"tokens": 3,
"schema": {
"type": "object",
"additionalProperties": false,
"properties": {
"all_models": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"maker": { "type": "string" },
"model_name": { "type": "string" }
},
"required": ["maker", "model_name"]
}
}
},
"required": ["all_models"]
}
});
root_value.x_walk(|parent_map, property_name| {
if property_name == "type" {
let val = parent_map.get(property_name).and_then(|v| v.as_str());
if let Some("object") = val {
parent_map.remove("additionalProperties");
return false; }
}
true
});
let mut marker_count = 0;
root_value.x_walk(|_parent_map, property_name| {
if property_name == "additionalProperties" {
marker_count += 1;
}
true
});
assert_eq!(1, marker_count);
Ok(())
}
#[test]
fn test_as_type_for_vec() -> Result<()> {
let json_array = json!([ {"a": 1}, {"b": 2} ]);
let vec_ref: &Vec<serde_json::Value> = <&Vec<serde_json::Value>>::from_value(&json_array)?;
assert_eq!(vec_ref.len(), 2);
let first_obj = &vec_ref[0];
let a_val = first_obj
.get("a")
.and_then(|v| v.as_i64())
.ok_or("Missing 'a' in first element")?;
assert_eq!(a_val, 1);
Ok(())
}
#[test]
fn test_as_type_for_vec_str() -> Result<()> {
let json_array = json!(["hello", "world"]);
let vec_str: Vec<&str> = <Vec<&str>>::from_value(&json_array)?;
assert_eq!(vec_str, vec!["hello", "world"]);
Ok(())
}
#[test]
fn test_x_remove_direct() -> Result<()> {
let mut value = json!({"key": "direct_value", "other": 42});
let removed: String = value.x_remove("key")?;
assert_eq!(removed, "direct_value");
let obj = value.as_object().ok_or("Expected object after removal")?;
assert!(!obj.contains_key("key"));
let other: i64 = value.x_get("other")?;
assert_eq!(other, 42);
Ok(())
}
#[test]
fn test_x_remove_nested() -> Result<()> {
let mut value = json!({
"a": {
"b": {
"c": "nested_value",
"d": "keep_this"
},
"e": "direct_in_a"
},
"f": "outside"
});
let removed: String = value.x_remove("/a/b/c")?;
assert_eq!(removed, "nested_value");
let d: String = value.x_get("/a/b/d")?;
assert_eq!(d, "keep_this");
let b = value.pointer("/a/b").ok_or("Expected pointer /a/b not found")?;
let b_obj = b.as_object().ok_or("Expected object at /a/b")?;
assert!(!b_obj.contains_key("c"));
let direct_in_a: String = value.x_get("/a/e")?;
assert_eq!(direct_in_a, "direct_in_a");
let outside: String = value.x_get("f")?;
assert_eq!(outside, "outside");
Ok(())
}
#[test]
fn test_x_merge_ok() -> Result<()> {
let mut value = json!({"a": 1, "b": 2});
let other = json!({"b": 3, "c": 4});
value.x_merge(other)?;
assert_eq!(value["a"], 1);
assert_eq!(value["b"], 3);
assert_eq!(value["c"], 4);
value.x_merge(serde_json::Value::Null)?;
assert_eq!(value["b"], 3);
Ok(())
}
#[test]
fn test_x_get_object_ok() -> Result<()> {
let value = json!({"data": {"inner": "value"}});
let map = value.x_get_object("data")?;
assert_eq!(map.len(), 1);
assert_eq!(map.get("inner").and_then(|v| v.as_str()), Some("value"));
Ok(())
}
#[test]
fn test_x_get_object_not_object() -> Result<()> {
let value = json!({"key": "string_value"});
let res = value.x_get_object("key");
assert!(res.is_err());
match res.unwrap_err() {
value_ext::JsonValueExtError::PropertyValueNotOfType { name, not_of_type } => {
assert_eq!(name, "key");
assert_eq!(not_of_type, "Object");
}
_ => panic!("Expected PropertyValueNotOfType"),
}
Ok(())
}
#[test]
fn test_x_get_strs_ok() -> Result<()> {
let value = json!({"strings": ["hello", "world"]});
let strs: Vec<&str> = value.x_get_strs("strings")?;
assert_eq!(strs, vec!["hello", "world"]);
Ok(())
}
#[test]
fn test_x_get_i64s_ok() -> Result<()> {
let value = json!({"nums": [1, 2, 3]});
let nums: Vec<i64> = value.x_get_i64s("nums")?;
assert_eq!(nums, vec![1, 2, 3]);
Ok(())
}
#[test]
fn test_x_get_f64s_ok() -> Result<()> {
let value = json!({"nums": [1.1, 2.2]});
let nums: Vec<f64> = value.x_get_f64s("nums")?;
assert_eq!(nums, vec![1.1, 2.2]);
Ok(())
}
#[test]
fn test_x_get_bools_ok() -> Result<()> {
let value = json!({"bools": [true, false, true]});
let bools: Vec<bool> = value.x_get_bools("bools")?;
assert_eq!(bools, vec![true, false, true]);
Ok(())
}
#[test]
fn test_x_get_strs_pointer_ok() -> Result<()> {
let value = json!({"outer": {"inner": ["hello"]}});
let strs: Vec<&str> = value.x_get_strs("/outer/inner")?;
assert_eq!(strs, vec!["hello"]);
Ok(())
}