hail_core 0.3.0

a library for implementing a speedrun timer
Documentation
mod common;
use common::*;
use hail_core::types::*;

#[test]
#[ignore]
fn against_skipped_splits() {
    let mut s = init_skip();
    s.request(StateChangeRequest::Split);
    s.update();
    sleep(900); // t = 900
    s.request(StateChangeRequest::Split);
    s.update();
    same_time!(s.rta.run_pb_diffs[0].val(), -100);
    same_time!(s.rta.run_pb_seg_diffs[0].val(), -100);
    assert_eq!(s.rta.run_pb_statuses[0], SplitStatus::Ahead);
    assert_eq!(s.rta.active_pb_status, SplitStatus::None);
    assert_eq!(s.rta.run_gold_statuses[0], SplitStatus::Behind); // even though there is no pb to compare, there should be other comps
    assert_eq!(s.rta.active_pb_diff, 0);
    same_time!(s.rta.run_gold_diffs[0].val(), 100);
    sleep(1000); // t = 1900
    s.request(StateChangeRequest::Split);
    s.update();
    assert_eq!(s.rta.active_pb_status, SplitStatus::Ahead); // back to ahead (split at 3000ms)
    assert_eq!(s.rta.run_pb_diffs[1], TimeType::None);
    assert_eq!(s.rta.run_pb_seg_diffs[1], TimeType::None);
    assert_eq!(s.rta.run_pb_statuses[1], SplitStatus::None);
    assert_eq!(s.rta.run_gold_statuses[1], SplitStatus::Behind);
    sleep(1050); // t = 2950
    s.update();
    assert_eq!(s.rta.active_pb_status, SplitStatus::Losing); // 2950 is less than 100ms ahead of 3000ms (-100 being our last known diff)
}

#[test]
#[ignore]
fn against_missing_golds() {
    let mut s = init_missinggolds();
    s.request(StateChangeRequest::Split);
    s.update();
    sleep(700); // t = 700
    s.request(StateChangeRequest::Split);
    s.update();
    sleep(100); // t = 800
    assert_eq!(s.rta.run_gold_statuses[0], SplitStatus::Gold);
    same_time!(s.rta.run_gold_diffs[0].val(), -100); // first gold split was at 800
    same_time!(s.rta.run_gold_seg_diffs[0].val(), -100);
    s.request(StateChangeRequest::Split);
    s.update();
    sleep(100); // t = 900
    assert_eq!(s.rta.active_gold_status, SplitStatus::None); // now there are no more gold splits because a gold segment was missing
    assert_eq!(s.rta.active_gold_diff, 0);
    assert_eq!(s.rta.run_gold_diffs[1], TimeType::None);
    assert_eq!(s.rta.run_gold_seg_diffs[1], TimeType::None); // no gold seg to beat
    s.request(StateChangeRequest::Split);
    s.update();
    assert_eq!(s.rta.active_gold_status, SplitStatus::None); // now there are no more gold splits because a gold segment was missing
    assert_eq!(s.rta.active_gold_diff, 0);
    assert_eq!(s.rta.run_gold_diffs[2], TimeType::None);
    same_time!(s.rta.run_gold_seg_diffs[2].val(), -700); // original segment was 800ms, we just did 100
    sleep(100);
    s.request(StateChangeRequest::Split);
    s.update();
    let times = &[700, 100, 100, 100];
    for (i, g) in s.run.rta_gold_segments.iter().enumerate() {
        same_time!(g.val(), times[i]);
    }
}

#[test]
#[ignore]
fn skipping_splits() {
    let mut s = init_noofset();
    s.request(StateChangeRequest::Split);
    s.update();
    sleep(2100); // t = 2100
    s.request(StateChangeRequest::Skip);
    s.update();
    assert_eq!(s.rta.run_split_times[0], TimeType::None);
    assert_eq!(s.rta.run_seg_times[0], TimeType::None);
    assert_eq!(s.rta.active_pb_status, SplitStatus::Behind); // split is at 2000
    assert_eq!(s.rta.run_pb_statuses[0], SplitStatus::None);
    assert_eq!(s.rta.run_pb_diffs[0], TimeType::None);
    assert_eq!(s.rta.run_pb_seg_diffs[0], TimeType::None);
    sleep(400); // t = 2500
    s.request(StateChangeRequest::Split);
    s.update();
    same_time!(s.rta.run_split_times[1].val(), 2500);
    assert_eq!(s.rta.run_seg_times[1], TimeType::None);
    assert_eq!(s.rta.run_pb_statuses[1], SplitStatus::Behind);
    same_time!(s.rta.run_pb_diffs[1].val(), 500);
    assert_eq!(s.rta.run_pb_seg_diffs[1], TimeType::None);
    sleep(1000); // t = 3500
    s.request(StateChangeRequest::Skip);
    s.update();
    assert_eq!(s.rta.run_split_times[2], TimeType::None);
    assert_eq!(s.rta.run_seg_times[2], TimeType::None);
    assert_eq!(s.rta.active_pb_status, SplitStatus::Ahead); // split is at 4000
    assert_eq!(s.rta.run_pb_statuses[2], SplitStatus::None);
    assert_eq!(s.rta.run_pb_diffs[2], TimeType::None);
    assert_eq!(s.rta.run_pb_seg_diffs[2], TimeType::None);

    let mut s = init_noofset();
    s.request(StateChangeRequest::Split);
    s.update();
    sleep(2100); // t = 2100
    s.request(StateChangeRequest::Skip);
    s.update();
    assert_eq!(s.rta.run_split_times[0], TimeType::None);
    assert_eq!(s.rta.run_seg_times[0], TimeType::None);
    assert_eq!(s.rta.active_pb_status, SplitStatus::Behind); // split is at 2000
    assert_eq!(s.rta.run_pb_statuses[0], SplitStatus::None);
    assert_eq!(s.rta.run_pb_diffs[0], TimeType::None);
    assert_eq!(s.rta.run_pb_seg_diffs[0], TimeType::None);
    sleep(400); // t = 2500
    s.request(StateChangeRequest::Split);
    s.update();
    same_time!(s.rta.run_split_times[1].val(), 2500);
    assert_eq!(s.rta.run_seg_times[1], TimeType::None);
    assert_eq!(s.rta.run_pb_statuses[1], SplitStatus::Behind);
    same_time!(s.rta.run_pb_diffs[1].val(), 500);
    assert_eq!(s.rta.run_pb_seg_diffs[1], TimeType::None);
    sleep(1000); // t = 3500
    s.request(StateChangeRequest::Split);
    s.update();
    same_time!(s.rta.run_split_times[2].val(), 3500);
    same_time!(s.rta.run_seg_times[2].val(), 1000);
    assert_eq!(s.rta.active_pb_status, SplitStatus::Ahead); // split is at 4000
    assert_eq!(s.rta.run_pb_statuses[2], SplitStatus::Behind);
    same_time!(s.rta.run_pb_diffs[2].val(), 500);
    same_time!(s.rta.run_pb_seg_diffs[2].val(), 0);
}

#[test]
#[ignore]
fn skipping_more_statuses() {
    let mut s = init_noofset();
    s.request(StateChangeRequest::Split);
    s.update();
    sleep(1500); // t = 1500
    s.request(StateChangeRequest::Split);
    s.update();
    assert_eq!(s.rta.run_pb_statuses[0], SplitStatus::Behind); // original split at 1000ms
    same_time!(s.rta.run_pb_diffs[0].val(), 500);
    s.request(StateChangeRequest::Skip); // skip the split at 2000ms
    s.update();
    assert_eq!(s.rta.active_pb_status, SplitStatus::Ahead); // t still = 1500
    sleep(1800); // t = 3300
    s.update();
    assert_eq!(s.rta.active_pb_status, SplitStatus::Gaining); // not yet 500ms behind split at 3000ms

    let mut s = init_noofset();
    s.request(StateChangeRequest::Split);
    s.update();
    sleep(500); // t = 500
    s.request(StateChangeRequest::Split);
    s.update();
    assert_eq!(s.rta.run_pb_statuses[0], SplitStatus::Gold); // original split at 1000ms
    same_time!(s.rta.run_pb_diffs[0].val(), -500);
    s.request(StateChangeRequest::Skip); // skip the split at 2000ms
    s.update();
    assert_eq!(s.rta.active_pb_status, SplitStatus::Ahead); // t still = 500
    sleep(2100); // t = 2600
    s.update();
    assert_eq!(s.rta.active_pb_status, SplitStatus::Losing); // no longer 500ms ahead of split at 3000ms
}