2026-04-21 17:55:26 -03:00
|
|
|
//! Contract tests for the launcher layout proportions.
|
|
|
|
|
//!
|
|
|
|
|
//! Scope: statically guard the GTK layout constants and sizing glue used by
|
|
|
|
|
//! the launcher shell.
|
|
|
|
|
//! Targets: `client/src/launcher/ui_components.rs`.
|
|
|
|
|
//! Why: the launcher is an operational control surface; accidental spacing
|
|
|
|
|
//! regressions can hide diagnostics or make eye/device previews unusable.
|
|
|
|
|
|
|
|
|
|
const UI_SRC: &str = include_str!("../../client/src/launcher/ui_components.rs");
|
|
|
|
|
|
|
|
|
|
fn const_i32(name: &str) -> i32 {
|
|
|
|
|
let needle = format!("const {name}: i32 = ");
|
|
|
|
|
let line = UI_SRC
|
|
|
|
|
.lines()
|
|
|
|
|
.find(|line| line.trim_start().starts_with(&needle))
|
|
|
|
|
.unwrap_or_else(|| panic!("missing {name} constant"));
|
|
|
|
|
line.trim_start()
|
|
|
|
|
.trim_start_matches(&needle)
|
|
|
|
|
.trim_end_matches(';')
|
|
|
|
|
.parse()
|
|
|
|
|
.unwrap_or_else(|err| panic!("invalid {name} constant: {err}"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn launcher_default_size_stays_inside_1080p() {
|
|
|
|
|
assert_eq!(const_i32("LAUNCHER_DEFAULT_WIDTH"), 1360);
|
|
|
|
|
assert_eq!(const_i32("LAUNCHER_DEFAULT_HEIGHT"), 820);
|
|
|
|
|
assert!(const_i32("LAUNCHER_DEFAULT_WIDTH") <= 1920);
|
|
|
|
|
assert!(const_i32("LAUNCHER_DEFAULT_HEIGHT") <= 1080);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn eye_panes_keep_the_locked_larger_preview_footprint() {
|
|
|
|
|
assert_eq!(const_i32("EYE_PREVIEW_MIN_WIDTH"), 460);
|
|
|
|
|
assert_eq!(const_i32("EYE_PREVIEW_MIN_HEIGHT"), 258);
|
|
|
|
|
assert!(
|
|
|
|
|
UI_SRC.contains("caption_label.set_halign(gtk::Align::End)")
|
|
|
|
|
|| UI_SRC.contains("capture_label.set_halign(gtk::Align::End)")
|
|
|
|
|
);
|
|
|
|
|
assert!(UI_SRC.contains("capture_label.set_ellipsize(pango::EllipsizeMode::Start);"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn device_staging_and_testing_bottoms_stay_locked_together() {
|
|
|
|
|
assert!(UI_SRC.contains("staging_row.set_homogeneous(true);"));
|
|
|
|
|
assert!(UI_SRC.contains("devices_panel.set_valign(gtk::Align::Fill);"));
|
|
|
|
|
assert!(UI_SRC.contains("preview_panel.set_valign(gtk::Align::Fill);"));
|
|
|
|
|
assert!(UI_SRC.contains(
|
|
|
|
|
"let device_body_height_group = gtk::SizeGroup::new(gtk::SizeGroupMode::Vertical);"
|
|
|
|
|
));
|
|
|
|
|
assert!(UI_SRC.contains("device_body_height_group.add_widget(&devices_body);"));
|
|
|
|
|
assert!(UI_SRC.contains("device_body_height_group.add_widget(&testing_row);"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn device_testing_keeps_webcam_and_mic_playback_as_equal_bottom_columns() {
|
|
|
|
|
assert_eq!(const_i32("CAMERA_PREVIEW_VIEWPORT_WIDTH"), 280);
|
|
|
|
|
assert_eq!(const_i32("CAMERA_PREVIEW_VIEWPORT_HEIGHT"), 158);
|
|
|
|
|
assert!(UI_SRC.contains("webcam_group.set_valign(gtk::Align::Fill);"));
|
|
|
|
|
assert!(UI_SRC.contains("playback_group.set_valign(gtk::Align::Fill);"));
|
|
|
|
|
assert!(UI_SRC.contains("playback_body.set_valign(gtk::Align::Fill);"));
|
|
|
|
|
assert!(UI_SRC.contains("audio_check_meter.set_vexpand(true);"));
|
|
|
|
|
assert!(UI_SRC.contains("playback_body.append(&audio_check_meter);"));
|
|
|
|
|
assert!(UI_SRC.contains("playback_body.append(µphone_replay_button);"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn operations_column_fills_height_and_splits_extra_space_between_logs() {
|
|
|
|
|
assert_eq!(const_i32("SIDE_LOG_HEIGHT"), 124);
|
|
|
|
|
assert!(UI_SRC.contains("operations.set_vexpand(true);"));
|
|
|
|
|
assert!(UI_SRC.contains("operations.set_valign(gtk::Align::Fill);"));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
UI_SRC
|
|
|
|
|
.matches(".min_content_height(SIDE_LOG_HEIGHT)")
|
|
|
|
|
.count(),
|
|
|
|
|
2
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
UI_SRC
|
|
|
|
|
.matches(".max_content_height(SIDE_LOG_HEIGHT)")
|
|
|
|
|
.count(),
|
|
|
|
|
2
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-04-21 20:19:47 -03:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn remote_audio_gain_control_stays_in_the_operations_rail() {
|
|
|
|
|
assert!(UI_SRC.contains("let audio_heading = gtk::Label::new(Some(\"Remote Audio\"));"));
|
|
|
|
|
assert!(UI_SRC.contains("let audio_gain_scale ="));
|
|
|
|
|
assert!(UI_SRC.contains("audio_gain_scale.set_draw_value(false);"));
|
|
|
|
|
assert!(UI_SRC.contains("audio_gain_value.set_width_chars(5);"));
|
|
|
|
|
assert!(UI_SRC.contains("connection_body.append(&audio_gain_row);"));
|
|
|
|
|
}
|