use std::path::Path;
fn setup_temp_db() -> (tempfile::TempDir, String) {
let dir = tempfile::tempdir().expect("failed to create temp dir");
let path = dir.path().to_string_lossy().to_string();
vantadb::cli_handlers::cmd_put(&path, "_init", "_init", "", None, false)
.expect("init put failed");
(dir, path)
}
fn seed_record(db_path: &str, namespace: &str, key: &str, payload: &str) {
vantadb::cli_handlers::cmd_put(db_path, namespace, key, payload, None, false)
.expect("seed put failed");
}
fn seed_embedded(db_path: &str, namespace: &str, key: &str, payload: &str) {
let config = vantadb::config::VantaConfig {
storage_path: db_path.to_string(),
read_only: false,
..Default::default()
};
let db = vantadb::VantaEmbedded::open_with_config(config).expect("seed embedded open failed");
db.put(vantadb::sdk::VantaMemoryInput {
namespace: namespace.to_string(),
key: key.to_string(),
payload: payload.to_string(),
metadata: vantadb::sdk::VantaMemoryMetadata::new(),
vector: None,
ttl_ms: None,
})
.expect("seed embedded put failed");
}
#[test]
fn test_put_and_get() {
let (_dir, path) = setup_temp_db();
seed_record(&path, "test_ns", "key1", "hello world");
let engine = vantadb::cli_handlers::open_database(&path, true).unwrap();
let node_id = vantadb::cli_handlers::memory_node_id("test_ns", "key1");
let node = engine.get(node_id).unwrap().expect("record not found");
let payload = node
.relational
.get(vantadb::cli_handlers::FIELD_PAYLOAD)
.and_then(|v| match v {
vantadb::node::FieldValue::String(s) => Some(s.clone()),
_ => None,
})
.expect("payload not found");
assert_eq!(payload, "hello world");
}
#[test]
fn test_get_nonexistent() {
let (_dir, path) = setup_temp_db();
let result = vantadb::cli_handlers::cmd_get(&path, "ns", "missing", false);
assert!(result.is_err(), "expected error for missing record");
}
#[test]
fn test_put_with_vector() {
let (_dir, path) = setup_temp_db();
vantadb::cli_handlers::cmd_put(&path, "vec_ns", "v1", "data", Some("1.0,2.0,3.0"), false)
.expect("put with vector failed");
let engine = vantadb::cli_handlers::open_database(&path, true).unwrap();
let node_id = vantadb::cli_handlers::memory_node_id("vec_ns", "v1");
let node = engine.get(node_id).unwrap().expect("record not found");
assert!(node.flags.is_set(vantadb::node::NodeFlags::HAS_VECTOR));
}
#[test]
fn test_put_invalid_vector() {
let (_dir, path) = setup_temp_db();
let result = vantadb::cli_handlers::cmd_put(&path, "ns", "k", "data", Some("abc"), false);
assert!(result.is_err(), "expected error for invalid vector");
}
#[test]
fn test_list_empty_namespace() {
let (_dir, path) = setup_temp_db();
let result = vantadb::cli_handlers::cmd_list(&path, "empty_ns", 10, false);
if let Err(e) = &result {
eprintln!("ERROR: {:?}", e);
}
assert!(
result.is_ok(),
"list on empty namespace should succeed: {:?}",
result
);
}
#[test]
fn test_list_with_records() {
let (_dir, path) = setup_temp_db();
seed_record(&path, "ns1", "a", "payload a");
seed_record(&path, "ns1", "b", "payload b");
seed_record(&path, "ns1", "c", "payload c");
let result = vantadb::cli_handlers::cmd_list(&path, "ns1", 2, false);
assert!(result.is_ok());
}
#[test]
fn test_list_limit() {
let (_dir, path) = setup_temp_db();
for i in 0..10 {
seed_record(&path, "lim_ns", &format!("k{}", i), "data");
}
let engine = vantadb::cli_handlers::open_database(&path, true).unwrap();
let nodes = engine.scan_nodes().unwrap();
let count = nodes
.iter()
.filter(|n| {
n.relational
.get(vantadb::cli_handlers::FIELD_NAMESPACE)
.map(|v| matches!(v, vantadb::node::FieldValue::String(s) if s == "lim_ns"))
.unwrap_or(false)
})
.count();
assert_eq!(count, 10, "expected 10 records in namespace");
}
#[test]
fn test_delete_record() {
let (_dir, path) = setup_temp_db();
seed_record(&path, "del_ns", "del_key", "to delete");
let result = vantadb::cli_handlers::cmd_delete(&path, "del_ns", "del_key", false);
assert!(result.is_ok());
let node_id = vantadb::cli_handlers::memory_node_id("del_ns", "del_key");
let engine = vantadb::cli_handlers::open_database(&path, true).unwrap();
assert!(engine.get(node_id).unwrap().is_none());
}
#[test]
fn test_delete_nonexistent() {
let (_dir, path) = setup_temp_db();
let result = vantadb::cli_handlers::cmd_delete(&path, "ns", "missing", false);
assert!(result.is_ok());
}
#[test]
fn test_delete_verbose() {
let (_dir, path) = setup_temp_db();
seed_record(&path, "v_ns", "v_key", "verbose delete");
let result = vantadb::cli_handlers::cmd_delete(&path, "v_ns", "v_key", true);
assert!(result.is_ok());
}
#[test]
fn test_search_no_results() {
let (_dir, path) = setup_temp_db();
seed_embedded(&path, "srch_ns", "k1", "hello world");
let result = vantadb::cli_handlers::cmd_search(&path, "srch_ns", "zzz_nonexistent", 10);
if let Err(e) = &result {
eprintln!("ERROR: {:?}", e);
}
assert!(
result.is_ok(),
"search with no match should succeed: {:?}",
result
);
}
#[test]
fn test_search_with_results() {
let (_dir, path) = setup_temp_db();
seed_embedded(&path, "search_ns", "r1", "apple banana");
seed_embedded(&path, "search_ns", "r2", "banana cherry");
let result = vantadb::cli_handlers::cmd_search(&path, "search_ns", "banana", 10);
if let Err(e) = &result {
eprintln!("ERROR: {:?}", e);
}
assert!(result.is_ok(), "search should find results: {:?}", result);
}
#[test]
fn test_namespace_list_empty() {
let (_dir, path) = setup_temp_db();
let result = vantadb::cli_handlers::cmd_namespace_list(&path);
if let Err(e) = &result {
eprintln!("ERROR: {:?}", e);
}
assert!(result.is_ok(), "namespace list on empty db: {:?}", result);
}
#[test]
fn test_namespace_list_with_data() {
let (_dir, path) = setup_temp_db();
seed_record(&path, "ns_a", "k1", "data");
seed_record(&path, "ns_b", "k2", "data");
let db = vantadb::cli_handlers::open_embedded(&path, true).unwrap();
let namespaces = db.list_namespaces().unwrap();
assert!(namespaces.contains(&"ns_a".to_string()));
assert!(namespaces.contains(&"ns_b".to_string()));
}
#[test]
fn test_namespace_info() {
let (_dir, path) = setup_temp_db();
seed_record(&path, "info_ns", "k1", "hello world");
let result = vantadb::cli_handlers::cmd_namespace_info(&path, "info_ns");
assert!(result.is_ok());
}
#[test]
fn test_namespace_info_empty() {
let (_dir, path) = setup_temp_db();
let result = vantadb::cli_handlers::cmd_namespace_info(&path, "empty_ns");
if let Err(e) = &result {
eprintln!("ERROR: {:?}", e);
}
assert!(result.is_ok(), "namespace info on empty ns: {:?}", result);
}
#[test]
fn test_status_no_db() {
let path = "./nonexistent_test_dir_should_not_exist";
if Path::new(path).exists() {
eprintln!("WARNING: test directory exists, using temp dir instead");
let (_dir, tmp_path) = setup_temp_db();
let result = vantadb::cli_handlers::cmd_status(&tmp_path, false);
assert!(result.is_ok());
return;
}
let result = vantadb::cli_handlers::cmd_status(path, false);
assert!(result.is_ok());
}
#[test]
fn test_status_with_db() {
let (_dir, path) = setup_temp_db();
seed_record(&path, "st_ns", "st_k", "status test");
let result = vantadb::cli_handlers::cmd_status(&path, false);
assert!(result.is_ok());
}
#[test]
fn test_status_verbose() {
let (_dir, path) = setup_temp_db();
seed_record(&path, "st_v", "k", "verbose status");
let result = vantadb::cli_handlers::cmd_status(&path, true);
assert!(result.is_ok());
}
#[test]
fn test_memory_node_id_deterministic() {
let id1 = vantadb::cli_handlers::memory_node_id("ns", "key");
let id2 = vantadb::cli_handlers::memory_node_id("ns", "key");
assert_eq!(id1, id2, "node ID must be deterministic");
}
#[test]
fn test_memory_node_id_different_keys() {
let id1 = vantadb::cli_handlers::memory_node_id("ns", "a");
let id2 = vantadb::cli_handlers::memory_node_id("ns", "b");
assert_ne!(id1, id2, "different keys must produce different IDs");
}
#[test]
fn test_memory_node_id_different_namespaces() {
let id1 = vantadb::cli_handlers::memory_node_id("ns1", "key");
let id2 = vantadb::cli_handlers::memory_node_id("ns2", "key");
assert_ne!(id1, id2, "different namespaces must produce different IDs");
}
#[test]
fn test_cmd_get_missing_db() {
let result = vantadb::cli_handlers::cmd_get("./ghost_dir", "ns", "k", false);
assert!(result.is_ok(), "missing db should warn, not error");
}
#[test]
fn test_cmd_list_missing_db() {
let result = vantadb::cli_handlers::cmd_list("./ghost_dir", "ns", 10, false);
assert!(result.is_ok(), "missing db should warn, not error");
}
#[test]
fn test_cmd_delete_missing_db() {
let result = vantadb::cli_handlers::cmd_delete("./ghost_dir", "ns", "k", false);
assert!(result.is_ok(), "missing db should warn, not error");
}
#[test]
fn test_cmd_search_missing_db() {
let result = vantadb::cli_handlers::cmd_search("./ghost_dir", "ns", "q", 10);
assert!(result.is_ok(), "missing db should warn, not error");
}
#[test]
fn test_cmd_namespace_list_missing_db() {
let result = vantadb::cli_handlers::cmd_namespace_list("./ghost_dir");
assert!(result.is_ok(), "missing db should warn, not error");
}
#[test]
fn test_cmd_namespace_info_missing_db() {
let result = vantadb::cli_handlers::cmd_namespace_info("./ghost_dir", "ns");
assert!(result.is_ok(), "missing db should warn, not error");
}
#[test]
fn test_cmd_rebuild_index_empty() {
let (_dir, path) = setup_temp_db();
let result = vantadb::cli_handlers::cmd_rebuild_index(&path, false);
assert!(result.is_ok());
}
#[test]
fn test_cmd_export_and_import() {
let (_dir, path) = setup_temp_db();
seed_record(&path, "ex_ns", "k1", "export me");
let export_path = format!("{}/export.json", &path);
let result = vantadb::cli_handlers::cmd_export(&path, Some("ex_ns"), &export_path);
assert!(result.is_ok(), "export failed");
assert!(Path::new(&export_path).exists(), "export file missing");
let (_dir2, path2) = setup_temp_db();
let result = vantadb::cli_handlers::cmd_import(&path2, &export_path, false);
assert!(result.is_ok(), "import failed");
let node_id = vantadb::cli_handlers::memory_node_id("ex_ns", "k1");
let engine = vantadb::cli_handlers::open_database(&path2, true).unwrap();
assert!(
engine.get(node_id).unwrap().is_some(),
"imported record not found"
);
}
#[test]
fn test_cmd_query_empty_db() {
let (_dir, path) = setup_temp_db();
let result = vantadb::cli_handlers::cmd_query(&path, "FROM Persona", 10, false);
if let Err(e) = &result {
eprintln!("ERROR: {:?}", e);
}
assert!(
result.is_ok(),
"query on empty db should succeed: {:?}",
result
);
}
#[test]
fn test_put_verbose() {
let (_dir, path) = setup_temp_db();
let result = vantadb::cli_handlers::cmd_put(&path, "v_ns", "v_key", "verbose", None, true);
assert!(result.is_ok());
}
#[test]
fn test_list_verbose() {
let (_dir, path) = setup_temp_db();
seed_record(&path, "lv_ns", "k", "data");
let result = vantadb::cli_handlers::cmd_list(&path, "lv_ns", 10, true);
assert!(result.is_ok());
}