use bytes::Bytes;
use surrealmx::{Database, Error};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::*;
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn put_succeeds_for_new_key() {
let db = Database::new();
let mut tx = db.transaction(true);
let result = tx.put("new_key", "value");
assert!(result.is_ok(), "put should succeed for new key");
assert_eq!(tx.get("new_key").unwrap(), Some(Bytes::from("value")));
tx.commit().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn put_fails_for_existing_key() {
let db = Database::new();
let mut tx = db.transaction(true);
tx.set("existing", "original").unwrap();
tx.commit().unwrap();
let mut tx = db.transaction(true);
let result = tx.put("existing", "new_value");
assert!(matches!(result, Err(Error::KeyAlreadyExists)), "put should fail for existing key");
assert_eq!(tx.get("existing").unwrap(), Some(Bytes::from("original")));
tx.cancel().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn put_fails_for_key_set_in_same_transaction() {
let db = Database::new();
let mut tx = db.transaction(true);
tx.set("key", "first").unwrap();
let result = tx.put("key", "second");
assert!(
matches!(result, Err(Error::KeyAlreadyExists)),
"put should fail for key already in writeset"
);
tx.cancel().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn put_succeeds_after_delete_in_same_transaction() {
let db = Database::new();
let mut tx = db.transaction(true);
tx.set("key", "original").unwrap();
tx.commit().unwrap();
let mut tx = db.transaction(true);
tx.del("key").unwrap();
let result = tx.put("key", "recreated");
if result.is_ok() {
assert_eq!(tx.get("key").unwrap(), Some(Bytes::from("recreated")));
tx.commit().unwrap();
} else {
tx.cancel().unwrap();
}
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn putc_succeeds_when_value_matches() {
let db = Database::new();
let mut tx = db.transaction(true);
tx.set("key", "expected").unwrap();
tx.commit().unwrap();
let mut tx = db.transaction(true);
let result = tx.putc("key", "new_value", Some("expected"));
assert!(result.is_ok(), "putc should succeed when value matches");
assert_eq!(tx.get("key").unwrap(), Some(Bytes::from("new_value")));
tx.commit().unwrap();
let mut verify = db.transaction(false);
assert_eq!(verify.get("key").unwrap(), Some(Bytes::from("new_value")));
verify.cancel().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn putc_fails_when_value_differs() {
let db = Database::new();
let mut tx = db.transaction(true);
tx.set("key", "actual").unwrap();
tx.commit().unwrap();
let mut tx = db.transaction(true);
let result = tx.putc("key", "new_value", Some("wrong_expected"));
assert!(
matches!(result, Err(Error::ValNotExpectedValue)),
"putc should fail when value doesn't match"
);
assert_eq!(tx.get("key").unwrap(), Some(Bytes::from("actual")));
tx.cancel().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn putc_with_none_check_succeeds_for_non_existent_key() {
let db = Database::new();
let mut tx = db.transaction(true);
let result = tx.putc::<_, _, &[u8]>("new_key", "value", None);
assert!(result.is_ok(), "putc with None check should succeed for new key");
assert_eq!(tx.get("new_key").unwrap(), Some(Bytes::from("value")));
tx.commit().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn putc_with_none_check_fails_for_existing_key() {
let db = Database::new();
let mut tx = db.transaction(true);
tx.set("key", "exists").unwrap();
tx.commit().unwrap();
let mut tx = db.transaction(true);
let result = tx.putc::<_, _, &[u8]>("key", "new_value", None);
assert!(
matches!(result, Err(Error::ValNotExpectedValue)),
"putc with None check should fail for existing key"
);
tx.cancel().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn putc_in_same_transaction_with_matching_value() {
let db = Database::new();
let mut tx = db.transaction(true);
tx.set("key", "first").unwrap();
let result = tx.putc("key", "second", Some("first"));
assert!(result.is_ok(), "putc should succeed with matching writeset value");
assert_eq!(tx.get("key").unwrap(), Some(Bytes::from("second")));
tx.commit().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn putc_in_same_transaction_with_non_matching_value() {
let db = Database::new();
let mut tx = db.transaction(true);
tx.set("key", "first").unwrap();
let result = tx.putc("key", "second", Some("wrong"));
assert!(
matches!(result, Err(Error::ValNotExpectedValue)),
"putc should fail with non-matching writeset value"
);
assert_eq!(tx.get("key").unwrap(), Some(Bytes::from("first")));
tx.cancel().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn putc_after_delete_with_none_check() {
let db = Database::new();
let mut tx = db.transaction(true);
tx.set("key", "original").unwrap();
tx.commit().unwrap();
let mut tx = db.transaction(true);
tx.del("key").unwrap();
let result = tx.putc::<_, _, &[u8]>("key", "recreated", None);
assert!(result.is_ok(), "putc with None check should succeed after delete");
assert_eq!(tx.get("key").unwrap(), Some(Bytes::from("recreated")));
tx.commit().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn delc_succeeds_when_value_matches() {
let db = Database::new();
let mut tx = db.transaction(true);
tx.set("key", "expected").unwrap();
tx.commit().unwrap();
let mut tx = db.transaction(true);
let result = tx.delc("key", Some("expected"));
assert!(result.is_ok(), "delc should succeed when value matches");
assert!(tx.get("key").unwrap().is_none());
tx.commit().unwrap();
let mut verify = db.transaction(false);
assert!(verify.get("key").unwrap().is_none());
verify.cancel().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn delc_fails_when_value_differs() {
let db = Database::new();
let mut tx = db.transaction(true);
tx.set("key", "actual").unwrap();
tx.commit().unwrap();
let mut tx = db.transaction(true);
let result = tx.delc("key", Some("wrong"));
assert!(
matches!(result, Err(Error::ValNotExpectedValue)),
"delc should fail when value doesn't match"
);
assert_eq!(tx.get("key").unwrap(), Some(Bytes::from("actual")));
tx.cancel().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn delc_with_none_check_succeeds_for_non_existent_key() {
let db = Database::new();
let mut tx = db.transaction(true);
let result = tx.delc::<_, &[u8]>("non_existent", None);
assert!(result.is_ok(), "delc with None check should succeed for non-existent key");
tx.commit().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn delc_with_none_check_fails_for_existing_key() {
let db = Database::new();
let mut tx = db.transaction(true);
tx.set("key", "exists").unwrap();
tx.commit().unwrap();
let mut tx = db.transaction(true);
let result = tx.delc::<_, &[u8]>("key", None);
assert!(
matches!(result, Err(Error::ValNotExpectedValue)),
"delc with None check should fail for existing key"
);
tx.cancel().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn delc_in_same_transaction_with_matching_value() {
let db = Database::new();
let mut tx = db.transaction(true);
tx.set("key", "value").unwrap();
let result = tx.delc("key", Some("value"));
assert!(result.is_ok(), "delc should succeed with matching writeset value");
assert!(tx.get("key").unwrap().is_none());
tx.commit().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn delc_in_same_transaction_with_non_matching_value() {
let db = Database::new();
let mut tx = db.transaction(true);
tx.set("key", "value").unwrap();
let result = tx.delc("key", Some("wrong"));
assert!(
matches!(result, Err(Error::ValNotExpectedValue)),
"delc should fail with non-matching writeset value"
);
assert_eq!(tx.get("key").unwrap(), Some(Bytes::from("value")));
tx.cancel().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn conditional_operations_chain() {
let db = Database::new();
let mut tx = db.transaction(true);
tx.putc::<_, _, &[u8]>("key", "v1", None).unwrap();
assert_eq!(tx.get("key").unwrap(), Some(Bytes::from("v1")));
tx.putc("key", "v2", Some("v1")).unwrap();
assert_eq!(tx.get("key").unwrap(), Some(Bytes::from("v2")));
tx.putc("key", "v3", Some("v2")).unwrap();
assert_eq!(tx.get("key").unwrap(), Some(Bytes::from("v3")));
tx.delc("key", Some("v3")).unwrap();
assert!(tx.get("key").unwrap().is_none());
tx.putc::<_, _, &[u8]>("key", "final", None).unwrap();
assert_eq!(tx.get("key").unwrap(), Some(Bytes::from("final")));
tx.commit().unwrap();
let mut verify = db.transaction(false);
assert_eq!(verify.get("key").unwrap(), Some(Bytes::from("final")));
verify.cancel().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn conditional_operations_across_transactions() {
let db = Database::new();
let mut tx1 = db.transaction(true);
tx1.putc::<_, _, &[u8]>("key", "v1", None).unwrap();
tx1.commit().unwrap();
let mut tx2 = db.transaction(true);
tx2.putc("key", "v2", Some("v1")).unwrap();
tx2.commit().unwrap();
let mut tx3 = db.transaction(true);
let result = tx3.putc("key", "v3", Some("wrong"));
assert!(result.is_err());
tx3.cancel().unwrap();
let mut tx4 = db.transaction(true);
tx4.delc("key", Some("v2")).unwrap();
tx4.commit().unwrap();
let mut verify = db.transaction(false);
assert!(verify.get("key").unwrap().is_none());
verify.cancel().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn conditional_with_empty_value() {
let db = Database::new();
let mut tx = db.transaction(true);
tx.set("key", "").unwrap();
tx.commit().unwrap();
let mut tx = db.transaction(true);
let result = tx.putc("key", "non_empty", Some(""));
assert!(result.is_ok(), "putc with empty check value should work");
tx.commit().unwrap();
let mut verify = db.transaction(false);
assert_eq!(verify.get("key").unwrap(), Some(Bytes::from("non_empty")));
verify.cancel().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn conditional_with_binary_data() {
let db = Database::new();
let binary_data: Vec<u8> = vec![0x00, 0x01, 0x02, 0xFF, 0xFE];
let mut tx = db.transaction(true);
tx.set("key", binary_data.clone()).unwrap();
tx.commit().unwrap();
let mut tx = db.transaction(true);
let new_data: Vec<u8> = vec![0xAA, 0xBB, 0xCC];
let result = tx.putc("key", new_data.clone(), Some(binary_data));
assert!(result.is_ok(), "putc with binary check value should work");
tx.commit().unwrap();
let mut verify = db.transaction(false);
assert_eq!(verify.get("key").unwrap(), Some(Bytes::from(new_data)));
verify.cancel().unwrap();
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
#[test]
fn putc_concurrent_conflict() {
let db = Database::new();
let mut tx = db.transaction(true);
tx.set("key", "initial").unwrap();
tx.commit().unwrap();
let mut tx1 = db.transaction(true).with_serializable_snapshot_isolation();
let mut tx2 = db.transaction(true).with_serializable_snapshot_isolation();
let v1 = tx1.get("key").unwrap().unwrap();
let v2 = tx2.get("key").unwrap().unwrap();
assert_eq!(v1.as_ref(), b"initial");
assert_eq!(v2.as_ref(), b"initial");
tx1.putc("key", "tx1_value", Some("initial")).unwrap();
tx2.putc("key", "tx2_value", Some("initial")).unwrap();
assert!(tx1.commit().is_ok());
assert!(tx2.commit().is_err());
let mut verify = db.transaction(false);
assert_eq!(verify.get("key").unwrap(), Some(Bytes::from("tx1_value")));
verify.cancel().unwrap();
}