#![cfg(feature = "std")]
use mem_dbg::*;
use std::sync::{Mutex, RwLock};
#[test]
fn test_mutex_flat_payload() {
let m = Mutex::new(42_u64);
assert_eq!(
m.mem_size(SizeFlags::default()),
core::mem::size_of::<Mutex<u64>>()
);
}
#[test]
fn test_mutex_string_payload() {
let s = String::from("hello");
let len = s.len();
let cap = s.capacity();
let m = Mutex::new(s);
assert_eq!(
m.mem_size(SizeFlags::default()),
core::mem::size_of::<Mutex<String>>() + len
);
assert_eq!(
m.mem_size(SizeFlags::CAPACITY),
core::mem::size_of::<Mutex<String>>() + cap
);
}
#[test]
fn test_mutex_vec_payload() {
let m = Mutex::new(vec![1u32, 2, 3]);
let len = 3;
assert_eq!(
m.mem_size(SizeFlags::default()),
core::mem::size_of::<Mutex<Vec<u32>>>() + len * core::mem::size_of::<u32>()
);
}
#[test]
fn test_rwlock_flat_payload() {
let r = RwLock::new(42_u64);
assert_eq!(
r.mem_size(SizeFlags::default()),
core::mem::size_of::<RwLock<u64>>()
);
}
#[test]
fn test_rwlock_string_payload() {
let s = String::from("hello");
let len = s.len();
let cap = s.capacity();
let r = RwLock::new(s);
assert_eq!(
r.mem_size(SizeFlags::default()),
core::mem::size_of::<RwLock<String>>() + len
);
assert_eq!(
r.mem_size(SizeFlags::CAPACITY),
core::mem::size_of::<RwLock<String>>() + cap
);
}
#[test]
fn test_rwlock_vec_payload() {
let r = RwLock::new(vec![1u32, 2, 3]);
let len = 3;
assert_eq!(
r.mem_size(SizeFlags::default()),
core::mem::size_of::<RwLock<Vec<u32>>>() + len * core::mem::size_of::<u32>()
);
}
#[test]
fn test_mutex_mem_size_while_locked_reports_shell_only() {
let m = Mutex::new(String::from("hello"));
let _guard = m.lock().expect("lock");
assert_eq!(
m.mem_size(SizeFlags::default()),
core::mem::size_of::<Mutex<String>>()
);
assert_eq!(
m.mem_size(SizeFlags::CAPACITY),
core::mem::size_of::<Mutex<String>>()
);
}
#[test]
fn test_rwlock_mem_size_while_write_locked_reports_shell_only() {
let r = RwLock::new(String::from("hello"));
let _guard = r.write().expect("write lock");
assert_eq!(
r.mem_size(SizeFlags::default()),
core::mem::size_of::<RwLock<String>>()
);
assert_eq!(
r.mem_size(SizeFlags::CAPACITY),
core::mem::size_of::<RwLock<String>>()
);
}
#[test]
fn test_mutex_mem_dbg_while_locked_marks_locked() {
let m = Mutex::new(vec![1_u8, 2, 3]);
let _guard = m.lock().expect("lock");
let mut output = String::new();
m.mem_dbg_on(&mut output, DbgFlags::default())
.expect("mem_dbg_on");
assert!(output.contains("<locked>"));
}
#[test]
fn test_rwlock_mem_dbg_while_write_locked_marks_locked() {
let r = RwLock::new(vec![1_u8, 2, 3]);
let _guard = r.write().expect("write lock");
let mut output = String::new();
r.mem_dbg_on(&mut output, DbgFlags::default())
.expect("mem_dbg_on");
assert!(output.contains("<locked>"));
}
#[cfg(feature = "derive")]
#[derive(MemSize, MemDbg)]
struct Inner {
heavy: Vec<u8>,
}
#[cfg(feature = "derive")]
fn render<T: MemDbg>(value: &T) -> String {
let mut out = String::new();
value
.mem_dbg_on(&mut out, DbgFlags::default())
.expect("mem_dbg_on");
out
}
#[cfg(feature = "derive")]
#[test]
fn test_mutex_renders_inner_children_under_default_flags() {
let m = Mutex::new(Inner {
heavy: vec![0u8; 64],
});
let out = render(&m);
assert!(out.contains("Mutex"));
assert!(
out.contains("heavy"),
"Mutex did not recurse into Inner under default flags:\n{out}"
);
}
#[cfg(feature = "derive")]
#[test]
fn test_rwlock_renders_inner_children_under_default_flags() {
let r = RwLock::new(Inner {
heavy: vec![0u8; 64],
});
let out = render(&r);
assert!(out.contains("RwLock"));
assert!(
out.contains("heavy"),
"RwLock did not recurse into Inner under default flags:\n{out}"
);
}