use par_term_config::Config;
use super::harvest::harvest_tab;
use super::registry::SectionEntry;
use crate::settings_ui::SettingsUI;
use crate::sidebar::SettingsTab;
fn harvest(tab: SettingsTab) -> Vec<SectionEntry> {
let mut settings = SettingsUI::new_for_tests(Config::default());
harvest_tab(&mut settings, tab)
}
fn find<'a>(sections: &'a [SectionEntry], title: &str) -> &'a SectionEntry {
sections
.iter()
.find(|s| s.title == title)
.unwrap_or_else(|| {
panic!(
"no section {title:?}; have {:?}",
sections.iter().map(|s| &s.title).collect::<Vec<_>>()
)
})
}
#[test]
fn cursor_blink_lands_in_appearance_cursor() {
let sections = harvest(SettingsTab::Appearance);
let cursor = find(§ions, "Cursor");
assert!(
cursor.controls.iter().any(|c| c.label == "Cursor blink"),
"no Cursor blink; have {:#?}",
cursor.controls
);
}
#[test]
fn a_tooltip_is_attached_to_its_own_control() {
let sections = harvest(SettingsTab::WindowsAndTabs);
let display = find(§ions, "Display");
let allow = display
.controls
.iter()
.find(|c| c.label == "Allow apps to change window title")
.unwrap_or_else(|| panic!("no control; have {:#?}", display.controls));
assert!(
allow
.extra
.iter()
.any(|t| t.contains("OSC escape sequences")),
"tooltip not attached: {allow:?}"
);
}
#[test]
fn a_slider_value_and_unit_are_never_indexed() {
let sections = harvest(SettingsTab::WindowsAndTabs);
let display = find(§ions, "Display");
for control in &display.controls {
for text in std::iter::once(&control.label).chain(&control.extra) {
assert!(
!text.ends_with(" columns") && !text.ends_with(" px"),
"a value leaked into the index: {control:?}"
);
}
}
}
#[test]
fn option_key_combo_carries_meta_from_its_popup() {
let sections = harvest(SettingsTab::Keys);
let keyboard = find(§ions, "Keyboard");
let meta = keyboard
.controls
.iter()
.any(|c| c.extra.iter().any(|t| t == "Meta") || c.label == "Meta");
assert!(meta, "no Meta option: {:#?}", keyboard.controls);
}
#[test]
fn every_tab_harvests_in_reasonable_time() {
let mut settings = SettingsUI::new_for_tests(Config::default());
let started = std::time::Instant::now();
let mut counts = Vec::new();
for tab in SettingsTab::all() {
let sections = harvest_tab(&mut settings, *tab);
let controls: usize = sections.iter().map(|s| s.controls.len()).sum();
counts.push((*tab, sections.len(), controls));
}
let elapsed = started.elapsed();
eprintln!("harvest: {elapsed:?} {counts:?}");
for (tab, sections, controls) in &counts {
assert!(*sections > 0 && *controls > 0, "{tab:?} harvested nothing");
}
}
#[test]
fn a_nested_section_gets_its_ancestors_page() {
let entry = |id: &str, parent: Option<usize>| SectionEntry {
id: id.to_string(),
parent,
..Default::default()
};
let mut sections = vec![
entry("grandchild", Some(1)),
entry("child", Some(2)),
entry("outer", None),
];
super::harvest::assign_pages(&mut sections, |id| (id == "outer").then_some(2));
assert_eq!(
sections.iter().map(|s| s.page).collect::<Vec<_>>(),
[2, 2, 2]
);
}
#[test]
fn nested_sections_share_their_parents_page() {
let mut config = Config::default();
config.shader.custom_shader = Some("variant.glsl".to_string());
config.shader.cursor_shader = Some("variant_cursor.glsl".to_string());
let mut settings = SettingsUI::new_for_tests(config);
settings.temp_custom_shader = "variant.glsl".to_string();
settings.temp_cursor_shader = "variant_cursor.glsl".to_string();
settings.collapsed_sections.clear();
let mut nested = 0;
for tab in SettingsTab::all() {
let sections = harvest_tab(&mut settings, *tab);
for section in §ions {
if let Some(p) = section.parent {
nested += 1;
assert_eq!(
(section.tab, section.page),
(sections[p].tab, sections[p].page),
"{} is not on its parent {}'s page",
section.id,
sections[p].id
);
}
}
}
assert!(nested > 0, "no nested section was harvested");
}