use eidetica::crdt::doc::Value;
use super::helpers::*;
#[test]
fn test_value_editor_set_and_get_string_at_root() -> eidetica::Result<()> {
let (_, _, _op, dict) = setup_complete_test_env("editor_test_store")?;
test_editor_basic_set_get(&dict, "user", Value::Text("alice".to_string()))?;
assert_eq!(dict.get_string("user")?, "alice");
Ok(())
}
#[test]
fn test_value_editor_set_and_get_nested_string() -> eidetica::Result<()> {
let (_, _, _op, dict) = setup_complete_test_env("editor_test_store")?;
test_nested_editor_operations(
&dict,
&["user", "profile", "name"],
Value::Text("bob".to_string()),
)?;
let user_editor = dict.get_value_mut("user");
let profile_editor = user_editor.get_value_mut("profile");
let retrieved_name = profile_editor.get_value("name")?;
assert_text_value(&retrieved_name, "bob");
let profile_map_value = user_editor.get_value("profile")?;
assert_map_contains(&profile_map_value, &["name"]);
let user_data = dict.get("user")?;
match user_data {
Value::Doc(user_map) => match user_map.get("profile") {
Some(Value::Doc(profile_map)) => {
assert_text_value(profile_map.get("name").unwrap(), "bob");
}
_ => panic!("Expected user.profile (nested) to be a map"),
},
_ => panic!("Expected user to be a map"),
}
Ok(())
}
#[test]
fn test_value_editor_overwrite_non_map_with_map() -> eidetica::Result<()> {
let (_, _, _op, dict) = setup_complete_test_env("editor_test_store")?;
dict.set("user", "string_value")?;
test_nested_editor_operations(
&dict,
&["user", "profile", "name"],
Value::Text("charlie".to_string()),
)?;
let user_editor = dict.get_value_mut("user");
let profile_editor = user_editor.get_value_mut("profile");
let retrieved_name = profile_editor.get_value("name")?;
assert_text_value(&retrieved_name, "charlie");
let user_data = dict.get("user")?;
match user_data {
Value::Doc(user_map) => match user_map.get("profile") {
Some(Value::Doc(profile_map)) => {
assert_text_value(profile_map.get("name").unwrap(), "charlie");
}
_ => panic!("Expected user.profile to be a map after overwrite"),
},
_ => panic!("Expected user to be a map after overwrite"),
}
Ok(())
}
#[test]
fn test_value_editor_get_non_existent_path() -> eidetica::Result<()> {
let (_, _, _op, dict) = setup_complete_test_env("editor_test_store")?;
let editor = dict.get_value_mut("nonexistent");
assert_not_found_error(editor.get());
let nested_editor = editor.get_value_mut("child");
assert_not_found_error(nested_editor.get());
assert_not_found_error(nested_editor.get_value("grandchild"));
Ok(())
}
#[test]
fn test_value_editor_set_deeply_nested_creates_path() -> eidetica::Result<()> {
let (_, _, _op, dict) = setup_complete_test_env("editor_test_store")?;
test_nested_editor_operations(
&dict,
&["a", "b", "c"],
Value::Text("deep_value".to_string()),
)?;
let a_val = dict.get("a")?;
match a_val {
Value::Doc(a_map) => match a_map.get("b") {
Some(Value::Doc(b_map)) => {
assert_text_value(b_map.get("c").unwrap(), "deep_value");
}
_ => panic!("Expected a.b to be a map"),
},
_ => panic!("Expected a to be a map"),
}
Ok(())
}
#[test]
fn test_value_editor_set_string_on_editor_path() -> eidetica::Result<()> {
let (_, _, _op, dict) = setup_complete_test_env("editor_test_store")?;
let user_editor = dict.get_value_mut("user");
let name_within_user_editor = user_editor.get_value_mut("name");
name_within_user_editor.set(Value::Text("dave".to_string()))?;
let user_data = dict.get("user")?;
assert_map_contains(&user_data, &["name"]);
match user_data {
Value::Doc(user_map) => {
assert_text_value(user_map.get("name").unwrap(), "dave");
}
_ => panic!("Expected user to be a map with name field"),
}
let profile_editor = user_editor.get_value_mut("profile");
let email_within_profile_editor = profile_editor.get_value_mut("email");
email_within_profile_editor.set(Value::Text("dave@example.com".to_string()))?;
let user_data_updated = dict.get("user")?;
match user_data_updated {
Value::Doc(user_map_updated) => {
match user_map_updated.get("profile") {
Some(Value::Doc(profile_map_updated)) => {
assert_text_value(
profile_map_updated.get("email").unwrap(),
"dave@example.com",
);
}
_ => panic!("Expected user.profile to be a map with email field"),
}
assert_text_value(user_map_updated.get("name").unwrap(), "dave");
}
_ => panic!("Expected user to be a map after profile update"),
}
Ok(())
}
#[test]
fn test_value_editor_root_operations() -> eidetica::Result<()> {
let (_db, tree, op, dict) = setup_complete_test_env("editor_test_store")?;
dict.set("key1", "value1")?;
dict.set("key2", "value2")?;
let root_editor = dict.get_root_mut();
match root_editor.get()? {
Value::Doc(map) => {
let entries = map.as_hashmap();
assert!(entries.contains_key("key1"));
assert!(entries.contains_key("key2"));
}
_ => panic!("Expected root editor to get a map"),
}
assert_text_value(&root_editor.get_value("key1")?, "value1");
let mut nested = eidetica::crdt::Doc::new();
nested.set_string("nested_key", "nested_value");
root_editor.get_value_mut("nested").set(nested.into())?;
assert_map_contains(&root_editor.get_value("nested")?, &["nested_key"]);
root_editor.delete_child("key1")?;
assert_not_found_error(root_editor.get_value("key1"));
op.commit()?;
let viewer_op = tree.new_transaction()?;
let viewer_dict = setup_dict_subtree(&viewer_op, "editor_test_store")?;
assert_not_found_error(viewer_dict.get("key1"));
assert_eq!(viewer_dict.get_string("key2")?, "value2");
Ok(())
}
#[test]
fn test_value_editor_delete_methods() -> eidetica::Result<()> {
let (_db, tree, op, dict) = setup_complete_test_env("editor_test_store")?;
let mut user_profile = eidetica::crdt::Doc::new();
user_profile.set_string("name", "Alice");
user_profile.set_string("email", "alice@example.com");
let mut user_data = eidetica::crdt::Doc::new();
user_data.set("profile", user_profile);
user_data.set_string("role", "admin");
dict.set_value("user", user_data)?;
let user_editor = dict.get_value_mut("user");
user_editor.delete_child("role")?;
assert_not_found_error(user_editor.get_value("role"));
assert_map_contains(&user_editor.get_value("profile")?, &["name", "email"]);
let profile_editor = user_editor.get_value_mut("profile");
profile_editor.delete_self()?;
assert_not_found_error(user_editor.get_value("profile"));
match dict.get("user")? {
Value::Doc(_) => (),
other => panic!("Expected user map to still exist, got {other:?}"),
}
op.commit()?;
let viewer_op = tree.new_transaction()?;
let viewer_dict = setup_dict_subtree(&viewer_op, "editor_test_store")?;
match viewer_dict.get("user")? {
Value::Doc(map) => {
let _entries = map.as_hashmap();
assert_path_deleted(&map, &["role"]);
assert_path_deleted(&map, &["profile"]);
}
_ => panic!("Expected user to be a map after commit"),
}
Ok(())
}
#[test]
fn test_value_editor_set_non_map_to_root() -> eidetica::Result<()> {
let (_, _, _op, dict) = setup_complete_test_env("editor_test_store")?;
let root_editor = dict.get_root_mut();
assert_type_error(root_editor.set(Value::Text("test string".to_string())));
let mut map = eidetica::crdt::Doc::new();
map.set_string("key", "value");
assert!(root_editor.set(map.into()).is_ok());
Ok(())
}