fish-shell/src/tests/common.rs
2024-06-29 18:03:52 -07:00

77 lines
2.2 KiB
Rust

use crate::common::{scoped_push, truncate_at_nul, ScopeGuard, ScopeGuarding};
use crate::wchar::prelude::*;
#[test]
fn test_scoped_push() {
struct Context {
value: i32,
}
let mut value = 0;
let mut ctx = Context { value };
{
let mut ctx = scoped_push(&mut ctx, |ctx| &mut ctx.value, value + 1);
value = ctx.value;
assert_eq!(value, 1);
{
let mut ctx = scoped_push(&mut ctx, |ctx| &mut ctx.value, value + 1);
assert_eq!(ctx.value, 2);
ctx.value = 5;
assert_eq!(ctx.value, 5);
}
assert_eq!(ctx.value, 1);
}
assert_eq!(ctx.value, 0);
}
#[test]
fn test_scope_guard() {
let relaxed = std::sync::atomic::Ordering::Relaxed;
let counter = std::sync::atomic::AtomicUsize::new(0);
{
let guard = ScopeGuard::new(123, |arg| {
assert_eq!(*arg, 123);
counter.fetch_add(1, relaxed);
});
assert_eq!(counter.load(relaxed), 0);
std::mem::drop(guard);
assert_eq!(counter.load(relaxed), 1);
}
// commit also invokes the callback.
{
let guard = ScopeGuard::new(123, |arg| {
assert_eq!(*arg, 123);
counter.fetch_add(1, relaxed);
});
assert_eq!(counter.load(relaxed), 1);
let val = ScopeGuard::commit(guard);
assert_eq!(counter.load(relaxed), 2);
assert_eq!(val, 123);
}
}
#[test]
fn test_scope_guard_consume() {
// The following pattern works.
struct Storage {
value: &'static str,
}
let obj = Storage { value: "nu" };
assert_eq!(obj.value, "nu");
let obj = scoped_push(obj, |obj| &mut obj.value, "mu");
assert_eq!(obj.value, "mu");
let obj = scoped_push(obj, |obj| &mut obj.value, "mu2");
assert_eq!(obj.value, "mu2");
let obj = ScopeGuarding::commit(obj);
assert_eq!(obj.value, "mu");
let obj = ScopeGuarding::commit(obj);
assert_eq!(obj.value, "nu");
}
#[test]
fn test_truncate_at_nul() {
assert_eq!(truncate_at_nul(L!("abc\0def")), L!("abc"));
assert_eq!(truncate_at_nul(L!("abc")), L!("abc"));
assert_eq!(truncate_at_nul(L!("\0abc")), L!(""));
}