use super::*;
use core::alloc::Layout;
use facet_core::{Facet, Shape};
type S<'a> = VShapeView<'a, VShapeStore>;
#[test]
fn verified_alloc_dealloc() {
let mut store = VShapeStore::new();
let h = store.add(VShapeDef::scalar(Layout::new::<u32>()));
let shape = store.view(h);
let mut heap = VHeap::<S<'_>>::new();
let ptr = unsafe { heap.alloc(shape) };
assert!(ptr.is_at_start());
assert_eq!(ptr.alloc_size(), 4);
unsafe { heap.dealloc(ptr, shape) };
heap.assert_no_leaks();
}
#[test]
fn vshape_scalar_is_not_struct() {
let mut store = VShapeStore::new();
let h = store.add(VShapeDef::scalar(Layout::new::<u32>()));
let s = store.view(h);
assert!(!s.is_struct());
assert!(s.as_struct().is_none());
}
#[test]
fn vshape_struct_is_struct() {
let mut store = VShapeStore::new();
let u32_h = store.add(VShapeDef::scalar(Layout::new::<u32>()));
let struct_def = VShapeDef::struct_with_fields(&store, &[(0, u32_h), (4, u32_h)]);
let struct_h = store.add(struct_def);
let s = store.view(struct_h);
assert!(s.is_struct());
assert!(s.as_struct().is_some());
}
#[test]
fn vshape_struct_field_access() {
let mut store = VShapeStore::new();
let u32_h = store.add(VShapeDef::scalar(Layout::new::<u32>()));
let u64_h = store.add(VShapeDef::scalar(Layout::new::<u64>()));
let struct_def = VShapeDef::struct_with_fields(&store, &[(0, u32_h), (8, u64_h)]);
let struct_h = store.add(struct_def);
let s = store.view(struct_h);
let st = s.as_struct().unwrap();
assert_eq!(st.field_count(), 2);
let f0 = st.field(0).unwrap();
assert_eq!(f0.offset(), 0);
assert_eq!(f0.shape().layout().unwrap().size(), 4);
let f1 = st.field(1).unwrap();
assert_eq!(f1.offset(), 8);
assert_eq!(f1.shape().layout().unwrap().size(), 8);
assert!(st.field(2).is_none());
}
#[test]
fn vshape_nested_struct() {
let mut store = VShapeStore::new();
let u32_h = store.add(VShapeDef::scalar(Layout::new::<u32>()));
let inner_def = VShapeDef::struct_with_fields(&store, &[(0, u32_h), (4, u32_h)]);
let inner_h = store.add(inner_def);
let u64_h = store.add(VShapeDef::scalar(Layout::new::<u64>()));
let outer_def = VShapeDef::struct_with_fields(
&store,
&[
(0, u64_h),
(8, inner_h), ],
);
let outer_h = store.add(outer_def);
let outer = store.view(outer_h);
assert!(outer.is_struct());
let outer_st = outer.as_struct().unwrap();
assert_eq!(outer_st.field_count(), 2);
let f0 = outer_st.field(0).unwrap();
assert_eq!(f0.offset(), 0);
assert!(!f0.shape().is_struct());
assert_eq!(f0.shape().layout().unwrap().size(), 8);
let f1 = outer_st.field(1).unwrap();
assert_eq!(f1.offset(), 8);
assert!(f1.shape().is_struct());
let inner_st = f1.shape().as_struct().unwrap();
assert_eq!(inner_st.field_count(), 2);
let inner_f0 = inner_st.field(0).unwrap();
assert_eq!(inner_f0.offset(), 0);
assert_eq!(inner_f0.shape().layout().unwrap().size(), 4);
let inner_f1 = inner_st.field(1).unwrap();
assert_eq!(inner_f1.offset(), 4);
assert_eq!(inner_f1.shape().layout().unwrap().size(), 4);
}
#[derive(facet::Facet)]
struct TestStruct {
a: u32,
b: u64,
}
#[test]
fn real_shape_is_struct() {
let shape: &'static Shape = TestStruct::SHAPE;
assert!(shape.is_struct());
assert!(shape.as_struct().is_some());
}
#[test]
fn real_shape_field_access() {
let shape: &'static Shape = TestStruct::SHAPE;
let st = shape.as_struct().unwrap();
assert_eq!(st.field_count(), 2);
let f0 = st.field(0).unwrap();
let f1 = st.field(1).unwrap();
assert!(f0.shape().layout().unwrap().size() > 0);
assert!(f1.shape().layout().unwrap().size() > 0);
assert!(st.field(2).is_none());
}
#[test]
fn real_scalar_is_not_struct() {
let shape: &'static Shape = u32::SHAPE;
assert!(!shape.is_struct());
assert!(shape.as_struct().is_none());
}
#[derive(facet::Facet)]
struct Inner {
a: u32,
b: u32,
}
#[derive(facet::Facet)]
struct Outer {
x: u64,
inner: Inner,
}
#[test]
fn real_nested_struct() {
let shape: &'static Shape = Outer::SHAPE;
assert!(shape.is_struct());
let st = shape.as_struct().unwrap();
assert_eq!(st.field_count(), 2);
let inner_field = st
.field(0)
.filter(|f| f.shape().is_struct())
.or_else(|| st.field(1).filter(|f| f.shape().is_struct()))
.expect("should have a struct field");
let inner_st = inner_field.shape().as_struct().unwrap();
assert_eq!(inner_st.field_count(), 2);
}
#[test]
fn verified_arena_alloc_and_get() {
let mut arena = VArena::<u32, 8>::new();
let id = arena.alloc(42);
assert!(id.is_valid());
assert_eq!(*arena.get(id), 42);
}
#[test]
fn verified_arena_free_and_reuse() {
let mut arena = VArena::<u32, 8>::new();
let id1 = arena.alloc(1);
let _id2 = arena.alloc(2);
let val = arena.free(id1);
assert_eq!(val, 1);
let id3 = arena.alloc(3);
assert!(id3.is_valid());
assert_eq!(*arena.get(id3), 3);
}
#[test]
#[should_panic(expected = "double-free")]
fn verified_arena_double_free_panics() {
let mut arena = VArena::<u32, 8>::new();
let id = arena.alloc(1);
arena.free(id);
arena.free(id);
}
#[test]
fn verified_arena_get_mut() {
let mut arena = VArena::<u32, 8>::new();
let id = arena.alloc(1);
*arena.get_mut(id) = 99;
assert_eq!(*arena.get(id), 99);
}