use super::*;
fn ms() -> Timebase {
Timebase::MILLIS
}
fn at(ticks: i64) -> Timestamp {
Timestamp::new(ticks, ms())
}
fn end_of(m: &Measured, track: usize) -> Option<Timestamp> {
m.get(track, ms()).map(|e| e.end())
}
#[test]
fn nothing_is_measured_before_a_packet_arrives() {
let m = Measured::new(3).expect("reserve");
for track in 0..3 {
assert_eq!(m.get(track, ms()), None);
}
assert_eq!(m.get(3, ms()), None, "outside the table");
assert_eq!(Measured::new(0).expect("reserve").get(0, ms()), None);
}
#[test]
fn a_packets_end_is_its_timestamp_plus_its_duration() {
let mut m = Measured::new(1).expect("reserve");
m.observe(0, Some(1_960), 40);
assert_eq!(
m.get(0, ms()),
Some(MeasuredEnd::new(at(2_000), false, true))
);
}
#[test]
fn a_packet_without_a_duration_ends_where_it_starts_and_the_end_is_a_lower_bound() {
let mut m = Measured::new(1).expect("reserve");
m.observe(0, Some(500), 0);
let figure = m.get(0, ms()).expect("measured");
assert_eq!(figure.end(), at(500));
assert!(!figure.exact());
let mut m = Measured::new(1).expect("reserve");
m.observe(0, Some(600), -3);
let figure = m.get(0, ms()).expect("measured");
assert_eq!(figure.end(), at(600));
assert!(!figure.exact());
}
#[test]
fn a_lower_bound_stays_a_lower_bound() {
let mut m = Measured::new(1).expect("reserve");
m.observe(0, Some(0), 40);
assert!(m.get(0, ms()).expect("measured").exact());
m.observe(0, Some(40), 0);
assert!(!m.get(0, ms()).expect("measured").exact());
m.observe(0, Some(80), 40);
let figure = m.get(0, ms()).expect("measured");
assert_eq!(figure.end(), at(120));
assert!(!figure.exact());
}
#[test]
fn a_track_whose_packets_all_carry_a_duration_is_exact() {
let mut m = Measured::new(1).expect("reserve");
for pts in (0..2_000).step_by(40) {
m.observe(0, Some(pts), 40);
}
let figure = m.get(0, ms()).expect("measured");
assert_eq!(figure.end(), at(2_000));
assert!(figure.exact());
}
#[test]
fn a_packet_read_without_a_timestamp_makes_the_end_a_lower_bound() {
let mut m = Measured::new(1).expect("reserve");
m.observe(0, Some(0), 40);
m.observe(0, None, 0);
let figure = m.get(0, ms()).expect("measured");
assert_eq!(figure.end(), at(40));
assert!(!figure.exact());
}
#[test]
fn a_timestamp_less_first_packet_leaves_the_track_inexact_for_good() {
let mut m = Measured::new(1).expect("reserve");
m.observe(0, None, 40);
assert_eq!(m.get(0, ms()), None, "no end yet");
m.observe(0, Some(0), 40);
let figure = m.get(0, ms()).expect("measured");
assert_eq!(figure.end(), at(40));
assert!(!figure.exact());
}
#[test]
fn inexactness_is_kept_per_track() {
let mut m = Measured::new(2).expect("reserve");
m.observe(0, Some(0), 40);
m.observe(1, Some(0), 0);
assert!(m.get(0, ms()).expect("measured").exact());
assert!(!m.get(1, ms()).expect("measured").exact());
}
#[test]
fn the_figure_is_the_greatest_end_and_not_the_last_one() {
let mut m = Measured::new(1).expect("reserve");
m.observe(0, Some(80), 40);
m.observe(0, Some(40), 40);
m.observe(0, Some(0), 40);
assert_eq!(end_of(&m, 0), Some(at(120)));
}
#[test]
fn a_packet_without_a_timestamp_is_passed_over() {
let mut m = Measured::new(1).expect("reserve");
m.observe(0, None, 40);
assert_eq!(m.get(0, ms()), None);
m.observe(0, Some(10), 40);
m.observe(0, None, 1_000_000);
assert_eq!(end_of(&m, 0), Some(at(50)));
}
#[test]
fn each_track_keeps_its_own_figure_and_a_stray_index_is_ignored() {
let mut m = Measured::new(2).expect("reserve");
m.observe(0, Some(1_960), 40);
m.observe(1, Some(3), 1);
m.observe(7, Some(99), 1);
m.observe(7, None, 0);
assert_eq!(end_of(&m, 0), Some(at(2_000)));
assert_eq!(
m.get(1, Timebase::SECONDS).map(|e| e.end()),
Some(Timestamp::new(4, Timebase::SECONDS)),
"the figure is expressed in the timebase the caller names",
);
assert_eq!(m.get(7, ms()), None);
}
#[test]
fn an_end_that_does_not_fit_is_no_end_and_no_walk_is_complete() {
let mut m = Measured::new(2).expect("reserve");
m.observe(0, Some(0), 40);
m.observe(1, Some(i64::MAX - 1), 40);
assert_eq!(m.get(1, ms()), None, "the end is unrepresentable");
m.observe(1, Some(5), 40);
assert_eq!(
m.get(1, ms()),
None,
"a later, smaller packet does not make it representable"
);
m.end_of_file();
assert_eq!(
m.get(0, ms()),
Some(MeasuredEnd::new(at(40), false, true)),
"one track's end is missing, so the walk is not complete for the others",
);
}
#[test]
fn the_largest_end_that_fits_is_still_a_figure() {
let mut m = Measured::new(1).expect("reserve");
m.observe(0, Some(i64::MAX - 40), 40);
assert_eq!(end_of(&m, 0), Some(at(i64::MAX)));
m.end_of_file();
assert!(m.get(0, ms()).expect("measured").walk_complete());
}
#[test]
fn an_end_before_zero_is_still_an_end() {
let mut m = Measured::new(1).expect("reserve");
m.observe(0, Some(-50), 40);
assert_eq!(end_of(&m, 0), Some(at(-10)));
}
#[test]
fn end_of_file_completes_a_walk_that_skipped_nothing() {
let mut m = Measured::new(1).expect("reserve");
m.observe(0, Some(0), 40);
assert!(!m.get(0, ms()).expect("measured").walk_complete());
m.end_of_file();
assert!(m.get(0, ms()).expect("measured").walk_complete());
}
#[test]
fn a_completed_walk_is_frozen() {
let mut m = Measured::new(1).expect("reserve");
m.observe(0, Some(0), 40);
m.end_of_file();
let frozen = m.get(0, ms()).expect("measured");
assert_eq!(frozen, MeasuredEnd::new(at(40), true, true));
m.observe(0, Some(1_000), 40);
assert_eq!(
m.get(0, ms()),
Some(frozen),
"a larger end does not move it"
);
m.observe(0, Some(2_000), 0);
assert_eq!(m.get(0, ms()), Some(frozen), "nor does an unknown duration");
m.observe(0, None, 0);
assert_eq!(
m.get(0, ms()),
Some(frozen),
"nor a packet with no timestamp"
);
m.observe(0, Some(i64::MAX - 1), 40);
assert_eq!(m.get(0, ms()), Some(frozen), "nor an unrepresentable end");
}
#[test]
fn a_seek_after_completion_keeps_the_walk_complete() {
let mut m = Measured::new(1).expect("reserve");
m.observe(0, Some(0), 40);
m.end_of_file();
m.break_walk();
m.observe(0, Some(0), 40);
m.end_of_file();
assert_eq!(m.get(0, ms()), Some(MeasuredEnd::new(at(40), true, true)),);
}
#[test]
fn a_break_before_completion_means_never_complete_and_the_figure_keeps_growing() {
let mut m = Measured::new(1).expect("reserve");
m.observe(0, Some(0), 40);
m.break_walk();
m.observe(0, Some(40), 40);
assert_eq!(
m.get(0, ms()),
Some(MeasuredEnd::new(at(80), false, true)),
"the figure grows after the break",
);
m.end_of_file();
m.observe(0, Some(80), 40);
assert_eq!(
m.get(0, ms()),
Some(MeasuredEnd::new(at(120), false, true)),
"end of file does not complete a broken walk, and the figure keeps growing",
);
}