#![cfg(feature = "git")]
mod common;
use prollytree::git::versioned_store::GitVersionedKvStore;
use prollytree::validation;
#[test]
fn test_open_corrupted_config() {
let (_temp, dataset) = common::setup_repo_and_dataset();
{
let mut store = GitVersionedKvStore::<32>::init(&dataset).unwrap();
store.insert(b"key".to_vec(), b"val".to_vec()).unwrap();
store.commit("data").unwrap();
}
let config_path = dataset.join("prolly_config_tree_config");
if config_path.exists() {
std::fs::write(&config_path, b"garbage_data_not_valid_config").unwrap();
}
let result = GitVersionedKvStore::<32>::open(&dataset);
match result {
Ok(_store) => {
}
Err(e) => {
assert!(!format!("{e:?}").is_empty(), "error should have a message");
}
}
}
#[test]
fn test_open_missing_git_directory() {
let temp = tempfile::TempDir::new().unwrap();
let dataset = temp.path().join("dataset");
std::fs::create_dir_all(&dataset).unwrap();
let result = GitVersionedKvStore::<32>::open(&dataset);
assert!(result.is_err(), "open without .git should fail");
}
#[test]
fn test_checkout_nonexistent_branch() {
let (_temp, dataset) = common::setup_repo_and_dataset();
let mut store = GitVersionedKvStore::<32>::init(&dataset).unwrap();
store.insert(b"k".to_vec(), b"v".to_vec()).unwrap();
store.commit("init").unwrap();
let result = store.checkout("nonexistent_branch_xyz");
assert!(
result.is_err(),
"checkout of nonexistent branch should fail"
);
std::mem::forget(_temp);
}
#[test]
fn test_double_init_preserves_data() {
let (_temp, dataset) = common::setup_repo_and_dataset();
{
let mut store = GitVersionedKvStore::<32>::init(&dataset).unwrap();
store.insert(b"survive".to_vec(), b"yes".to_vec()).unwrap();
store.commit("first init").unwrap();
}
{
let store = GitVersionedKvStore::<32>::open(&dataset).unwrap();
assert_eq!(
store.get(b"survive"),
Some(b"yes".to_vec()),
"data from first init should survive open"
);
}
}
#[test]
fn test_init_in_nonexistent_parent() {
let result = GitVersionedKvStore::<32>::init("/tmp/prollytree_nonexistent_parent_9999/dataset");
assert!(
result.is_err(),
"init in nonexistent directory without git repo should fail"
);
}
#[test]
fn test_insert_empty_key_rejected() {
let (_temp, dataset) = common::setup_repo_and_dataset();
let mut store = GitVersionedKvStore::<32>::init(&dataset).unwrap();
let result = store.insert(b"".to_vec(), b"value".to_vec());
assert!(result.is_err(), "empty key should be rejected");
let err = format!("{}", result.unwrap_err());
assert!(
err.contains("empty"),
"error should mention empty key: {err}"
);
}
#[test]
fn test_insert_oversized_key_rejected() {
let (_temp, dataset) = common::setup_repo_and_dataset();
let mut store = GitVersionedKvStore::<32>::init(&dataset).unwrap();
let big_key = vec![0u8; validation::MAX_KEY_SIZE + 1];
let result = store.insert(big_key, b"value".to_vec());
assert!(result.is_err(), "oversized key should be rejected");
let err = format!("{}", result.unwrap_err());
assert!(
err.contains("exceeds"),
"error should mention size limit: {err}"
);
}
#[test]
fn test_insert_oversized_value_rejected() {
let (_temp, dataset) = common::setup_repo_and_dataset();
let mut store = GitVersionedKvStore::<32>::init(&dataset).unwrap();
let big_value = vec![0u8; validation::MAX_VALUE_SIZE + 1];
let result = store.insert(b"key".to_vec(), big_value);
assert!(result.is_err(), "oversized value should be rejected");
}
#[test]
fn test_update_empty_key_rejected() {
let (_temp, dataset) = common::setup_repo_and_dataset();
let mut store = GitVersionedKvStore::<32>::init(&dataset).unwrap();
let result = store.update(b"".to_vec(), b"value".to_vec());
assert!(result.is_err(), "empty key update should be rejected");
}
#[test]
fn test_valid_key_value_accepted() {
let (_temp, dataset) = common::setup_repo_and_dataset();
let mut store = GitVersionedKvStore::<32>::init(&dataset).unwrap();
store
.insert(b"normal_key".to_vec(), b"normal_value".to_vec())
.expect("valid kv should be accepted");
let max_key = vec![b'k'; validation::MAX_KEY_SIZE];
store
.insert(max_key, b"val".to_vec())
.expect("max-size key should be accepted");
}