diff --git a/Cargo.lock b/Cargo.lock index 5fc7219ada..0cbab519a8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2621,6 +2621,7 @@ dependencies = [ "nu-utils", "reedline", "regex", + "rstest 0.12.0", "sysinfo", "thiserror", ] diff --git a/crates/nu-cli/Cargo.toml b/crates/nu-cli/Cargo.toml index 4bd644aac9..ba59974861 100644 --- a/crates/nu-cli/Cargo.toml +++ b/crates/nu-cli/Cargo.toml @@ -9,6 +9,7 @@ version = "0.65.1" [dev-dependencies] nu-test-support = { path="../nu-test-support", version = "0.65.1" } nu-command = { path = "../nu-command", version = "0.65.1" } +rstest = "0.12.0" [dependencies] nu-engine = { path = "../nu-engine", version = "0.65.1" } diff --git a/crates/nu-cli/tests/custom_completions.rs b/crates/nu-cli/tests/custom_completions.rs index fb6dc63625..8f24cbfd4e 100644 --- a/crates/nu-cli/tests/custom_completions.rs +++ b/crates/nu-cli/tests/custom_completions.rs @@ -2,10 +2,24 @@ pub mod support; use nu_cli::NuCompleter; use reedline::Completer; +use rstest::{fixture, rstest}; use support::{match_suggestions, new_engine}; -#[test] -fn variables_completions() { +#[fixture] +fn completer() -> NuCompleter { + // Create a new engine + let (dir, _, mut engine, mut stack) = new_engine(); + + // Add record value as example + let record = "def tst [--mod -s] {}"; + assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack, dir).is_ok()); + + // Instantiate a new completer + NuCompleter::new(std::sync::Arc::new(engine), stack) +} + +#[fixture] +fn completer_strings() -> NuCompleter { // Create a new engine let (dir, _, mut engine, mut stack) = new_engine(); @@ -15,15 +29,41 @@ fn variables_completions() { assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack, dir).is_ok()); // Instantiate a new completer - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + NuCompleter::new(std::sync::Arc::new(engine), stack) +} - // Test completions for $nu - let suggestions = completer.complete("my-command ", 11); - - assert_eq!(3, suggestions.len()); - - let expected: Vec = vec!["cat".into(), "dog".into(), "eel".into()]; - - // Match results +#[rstest] +fn variables_completions_double_dash_argument(mut completer: NuCompleter) { + let suggestions = completer.complete("tst --", 6); + let expected: Vec = vec!["--help".into(), "--mod".into()]; + // dbg!(&expected, &suggestions); + match_suggestions(expected, suggestions); +} + +#[rstest] +fn variables_completions_single_dash_argument(mut completer: NuCompleter) { + let suggestions = completer.complete("tst -", 5); + let expected: Vec = vec!["--help".into(), "--mod".into(), "-h".into(), "-s".into()]; + match_suggestions(expected, suggestions); +} + +#[rstest] +fn variables_completions_command(mut completer_strings: NuCompleter) { + let suggestions = completer_strings.complete("my-command ", 9); + let expected: Vec = vec!["my-command".into()]; + match_suggestions(expected, suggestions); +} + +#[rstest] +fn variables_completions_subcommands(mut completer_strings: NuCompleter) { + let suggestions = completer_strings.complete("my-command ", 11); + let expected: Vec = vec!["cat".into(), "dog".into(), "eel".into()]; + match_suggestions(expected, suggestions); +} + +#[rstest] +fn variables_completions_subcommands_2(mut completer_strings: NuCompleter) { + let suggestions = completer_strings.complete("my-command ", 11); + let expected: Vec = vec!["cat".into(), "dog".into(), "eel".into()]; match_suggestions(expected, suggestions); } diff --git a/crates/nu-cli/tests/file_completions.rs b/crates/nu-cli/tests/file_completions.rs index 6e36063637..ac7d909886 100644 --- a/crates/nu-cli/tests/file_completions.rs +++ b/crates/nu-cli/tests/file_completions.rs @@ -30,8 +30,8 @@ fn file_completions() { // Match the results match_suggestions(expected_paths, suggestions); - // Test completions for the completions/another folder - let target_dir = format!("cd {}", folder(dir.join("another"))); + // Test completions for a file + let target_dir = format!("cp {}", folder(dir.join("another"))); let suggestions = completer.complete(&target_dir, target_dir.len()); // Create the expected values diff --git a/crates/nu-cli/tests/support/completions_helpers.rs b/crates/nu-cli/tests/support/completions_helpers.rs index a4e7ab641d..f774dd3f1d 100644 --- a/crates/nu-cli/tests/support/completions_helpers.rs +++ b/crates/nu-cli/tests/support/completions_helpers.rs @@ -59,6 +59,15 @@ pub fn new_engine() -> (PathBuf, String, EngineState, Stack) { // match a list of suggestions with the expected values pub fn match_suggestions(expected: Vec, suggestions: Vec) { + let expected_len = expected.len(); + let suggestions_len = suggestions.len(); + if expected_len != suggestions_len { + panic!( + "\nexpected {expected_len} suggestions but got {suggestions_len}: \n\ + Suggestions: {suggestions:#?} \n\ + Expected: {expected:#?}\n" + ) + } expected.iter().zip(suggestions).for_each(|it| { assert_eq!(it.0, &it.1.value); }); diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index 46c842beba..29a675ae43 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -791,7 +791,18 @@ pub fn parse_internal_call( &signature, ); - if let Some(short_flags) = short_flags { + if let Some(mut short_flags) = short_flags { + if short_flags.is_empty() { + short_flags.push(Flag { + long: "".to_string(), + short: Some('a'), + arg: None, + required: false, + desc: "".to_string(), + var_id: None, + default_value: None, + }) + } error = error.or(err); for flag in short_flags { if let Some(arg_shape) = flag.arg {