use rand::prelude::*;
use rand_chacha::ChaCha12Rng;
use requestty::question::Choice;
use ui::events::{KeyCode, KeyEvent, TestEvents};
mod helpers;
const SEED: u64 = 9828123;
const SEP_RATIO: f32 = 0.3;
const DEFAULT_SEP_RATIO: f32 = 0.10;
fn choices(len: usize) -> impl Iterator<Item = Choice<String>> {
let mut rng = ChaCha12Rng::seed_from_u64(SEED);
(0..len).map(move |i| {
let rand: f32 = rng.gen();
if rand < DEFAULT_SEP_RATIO {
Choice::DefaultSeparator
} else if rand < SEP_RATIO {
Choice::Separator(format!("Separator {}", i))
} else {
Choice::Choice(format!("Choice {}", i))
}
})
}
#[test]
fn test_validate() {
let multi_select = requestty::Question::multi_select("name")
.validate(|checked, _| {
let count = checked.iter().filter(|&&b| b).count();
if count > 1 {
Ok(())
} else {
Err(format!(
"At least 2 items must be checked. {} items were checked",
count
))
}
})
.message("multi select")
.choices(choices(10));
let size = (50, 20).into();
let mut backend = helpers::SnapshotOnFlushBackend::new(size);
let mut events = TestEvents::new(vec![
KeyEvent::from(KeyCode::Down),
KeyCode::Char(' ').into(),
KeyCode::Enter.into(),
KeyCode::End.into(),
KeyCode::Char(' ').into(),
KeyCode::Enter.into(),
]);
let ans: Vec<_> = requestty::prompt_one_with(multi_select, &mut backend, &mut events)
.unwrap()
.try_into_list_items()
.unwrap()
.into_iter()
.map(|item| item.index)
.collect();
assert_eq!(ans, [3, 9]);
}
#[test]
fn test_filter() {
let multi_select = requestty::Question::multi_select("name")
.filter(|mut checked, _| {
checked.iter_mut().for_each(|b| *b = !*b);
checked
})
.message("multi select")
.choices(choices(10));
let size = (50, 20).into();
let mut backend = helpers::SnapshotOnFlushBackend::new(size);
let mut events = TestEvents::new(vec![
KeyEvent::from(KeyCode::Down),
KeyCode::Char(' ').into(),
KeyCode::End.into(),
KeyCode::Char(' ').into(),
KeyCode::Enter.into(),
]);
let ans: Vec<_> = requestty::prompt_one_with(multi_select, &mut backend, &mut events)
.unwrap()
.try_into_list_items()
.unwrap()
.into_iter()
.map(|item| item.index)
.collect();
assert_eq!(ans, [0, 4, 6, 7, 8]);
}
#[test]
fn test_transform() {
let multi_select = requestty::Question::multi_select("name")
.transform(|items, _, b| {
b.set_fg(ui::style::Color::Magenta)?;
for (i, item) in items.iter().enumerate() {
write!(b, "{}: {}", item.index, item.text)?;
if i + 1 != items.len() {
write!(b, ", ")?;
}
}
b.set_fg(ui::style::Color::Reset)
})
.message("multi select")
.choices(choices(10));
let size = (50, 20).into();
let mut backend = helpers::SnapshotOnFlushBackend::new(size);
let mut events = TestEvents::new(vec![
KeyEvent::from(KeyCode::Down),
KeyCode::Char(' ').into(),
KeyCode::End.into(),
KeyCode::Char(' ').into(),
KeyCode::Enter.into(),
]);
let ans: Vec<_> = requestty::prompt_one_with(multi_select, &mut backend, &mut events)
.unwrap()
.try_into_list_items()
.unwrap()
.into_iter()
.map(|item| item.index)
.collect();
assert_eq!(ans, [3, 9]);
}
#[test]
fn test_on_esc() {
let size = (50, 20).into();
let mut backend = helpers::SnapshotOnFlushBackend::new(size);
let mut events = TestEvents::new(Some(KeyCode::Esc.into()));
let res = requestty::prompt_one_with(
requestty::Question::multi_select("name")
.message("message")
.choices(choices(10))
.on_esc(requestty::OnEsc::Terminate),
&mut backend,
&mut events,
);
assert!(matches!(res, Err(requestty::ErrorKind::Aborted)));
let size = (50, 20).into();
let mut backend = helpers::SnapshotOnFlushBackend::new(size);
let mut events = TestEvents::new(Some(KeyCode::Esc.into()));
let res = requestty::prompt_with(
Some(
requestty::Question::multi_select("name")
.message("message")
.choices(choices(10))
.on_esc(requestty::OnEsc::SkipQuestion)
.build(),
),
&mut backend,
&mut events,
)
.unwrap();
assert!(res.is_empty());
}