use tst::TST; use std::env::temp_dir; use std::fs; use std::time::SystemTime; fn get_test_db_path() -> String { let timestamp = SystemTime::now() .duration_since(SystemTime::UNIX_EPOCH) .unwrap() .as_nanos(); let path = temp_dir().join(format!("tst_test_{}", timestamp)); // If the path exists, remove it first if path.exists() { let _ = fs::remove_dir_all(&path); } // Create the directory fs::create_dir_all(&path).unwrap(); path.to_string_lossy().to_string() } fn cleanup_test_db(path: &str) { // Make sure to clean up properly let _ = fs::remove_dir_all(path); } #[test] fn test_create_tst() { let path = get_test_db_path(); let result = TST::new(&path, true); match &result { Ok(_) => (), Err(e) => println!("Error creating TST: {:?}", e), } assert!(result.is_ok()); if let Ok(mut tst) = result { // Make sure we can perform a basic operation let set_result = tst.set("test_key", b"test_value".to_vec()); assert!(set_result.is_ok()); } cleanup_test_db(&path); } #[test] fn test_set_and_get() { let path = get_test_db_path(); // Create a new TST with reset=true to ensure a clean state let result = TST::new(&path, true); assert!(result.is_ok()); let mut tree = result.unwrap(); // Test setting and getting a key let key = "test_key"; let value = b"test_value".to_vec(); let set_result = tree.set(key, value.clone()); assert!(set_result.is_ok()); let get_result = tree.get(key); assert!(get_result.is_ok()); assert_eq!(get_result.unwrap(), value); // Make sure to clean up properly cleanup_test_db(&path); } #[test] fn test_get_nonexistent_key() { let path = get_test_db_path(); let mut tree = TST::new(&path, true).unwrap(); // Test getting a key that doesn't exist let get_result = tree.get("nonexistent_key"); assert!(get_result.is_err()); cleanup_test_db(&path); } #[test] fn test_delete() { let path = get_test_db_path(); // Create a new TST with reset=true to ensure a clean state let result = TST::new(&path, true); assert!(result.is_ok()); let mut tree = result.unwrap(); // Set a key let key = "delete_test"; let value = b"to_be_deleted".to_vec(); let set_result = tree.set(key, value); assert!(set_result.is_ok()); // Verify it exists let get_result = tree.get(key); assert!(get_result.is_ok()); // Delete it let delete_result = tree.delete(key); assert!(delete_result.is_ok()); // Verify it's gone let get_after_delete = tree.get(key); assert!(get_after_delete.is_err()); // Make sure to clean up properly cleanup_test_db(&path); } #[test] fn test_multiple_keys() { let path = get_test_db_path(); // Create a new TST with reset=true to ensure a clean state let result = TST::new(&path, true); assert!(result.is_ok()); let mut tree = result.unwrap(); // Insert multiple keys - use fewer keys to avoid filling the lookup table let keys = ["apple", "banana", "cherry"]; for (i, key) in keys.iter().enumerate() { let value = format!("value_{}", i).into_bytes(); let set_result = tree.set(key, value); // Print error if set fails if set_result.is_err() { println!("Error setting key '{}': {:?}", key, set_result); } assert!(set_result.is_ok()); } // Verify all keys exist for (i, key) in keys.iter().enumerate() { let expected_value = format!("value_{}", i).into_bytes(); let get_result = tree.get(key); assert!(get_result.is_ok()); assert_eq!(get_result.unwrap(), expected_value); } // Make sure to clean up properly cleanup_test_db(&path); } #[test] fn test_list_prefix() { let path = get_test_db_path(); // Create a new TST with reset=true to ensure a clean state let result = TST::new(&path, true); assert!(result.is_ok()); let mut tree = result.unwrap(); // Insert keys with common prefixes - use fewer keys to avoid filling the lookup table let keys = [ "apple", "application", "append", "banana", "bandana" ]; for key in &keys { let set_result = tree.set(key, key.as_bytes().to_vec()); assert!(set_result.is_ok()); } // Test prefix "app" let list_result = tree.list("app"); assert!(list_result.is_ok()); let app_keys = list_result.unwrap(); // Print the keys for debugging println!("Keys with prefix 'app':"); for key in &app_keys { println!(" {}", key); } // Check that each key is present assert!(app_keys.contains(&"apple".to_string())); assert!(app_keys.contains(&"application".to_string())); assert!(app_keys.contains(&"append".to_string())); // Test prefix "ban" let list_result = tree.list("ban"); assert!(list_result.is_ok()); let ban_keys = list_result.unwrap(); assert!(ban_keys.contains(&"banana".to_string())); assert!(ban_keys.contains(&"bandana".to_string())); // Test non-existent prefix let list_result = tree.list("z"); assert!(list_result.is_ok()); let z_keys = list_result.unwrap(); assert_eq!(z_keys.len(), 0); // Make sure to clean up properly cleanup_test_db(&path); } #[test] fn test_getall_prefix() { let path = get_test_db_path(); // Create a new TST with reset=true to ensure a clean state let result = TST::new(&path, true); assert!(result.is_ok()); let mut tree = result.unwrap(); // Insert keys with common prefixes - use fewer keys to avoid filling the lookup table let keys = [ "apple", "application", "append" ]; for key in &keys { let set_result = tree.set(key, key.as_bytes().to_vec()); assert!(set_result.is_ok()); } // Test getall with prefix "app" let getall_result = tree.getall("app"); assert!(getall_result.is_ok()); let app_values = getall_result.unwrap(); // Convert values to strings for easier comparison let app_value_strings: Vec = app_values .iter() .map(|v| String::from_utf8_lossy(v).to_string()) .collect(); // Print the values for debugging println!("Values with prefix 'app':"); for value in &app_value_strings { println!(" {}", value); } // Check that each value is present assert!(app_value_strings.contains(&"apple".to_string())); assert!(app_value_strings.contains(&"application".to_string())); assert!(app_value_strings.contains(&"append".to_string())); // Make sure to clean up properly cleanup_test_db(&path); } #[test] fn test_empty_prefix() { let path = get_test_db_path(); // Create a new TST with reset=true to ensure a clean state let result = TST::new(&path, true); assert!(result.is_ok()); let mut tree = result.unwrap(); // Insert some keys let keys = ["apple", "banana", "cherry"]; for key in &keys { let set_result = tree.set(key, key.as_bytes().to_vec()); assert!(set_result.is_ok()); } // Test list with empty prefix (should return all keys) let list_result = tree.list(""); assert!(list_result.is_ok()); let all_keys = list_result.unwrap(); // Print the keys for debugging println!("Keys with empty prefix:"); for key in &all_keys { println!(" {}", key); } // Check that each key is present for key in &keys { assert!(all_keys.contains(&key.to_string())); } // Make sure to clean up properly cleanup_test_db(&path); }