1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//! Shared helpers for the headless integration tests: a no-op paths provider and a minimal real app that fills its whole window with one solid color.
// Each test binary compiles this module whole but uses only the helpers it needs.
#![allow(dead_code)]
use telar::{
App, Color, Component, LayoutStyle, RectStyle, Rectangle, SizeDimension, WindowRoot,
reset_layout_runtime,
};
fn fill_root(color: Color) -> Box<dyn Component> {
let rect = Rectangle::new(
LayoutStyle::new()
.width(SizeDimension::Percent(1.0))
.height(SizeDimension::Percent(1.0)),
move || RectStyle::filled(color, 0.0),
)
.unwrap();
Box::new(WindowRoot::new(Box::new(rect)))
}
/// A real rsx app whose window is entirely one solid color.
pub struct FillApp {
pub color: Color,
}
impl App for FillApp {
fn root(&self) -> Box<dyn Component> {
reset_layout_runtime();
fill_root(self.color)
}
fn clear_color(&self) -> Option<Color> {
Some(Color::rgba(0.0, 0.0, 0.0, 1.0))
}
}
/// A fill app that can be told to panic during build, to exercise the multi-surface panic quarantine (T-4.2): a surface whose build panics must unmount without tumbling the other surfaces.
pub struct MaybePanicApp {
pub color: Color,
pub panic_on_build: bool,
}
impl App for MaybePanicApp {
fn root(&self) -> Box<dyn Component> {
assert!(
!self.panic_on_build,
"MaybePanicApp: intentional build panic"
);
reset_layout_runtime();
fill_root(self.color)
}
fn clear_color(&self) -> Option<Color> {
Some(Color::rgba(0.0, 0.0, 0.0, 1.0))
}
}
/// Assert the center pixel of a `w`×`h` premultiplied-RGBA8 buffer matches `expected` (R, G, B) within a small tolerance, and is not the black clear color.
pub fn assert_center_rgb(pixels: &[u8], w: u32, h: u32, expected: [u8; 3], label: &str) {
assert_eq!(
pixels.len(),
(w * h * 4) as usize,
"{label}: read-back must be width*height*4"
);
let center = (((h / 2) * w + (w / 2)) * 4) as usize;
let px = &pixels[center..center + 4];
for c in 0..3 {
assert!(
(px[c] as i32 - expected[c] as i32).abs() <= 4,
"{label} channel {c}: got {} expected ~{} (pixel {px:?})",
px[c],
expected[c],
);
}
assert_ne!(
&px[0..3],
&[0u8, 0, 0],
"{label}: fill did not paint over clear"
);
}
/// Reports that a GPU test is skipping for want of an adapter — and fails instead when `TELAR_REQUIRE_GPU` is set.
///
/// CI sets it on the leg that installs lavapipe, so a suite that quietly stopped covering the GPU reads as red there rather than as passing tests that never ran. Everywhere else the absence is a real answer and the test skips.
pub fn skip_without_gpu(what: &str) {
telar::testing::require_gpu(what, "no adapter");
}