Skip to content

Commit af87f3a

Browse files
kitizzmichalsustr
andauthored
Add initial auto_bounds test for Plot (#220)
Includes the following changes: - Add `egui_kittest`, `log`, `env_logger`, `assertables` as dev-dependencies to egui_plot crate - Add test-only `init_test_logger` function to enable capturing `log::info!` and friends in tests - Add tests for basic auto_bounds behavior to be an example for additional test cases <!-- Please read the "Making a PR" section of [`CONTRIBUTING.md`](https://github.com/emilk/egui_plot/blob/master/CONTRIBUTING.md) before opening a Pull Request! * Keep your PR:s small and focused. * The PR title is what ends up in the changelog, so make it descriptive! * If applicable, add a screenshot or gif. * If it is a non-trivial addition, consider adding a demo f or a new example. * Do NOT open PR:s from your `master` or `main` branch, as that makes it hard for maintainers to test and add commits to your PR. * Remember to run `cargo fmt` and `cargo clippy`. * Open the PR as a draft until you have self-reviewed it and run `./scripts/check.sh`. * When you have addressed a PR comment, mark it as resolved. Please be patient! We will review your PR, but our time is limited! --> * Closes <#219> * [x] I have followed the instructions in the PR template --------- Co-authored-by: Michal Sustr <michal.sustr@gmail.com>
1 parent f70ac43 commit af87f3a

5 files changed

Lines changed: 98 additions & 0 deletions

File tree

Cargo.lock

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,12 @@ dependencies = [
303303
"zbus",
304304
]
305305

306+
[[package]]
307+
name = "assertables"
308+
version = "9.8.2"
309+
source = "registry+https://github.com/rust-lang/crates.io-index"
310+
checksum = "59051ec02907378a67b0ba1b8631121f5388c8dbbb3cec8c749d8f93c2c3c211"
311+
306312
[[package]]
307313
name = "async-broadcast"
308314
version = "0.7.2"
@@ -1192,9 +1198,13 @@ name = "egui_plot"
11921198
version = "0.34.0"
11931199
dependencies = [
11941200
"ahash",
1201+
"assertables",
11951202
"document-features",
11961203
"egui",
1204+
"egui_kittest",
11971205
"emath",
1206+
"env_logger",
1207+
"log",
11981208
"serde",
11991209
]
12001210

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ ahash = { version = "0.8.12", default-features = false, features = [
4545
"no-rng", # we don't need DOS-protection, so we let users opt-in to it instead
4646
"std",
4747
] }
48+
assertables = "9.8.2"
4849
document-features = "0.2.12"
4950
eframe = { version = "0.33", default-features = false }
5051
egui = { version = "0.33", default-features = false }
@@ -279,3 +280,7 @@ zero_sized_map_values = "warn"
279280

280281
manual_range_contains = "allow" # this is better on 'allow'
281282
map_unwrap_or = "allow" # this is better on 'allow'
283+
284+
285+
[workspace.metadata.cargo-shear]
286+
ignored = ["log", "assertables"]

egui_plot/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,9 @@ ahash.workspace = true
4545
document-features = { workspace = true, optional = true }
4646

4747
serde = { workspace = true, optional = true }
48+
49+
[dev-dependencies]
50+
assertables.workspace = true
51+
egui_kittest.workspace = true
52+
env_logger.workspace = true
53+
log.workspace = true

egui_plot/src/plot.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2124,3 +2124,44 @@ impl<'a> PlotUi<'a> {
21242124
self.items.push(Box::new(heatmap));
21252125
}
21262126
}
2127+
2128+
#[cfg(all(test, not(target_arch = "wasm32")))]
2129+
mod plot_tests {
2130+
use super::*;
2131+
use crate::{Plot, Points};
2132+
2133+
use egui_kittest::Harness;
2134+
2135+
/// Test that `auto_bounds(true)` fits the data exactly when the margin fraction is zero.
2136+
#[test]
2137+
fn auto_bounds_true() {
2138+
crate::utils::init_test_logger();
2139+
2140+
const MIN: [f64; 2] = [-10.0, -10.0];
2141+
const MAX: [f64; 2] = [10.0, 10.0];
2142+
2143+
let harness = {
2144+
let bounds = PlotBounds::from_min_max(MIN, MAX);
2145+
Harness::new_ui_state(
2146+
|ui, bounds| {
2147+
let plot = Plot::new("test_plot")
2148+
.auto_bounds(true)
2149+
.set_margin_fraction(Vec2::splat(0.0));
2150+
2151+
plot.show(ui, |plot_ui| {
2152+
let corners = vec![MIN, MAX];
2153+
plot_ui.points(Points::new("filler", corners));
2154+
*bounds = plot_ui.plot_bounds();
2155+
});
2156+
},
2157+
bounds,
2158+
)
2159+
};
2160+
2161+
let final_bounds = harness.state();
2162+
assert!((final_bounds.min[0] - MIN[0]).abs() <= f64::EPSILON);
2163+
assert!((final_bounds.min[1] - MIN[1]).abs() <= f64::EPSILON);
2164+
assert!((final_bounds.max[0] - MAX[0]).abs() <= f64::EPSILON);
2165+
assert!((final_bounds.max[1] - MAX[1]).abs() <= f64::EPSILON);
2166+
}
2167+
}

egui_plot/src/utils.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,39 @@ pub(crate) fn find_name_candidate(name: &str, width: f32, painter: &Painter, fon
5656

5757
best
5858
}
59+
60+
/// Initialize logging so that the testing framework can capture log output.
61+
///
62+
/// Call this at the top of a test function to see log output from that test.
63+
/// The logging output will only be shown when the following conditions are met:
64+
/// - The test fails
65+
/// - The `RUST_LOG` environment variable is set to a level at or below the message level
66+
///
67+
/// When running a specific test:
68+
/// ```sh
69+
/// RUST_LOG=info cargo test auto_bounds_true
70+
/// ```
71+
///
72+
/// If the something causes the test to panic so hard that it never shows logging output,
73+
/// you can use `--nocapture` to see log output as it happens:
74+
/// ```sh
75+
/// RUST_LOG=info cargo test auto_bounds_true -- --nocapture
76+
/// ```
77+
#[cfg(test)]
78+
pub(crate) fn init_test_logger() {
79+
use std::io::Write as _;
80+
let _result: Result<(), log::SetLoggerError> = env_logger::builder()
81+
.is_test(true)
82+
.format(|buf, record| {
83+
let level_style = buf.default_level_style(record.level());
84+
writeln!(
85+
buf,
86+
"[{level_style}{}{level_style:#} {}:{}] {}",
87+
record.level(),
88+
record.file().unwrap_or("unknown"),
89+
record.line().unwrap_or(0),
90+
record.args()
91+
)
92+
})
93+
.try_init();
94+
}

0 commit comments

Comments
 (0)