molframe-core 0.5.1

Core types, storage and analysis contracts for molframe
Documentation
use super::*;
use num_traits::ToPrimitive;

#[test]
fn a_lane_is_three_cache_lines_so_the_allocation_is_aligned() {
    assert_eq!(size_of::<CoordLane>(), 192);
    assert_eq!(align_of::<CoordLane>(), 64);
}

#[test]
fn positions_are_contiguous_across_lane_boundaries() {
    let block: CoordinateBlock = (0..40)
        .map(|i| [i.to_f32().expect("small coordinate"), 0.0, 0.0])
        .collect();
    assert_eq!(block.len(), 40);
    let slice = block.as_slice();
    assert_eq!(slice.len(), 40);
    for (i, position) in slice.iter().enumerate() {
        assert_eq!(
            position[0].to_bits(),
            i.to_f32().expect("small coordinate").to_bits()
        );
    }
}

#[test]
fn the_slice_stops_at_the_position_count_not_at_the_lane_boundary() {
    let mut block = CoordinateBlock::new();
    block.push([1.0, 1.0, 1.0]);
    assert_eq!(block.as_slice().len(), 1);
    assert_eq!(block.allocated_bytes(), block.lanes.capacity() * 192);
}

#[test]
fn allocated_bytes_include_reserved_lanes_before_positions_are_written() {
    let mut block = CoordinateBlock::with_capacity(1000);
    let bytes = block.allocated_bytes();
    assert!(bytes >= 1000 * size_of::<[f32; 3]>());
    assert!(block.is_empty());
    block.push([1.0; 3]);
    assert_eq!(block.allocated_bytes(), bytes);
    let shared = block.clone();
    assert_eq!(shared.allocated_bytes(), bytes);
    drop(block);
    assert_eq!(shared.allocated_bytes(), bytes);
}

#[test]
fn a_cloned_block_shares_storage_until_one_copy_is_edited() {
    let original: CoordinateBlock = [[1.0, 2.0, 3.0]].into_iter().collect();
    let mut edited = original.clone();
    assert!(std::ptr::eq(
        original.as_slice().as_ptr(),
        edited.as_slice().as_ptr()
    ));

    edited.as_mut_slice()[0][0] = 9.0;
    assert!(!std::ptr::eq(
        original.as_slice().as_ptr(),
        edited.as_slice().as_ptr()
    ));
    assert_eq!(original.as_slice()[0][0].to_bits(), 1.0_f32.to_bits());
    assert_eq!(edited.as_slice()[0][0].to_bits(), 9.0_f32.to_bits());
}

#[test]
fn a_range_past_the_end_yields_nothing_rather_than_a_short_slice() {
    let block: CoordinateBlock = (0..5).map(|_| [0.0; 3]).collect();
    assert!(block.range(0..5).is_some());
    assert!(block.range(0..6).is_none());
    assert!(block.range(3..99).is_none());
}

#[test]
fn a_bounding_box_ignores_non_finite_positions() {
    let mut bounds = Aabb::EMPTY;
    bounds.extend([1.0, 2.0, 3.0]);
    bounds.extend([f32::NAN, -1.0, 0.0]);
    assert_eq!(
        bounds.min.map(f32::to_bits),
        [1.0, -1.0, 0.0].map(f32::to_bits)
    );
    assert_eq!(
        bounds.max.map(f32::to_bits),
        [1.0, 2.0, 3.0].map(f32::to_bits)
    );
}

#[test]
fn an_empty_bounding_box_is_never_within_reach_of_anything() {
    let full = Aabb {
        min: [0.0; 3],
        max: [1.0; 3],
    };
    assert!(!Aabb::EMPTY.within(&full, 1000.0));
    assert!(!full.within(&Aabb::EMPTY, 1000.0));
}

#[test]
fn boxes_that_are_further_apart_than_the_cutoff_are_rejected() {
    let left = Aabb {
        min: [0.0; 3],
        max: [1.0; 3],
    };
    let right = Aabb {
        min: [10.0, 0.0, 0.0],
        max: [11.0, 1.0, 1.0],
    };
    assert!(!left.within(&right, 8.0));
    assert!(left.within(&right, 9.0));
    assert!(left.within(&left, 0.0));
}

#[test]
fn a_generation_advances_and_rejects_overflow() {
    assert_eq!(
        CoordinateGeneration::INITIAL
            .next()
            .map(CoordinateGeneration::get),
        Some(1)
    );
    assert_eq!(
        CoordinateGeneration::INITIAL
            .next()
            .and_then(CoordinateGeneration::next),
        Some(CoordinateGeneration(2))
    );
    assert_eq!(CoordinateGeneration(u64::MAX).next(), None);
}