euv-engine 0.28.21

A high-performance 2D game engine built on the euv framework, featuring ECS, fixed-timestep game loop, canvas rendering, physics, collision detection, sprite animation, and audio.
Documentation
use super::*;

#[test]
fn a_value_inside_the_deadzone_reads_as_zero() {
    let observed: f64 = apply_axis_deadzone(0.1);
    assert_eq!(
        observed, 0.0,
        "joystick drift below the deadzone is dropped"
    );
}

#[test]
fn the_deadzone_boundary_itself_reads_as_zero() {
    let observed: f64 = apply_axis_deadzone(0.15);
    assert_eq!(
        observed, 0.0,
        "the comparison is inclusive, so exactly at the deadzone is still zero"
    );
}

#[test]
fn a_value_just_outside_the_deadzone_rescales_upward() {
    let observed: f64 = apply_axis_deadzone(0.16);
    assert!(
        observed > 0.0,
        "crossing the deadzone must not stay at zero, got {observed}"
    );
}

#[test]
fn a_full_deflection_rescales_to_one() {
    let observed: f64 = apply_axis_deadzone(1.0);
    assert!(
        (observed - 1.0).abs() < 1e-9,
        "the post-deadzone span is rescaled onto the full range, got {observed}"
    );
}

#[test]
fn a_full_negative_deflection_rescales_to_minus_one() {
    let observed: f64 = apply_axis_deadzone(-1.0);
    assert!(
        (observed + 1.0).abs() < 1e-9,
        "the sign is preserved through the rescale, got {observed}"
    );
}

#[test]
fn the_deadzone_rescale_is_symmetric_about_zero() {
    let positive: f64 = apply_axis_deadzone(0.6);
    let negative: f64 = apply_axis_deadzone(-0.6);
    assert!(
        (positive + negative).abs() < 1e-9,
        "mirror inputs must give mirror outputs, got {positive} vs {negative}"
    );
}

#[test]
fn an_over_range_value_is_clamped_to_one() {
    let observed: f64 = apply_axis_deadzone(1.5);
    assert!(
        (observed - 1.0).abs() < 1e-9,
        "an out-of-range reading must not rescale past one, got {observed}"
    );
}

#[test]
fn an_over_range_negative_value_is_clamped_to_minus_one() {
    let observed: f64 = apply_axis_deadzone(-1.5);
    assert!(
        (observed + 1.0).abs() < 1e-9,
        "an out-of-range negative must not pass minus one, got {observed}"
    );
}

#[test]
fn exactly_zero_reads_as_zero() {
    let observed: f64 = apply_axis_deadzone(0.0);
    assert_eq!(observed, 0.0, "a centred stick is zero");
}

#[test]
fn a_button_at_the_press_threshold_counts_as_down() {
    let observed: bool = is_button_down(0.5);
    assert!(observed, "the threshold comparison is inclusive");
}

#[test]
fn a_button_just_below_the_threshold_is_up() {
    let observed: bool = is_button_down(0.49);
    assert!(!observed, "just under the threshold is still released");
}

#[test]
fn a_fully_pressed_button_is_down() {
    let observed: bool = is_button_down(1.0);
    assert!(observed, "full deflection is definitely down");
}

#[test]
fn a_released_button_is_up() {
    let observed: bool = is_button_down(0.0);
    assert!(!observed, "no deflection is up");
}

#[test]
fn compute_held_reports_every_button_currently_down() {
    let observed: GamepadButtonSet = compute_held_buttons(&[1.0, 0.0, 1.0]);
    assert_eq!(observed.len(), 2, "two of the three are down");
    assert!(
        observed.contains(&0) && observed.contains(&2),
        "the right two"
    );
}

#[test]
fn compute_held_of_no_buttons_is_empty() {
    let observed: GamepadButtonSet = compute_held_buttons(&[0.0, 0.0]);
    assert!(observed.is_empty(), "nothing down means nothing held");
}

#[test]
fn compute_pressed_reports_only_newly_down_buttons() {
    let mut previous: GamepadButtonSet = GamepadButtonSet::new();
    previous.insert(0);
    let observed: GamepadButtonSet = compute_pressed_buttons(&previous, &[1.0, 1.0]);
    assert_eq!(
        observed.len(),
        1,
        "only the newly pressed button is an edge"
    );
    assert!(observed.contains(&1), "the button that was not held before");
}

#[test]
fn holding_the_same_button_again_produces_no_press_edge() {
    let mut previous: GamepadButtonSet = GamepadButtonSet::new();
    previous.insert(0);
    previous.insert(1);
    let observed: GamepadButtonSet = compute_pressed_buttons(&previous, &[1.0, 1.0]);
    assert!(observed.is_empty(), "a sustained hold is not a new press");
}

#[test]
fn compute_pressed_from_nothing_holds_reports_everything_down() {
    let previous: GamepadButtonSet = GamepadButtonSet::new();
    let observed: GamepadButtonSet = compute_pressed_buttons(&previous, &[1.0, 1.0, 1.0]);
    assert_eq!(observed.len(), 3, "the first frame of a press is an edge");
}

#[test]
fn compute_released_reports_only_newly_up_buttons() {
    let mut previous: GamepadButtonSet = GamepadButtonSet::new();
    previous.insert(0);
    previous.insert(1);
    let observed: GamepadButtonSet = compute_released_buttons(&previous, &[0.0, 1.0]);
    assert_eq!(observed.len(), 1, "only the button that came up");
    assert!(observed.contains(&0), "the released one, not the held one");
}

#[test]
fn a_sustained_hold_produces_no_release_edge() {
    let mut previous: GamepadButtonSet = GamepadButtonSet::new();
    previous.insert(0);
    let observed: GamepadButtonSet = compute_released_buttons(&previous, &[1.0]);
    assert!(observed.is_empty(), "a button still down is not released");
}

#[test]
fn a_button_whose_slot_vanished_counts_as_released() {
    let mut previous: GamepadButtonSet = GamepadButtonSet::new();
    previous.insert(5);
    let observed: GamepadButtonSet = compute_released_buttons(&previous, &[]);
    assert!(
        observed.contains(&5),
        "a previously held button that is no longer reported is released, not stuck"
    );
}

#[test]
fn press_and_release_edges_never_land_on_the_same_button() {
    let mut previous: GamepadButtonSet = GamepadButtonSet::new();
    previous.insert(0);
    let values: [f64; 2] = [0.0, 1.0];
    let pressed: GamepadButtonSet = compute_pressed_buttons(&previous, &values);
    let released: GamepadButtonSet = compute_released_buttons(&previous, &values);
    assert_eq!(pressed.len(), 1, "button 1 came down");
    assert_eq!(released.len(), 1, "button 0 came up");
    assert!(
        pressed.contains(&1) && released.contains(&0),
        "the two edges belong to different buttons"
    );
}

#[test]
fn a_frame_with_no_changes_produces_no_edges_at_all() {
    let mut previous: GamepadButtonSet = GamepadButtonSet::new();
    previous.insert(0);
    previous.insert(1);
    let values: [f64; 2] = [1.0, 1.0];
    let pressed: GamepadButtonSet = compute_pressed_buttons(&previous, &values);
    let released: GamepadButtonSet = compute_released_buttons(&previous, &values);
    assert!(pressed.is_empty(), "nothing came down");
    assert!(released.is_empty(), "nothing came up");
}

#[test]
fn read_raw_axis_returns_the_value_at_the_index() {
    let observed: f64 = read_raw_axis(&[0.1, 0.2, 0.3], 1);
    assert!(
        (observed - 0.2).abs() < 1e-9,
        "the axis is read positionally, got {observed}"
    );
}

#[test]
fn read_raw_axis_beyond_the_slice_reads_as_zero() {
    let observed: f64 = read_raw_axis(&[0.1], 9);
    assert_eq!(
        observed, 0.0,
        "a missing axis reads as centred, not a panic"
    );
}

#[test]
fn read_raw_axis_from_an_empty_slice_reads_as_zero() {
    let observed: f64 = read_raw_axis(&[], 0);
    assert_eq!(observed, 0.0, "no axes reported means centred");
}

#[test]
fn read_raw_axis_index_zero_is_the_first_axis() {
    let observed: f64 = read_raw_axis(&[0.75, 0.0], 0);
    assert!(
        (observed - 0.75).abs() < 1e-9,
        "axis zero is the first slot, got {observed}"
    );
}