feat: Add new system for multi-selections.
This commit is contained in:
@@ -92,12 +92,15 @@ fn gen_headless(case: &TestCase, fixtures: &Fixtures) -> syn::Result<TokenStream
|
||||
// Build script string from actions
|
||||
let script = build_headless_script(&case.actions);
|
||||
|
||||
// Build extra CLI args (e.g. --label-key)
|
||||
let extra_args: Vec<TokenStream> = if let Some(ref key) = fixtures.label_key {
|
||||
vec![quote! { "--label-key" }, quote! { #key }]
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
// Build extra CLI args (e.g. --label-key, --multi)
|
||||
let mut extra_args: Vec<TokenStream> = Vec::new();
|
||||
if let Some(ref key) = fixtures.label_key {
|
||||
extra_args.push(quote! { "--label-key" });
|
||||
extra_args.push(quote! { #key });
|
||||
}
|
||||
if fixtures.multi == Some(true) {
|
||||
extra_args.push(quote! { "--multi" });
|
||||
}
|
||||
|
||||
// Build assertions
|
||||
let mut asserts = Vec::new();
|
||||
@@ -327,7 +330,9 @@ fn gen_menu(case: &TestCase, fixtures: &Fixtures) -> syn::Result<TokenStream> {
|
||||
} else if let Some(ref expected) = case.selected {
|
||||
quote! {
|
||||
match &result {
|
||||
Ok(MenuResult::Selected { value, .. }) => {
|
||||
Ok(MenuResult::Selected { items, .. }) => {
|
||||
assert!(!items.is_empty(), "expected Selected with items, got empty");
|
||||
let value = &items[0].0;
|
||||
let got = value.as_str()
|
||||
.or_else(|| value.get(#label_key).and_then(|v| v.as_str()))
|
||||
.unwrap_or("");
|
||||
@@ -339,6 +344,25 @@ fn gen_menu(case: &TestCase, fixtures: &Fixtures) -> syn::Result<TokenStream> {
|
||||
other => panic!("expected Selected, got: {:?}", other),
|
||||
}
|
||||
}
|
||||
} else if let Some(ref expected) = case.selected_items {
|
||||
quote! {
|
||||
match &result {
|
||||
Ok(MenuResult::Selected { items, .. }) => {
|
||||
let mut labels: Vec<&str> = items.iter()
|
||||
.filter_map(|(v, _)| v.as_str()
|
||||
.or_else(|| v.get(#label_key).and_then(|v| v.as_str())))
|
||||
.collect();
|
||||
labels.sort();
|
||||
let mut expected = vec![#(#expected),*];
|
||||
expected.sort();
|
||||
assert_eq!(
|
||||
labels, expected,
|
||||
"expected selected_items {:?}, got {:?}", expected, labels
|
||||
);
|
||||
}
|
||||
other => panic!("expected Selected, got: {:?}", other),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No assertion on result. Probably an error, but let it compile.
|
||||
quote! {}
|
||||
@@ -348,11 +372,18 @@ fn gen_menu(case: &TestCase, fixtures: &Fixtures) -> syn::Result<TokenStream> {
|
||||
// we need to drop tx after sending actions.
|
||||
let drop_sender = quote! { drop(tx); };
|
||||
|
||||
let multi_setup = if fixtures.multi == Some(true) {
|
||||
quote! { menu.set_multi(true); }
|
||||
} else {
|
||||
quote! {}
|
||||
};
|
||||
|
||||
Ok(quote! {
|
||||
#[tokio::test]
|
||||
async fn #test_name() {
|
||||
let items = vec![#(#item_exprs),*];
|
||||
let (menu, tx) = MenuRunner::new(JsonMenu::new(items, #label_key.to_string()));
|
||||
let (mut menu, tx) = MenuRunner::new(JsonMenu::new(items, #label_key.to_string()));
|
||||
#multi_setup
|
||||
let mut rx = menu.subscribe();
|
||||
let handle = tokio::spawn(async move { menu.run().await });
|
||||
|
||||
@@ -427,6 +458,12 @@ fn menu_action_variant(name: &str) -> syn::Result<TokenStream> {
|
||||
"half-page-down" => quote! { Action::HalfPageDown(1) },
|
||||
"set-mode-insert" => quote! { Action::SetMode(pikl_core::event::Mode::Insert) },
|
||||
"set-mode-normal" => quote! { Action::SetMode(pikl_core::event::Mode::Normal) },
|
||||
"set-mode-visual" => quote! { Action::SetMode(pikl_core::event::Mode::Visual) },
|
||||
"toggle-select" => quote! { Action::ToggleSelect },
|
||||
"select-all" => quote! { Action::SelectAll },
|
||||
"clear-selections" => quote! { Action::ClearSelections },
|
||||
"undo-selection" => quote! { Action::UndoSelection },
|
||||
"redo-selection" => quote! { Action::RedoSelection },
|
||||
_ => {
|
||||
return Err(syn::Error::new(
|
||||
Span::call_site(),
|
||||
|
||||
Reference in New Issue
Block a user