use std::sync::atomic::{AtomicUsize, Ordering};
use super::Allocator;
use crate::{Box, Vec};
#[test]
fn test_allocator_new() {
let allocator = Allocator::new();
assert_eq!(allocator.allocated_bytes(), 0);
}
#[test]
fn test_allocator_default() {
let allocator = Allocator::default();
assert_eq!(allocator.allocated_bytes(), 0);
}
#[test]
fn test_alloc_str() {
let allocator = Allocator::new();
let s = allocator.alloc_str("hello world");
assert_eq!(s, "hello world");
}
#[test]
fn test_oxc_pool_allocates_and_counts() {
let allocator = Allocator::new();
let s = allocator.as_oxc().alloc_str("retained");
assert_eq!(s, "retained");
assert_ne!(allocator.allocated_bytes(), 0);
}
#[test]
fn test_containers_and_strings_share_the_handle_lifetime() {
let allocator = Allocator::new();
let allocator = &allocator;
let from_str = allocator.alloc_str("string side");
let from_oxc = allocator.as_oxc().alloc_str("retained side");
let boxed = Box::new_in(7_u32, &allocator);
assert_eq!(
(from_str, from_oxc, *boxed),
("string side", "retained side", 7)
);
}
#[test]
fn test_reset_clears_the_pool() {
let mut allocator = Allocator::new();
{
let alloc = &allocator;
let _ = alloc.alloc_str("hello");
let mut v: Vec<'_, u32> = Vec::new_in(&alloc);
v.push(1);
}
assert_ne!(allocator.allocated_bytes(), 0);
allocator.reset();
assert_eq!(allocator.allocated_bytes(), 0);
}
struct DropWitness {
drops: &'static AtomicUsize,
payload: u32,
}
impl Drop for DropWitness {
fn drop(&mut self) {
self.drops.fetch_add(1, Ordering::Relaxed);
}
}
#[test]
fn test_alloc_owned_borrows_for_the_compile_and_drops_at_reset() {
static DROPS: AtomicUsize = AtomicUsize::new(0);
let mut allocator = Allocator::new();
{
let parked = allocator.alloc_owned(DropWitness {
drops: &DROPS,
payload: 42,
});
assert_eq!(parked.payload, 42);
assert_eq!(DROPS.load(Ordering::Relaxed), 0);
}
allocator.reset();
assert_eq!(DROPS.load(Ordering::Relaxed), 1);
}
#[test]
fn test_alloc_owned_drops_with_the_allocator() {
static DROPS: AtomicUsize = AtomicUsize::new(0);
{
let allocator = Allocator::new();
let parked = allocator.alloc_owned(DropWitness {
drops: &DROPS,
payload: 7,
});
assert_eq!(parked.payload, 7);
assert_eq!(DROPS.load(Ordering::Relaxed), 0);
}
assert_eq!(DROPS.load(Ordering::Relaxed), 1);
}
#[test]
fn test_alloc_owned_survives_further_parks() {
let allocator = Allocator::new();
let first: &crate::String = allocator.alloc_owned(crate::String::from("first"));
let mut parked = std::vec::Vec::new();
for index in 0..32_usize {
let name = match index % 2 {
0 => "even",
_ => "odd",
};
parked.push(allocator.alloc_owned(crate::String::from(name)));
}
assert_eq!(first.as_str(), "first");
assert_eq!(parked[31].as_str(), "odd");
}
#[test]
#[cfg(debug_assertions)]
#[should_panic(expected = "arena-backed value outlived its compile")]
fn test_stale_stamp_panics_after_reset() {
let mut allocator = Allocator::new();
let stamp = allocator.stamp();
allocator.assert_stamp_current(stamp);
allocator.reset();
allocator.assert_stamp_current(stamp);
}
#[test]
fn test_stamp_stays_current_without_a_reset() {
let allocator = Allocator::new();
let stamp = allocator.stamp();
let _ = allocator.alloc_str("allocation alone is not a generation change");
allocator.assert_stamp_current(stamp);
assert_eq!(stamp, allocator.stamp());
}
#[test]
#[cfg(debug_assertions)]
#[should_panic(expected = "arena-backed value outlived its compile")]
fn test_stamp_from_another_arena_panics() {
let first = Allocator::new();
let second = Allocator::new();
second.assert_stamp_current(first.stamp());
}