test(plot): region removal re-indexes the ids and the statistics cache
This commit is contained in:
1 parent
5e610bc138
commit
4e0e0ae0b3
1 file changed
+51
@@ -1590,3 +1590,54 @@ PLOT_TEST(region_stats_track_a_sliding_streaming_window) {
|
|||||||
PLOT_CHECK_NEAR(step.mean, 0.5 * (step.min + 60.0), 1e-9);
|
PLOT_CHECK_NEAR(step.mean, 0.5 * (step.min + 60.0), 1e-9);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Region ids are vector indices, so removing one shifts every id above it -- and the
|
||||||
|
/// statistics cache is keyed by that index, so it has to be re-indexed with the vector
|
||||||
|
/// rather than left naming the regions it was filled for. A stale key here would answer
|
||||||
|
/// for a *different* interval than the one asked about, which a count alone cannot see:
|
||||||
|
/// the three intervals below are all 11 samples wide, so these assertions are about the
|
||||||
|
/// extremes each id actually names.
|
||||||
|
PLOT_TEST(removing_a_region_shifts_the_ids_and_keeps_the_statistics) {
|
||||||
|
plot::data::ArraySeries s(ramp(100), 0.0, 1.0);
|
||||||
|
plot::Plot p;
|
||||||
|
p.set_viewport({0.0f, 0.0f, 800.0f, 400.0f});
|
||||||
|
const u32 ax = p.add_x_axis({"t", {0.0, 99.0}, false, plot::AxisPlace::Bottom, false});
|
||||||
|
const u32 ay = p.add_y_axis({"v", {0.0, 99.0}, false, plot::AxisPlace::Left, false});
|
||||||
|
const u32 tr = p.add_trace({&s, plot::Color::hex(0xFFFFFF), 1.0f, ax, ay});
|
||||||
|
|
||||||
|
plot::Region bounds;
|
||||||
|
bounds.snap = plot::RegionSnap::Free; // the intervals under test are these numbers
|
||||||
|
bounds.x0 = 10.0;
|
||||||
|
bounds.x1 = 20.0;
|
||||||
|
const u32 a = p.add_region(bounds);
|
||||||
|
bounds.x0 = 30.0;
|
||||||
|
bounds.x1 = 40.0;
|
||||||
|
const u32 b = p.add_region(bounds);
|
||||||
|
bounds.x0 = 50.0;
|
||||||
|
bounds.x1 = 60.0;
|
||||||
|
const u32 c = p.add_region(bounds);
|
||||||
|
PLOT_CHECK(a == 0u && b == 1u && c == 2u);
|
||||||
|
PLOT_CHECK(p.region_count() == 3u);
|
||||||
|
// Filled on demand, in the order the caller asks: three entries, one per pair.
|
||||||
|
PLOT_CHECK_NEAR(p.region_stats(a, tr).min, 10.0, 1e-9);
|
||||||
|
PLOT_CHECK_NEAR(p.region_stats(b, tr).min, 30.0, 1e-9);
|
||||||
|
PLOT_CHECK_NEAR(p.region_stats(c, tr).min, 50.0, 1e-9);
|
||||||
|
|
||||||
|
p.remove_region(a);
|
||||||
|
PLOT_CHECK(p.region_count() == 2u);
|
||||||
|
PLOT_CHECK_NEAR(p.region(0).x0, 30.0, 1e-12); // the old region 1
|
||||||
|
PLOT_CHECK_NEAR(p.region(1).x0, 50.0, 1e-12); // the old region 2
|
||||||
|
// The surviving entries follow their regions down, so each id still answers for its own
|
||||||
|
// interval rather than for the one that used to hold that index.
|
||||||
|
PLOT_CHECK_NEAR(p.region_stats(0u, tr).min, 30.0, 1e-9);
|
||||||
|
PLOT_CHECK_NEAR(p.region_stats(0u, tr).max, 40.0, 1e-9);
|
||||||
|
PLOT_CHECK_NEAR(p.region_stats(1u, tr).min, 50.0, 1e-9);
|
||||||
|
PLOT_CHECK_NEAR(p.region_stats(1u, tr).max, 60.0, 1e-9);
|
||||||
|
// The id the removed region held now names the region that shifted into it -- there is
|
||||||
|
// no hole in the vector -- and an id past the end names nothing and reads a default
|
||||||
|
// rather than out of range. Neither has any statistics.
|
||||||
|
PLOT_CHECK_NEAR(p.region(0u).x0, 30.0, 1e-12);
|
||||||
|
PLOT_CHECK_NEAR(p.region(2u).x0, 0.0, 1e-12);
|
||||||
|
PLOT_CHECK(!p.region_stats(2u, tr).valid);
|
||||||
|
PLOT_CHECK(!p.region_stats(9u, tr).valid);
|
||||||
|
}
|
||||||
Reference in new issue
Block a user