nu-cli/completions: add custom completion test (#5543)

This commit is contained in:
Herlon Aguiar 2022-05-14 22:09:41 +02:00 committed by GitHub
parent 16bd7b6d0d
commit c047fd4778
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 80 additions and 46 deletions

View File

@ -0,0 +1,29 @@
pub mod support;
use nu_cli::NuCompleter;
use reedline::Completer;
use support::{match_suggestions, new_engine};
#[test]
fn variables_completions() {
// Create a new engine
let (dir, _, mut engine, mut stack) = new_engine();
// Add record value as example
let record = r#"def animals [] { ["cat", "dog", "eel" ] }
def my-command [animal: string@animals] { print $animal }"#;
assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack, dir).is_ok());
// Instatiate a new completer
let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack);
// Test completions for $nu
let suggestions = completer.complete("my-command ".into(), 11);
assert_eq!(3, suggestions.len());
let expected: Vec<String> = vec!["cat".into(), "dog".into(), "eel".into()];
// Match results
match_suggestions(expected, suggestions);
}

View File

@ -1,4 +1,4 @@
mod support; pub mod support;
use nu_cli::NuCompleter; use nu_cli::NuCompleter;
use reedline::Completer; use reedline::Completer;
@ -17,12 +17,12 @@ fn dotnu_completions() {
let suggestions = completer.complete(&completion_str, completion_str.len()); let suggestions = completer.complete(&completion_str, completion_str.len());
assert_eq!(1, suggestions.len()); assert_eq!(1, suggestions.len());
assert_eq!("test_dotnu.nu", suggestions.get(0).unwrap().value); assert_eq!("custom_completion.nu", suggestions.get(0).unwrap().value);
// Test use completion // Test use completion
let completion_str = "use ".to_string(); let completion_str = "use ".to_string();
let suggestions = completer.complete(&completion_str, completion_str.len()); let suggestions = completer.complete(&completion_str, completion_str.len());
assert_eq!(1, suggestions.len()); assert_eq!(1, suggestions.len());
assert_eq!("test_dotnu.nu", suggestions.get(0).unwrap().value); assert_eq!("custom_completion.nu", suggestions.get(0).unwrap().value);
} }

View File

@ -1,4 +1,4 @@
mod support; pub mod support;
use nu_cli::NuCompleter; use nu_cli::NuCompleter;
use reedline::Completer; use reedline::Completer;
@ -22,7 +22,7 @@ fn file_completions() {
folder(dir.join("test_a")), folder(dir.join("test_a")),
folder(dir.join("test_b")), folder(dir.join("test_b")),
folder(dir.join("another")), folder(dir.join("another")),
file(dir.join("test_dotnu.nu")), file(dir.join("custom_completion.nu")),
file(dir.join(".hidden_file")), file(dir.join(".hidden_file")),
folder(dir.join(".hidden_folder")), folder(dir.join(".hidden_folder")),
]; ];

View File

@ -1,4 +1,4 @@
mod support; pub mod support;
use nu_cli::NuCompleter; use nu_cli::NuCompleter;
use reedline::Completer; use reedline::Completer;

View File

@ -1,4 +1,4 @@
mod support; pub mod support;
use nu_cli::NuCompleter; use nu_cli::NuCompleter;
use reedline::Completer; use reedline::Completer;

View File

@ -5,13 +5,12 @@ use nu_engine::eval_block;
use nu_parser::parse; use nu_parser::parse;
use nu_protocol::{ use nu_protocol::{
engine::{EngineState, Stack, StateDelta, StateWorkingSet}, engine::{EngineState, Stack, StateDelta, StateWorkingSet},
PipelineData, Span, Value, PipelineData, ShellError, Span, Value,
}; };
use nu_test_support::fs; use nu_test_support::fs;
use reedline::Suggestion; use reedline::Suggestion;
const SEP: char = std::path::MAIN_SEPARATOR; const SEP: char = std::path::MAIN_SEPARATOR;
#[allow(dead_code)]
// creates a new engine with the current path into the completions fixtures folder // creates a new engine with the current path into the completions fixtures folder
pub fn new_engine() -> (PathBuf, String, EngineState, Stack) { pub fn new_engine() -> (PathBuf, String, EngineState, Stack) {
// Target folder inside assets // Target folder inside assets
@ -48,12 +47,41 @@ pub fn new_engine() -> (PathBuf, String, EngineState, Stack) {
let merge_result = engine_state.merge_delta(delta, Some(&mut stack), &dir); let merge_result = engine_state.merge_delta(delta, Some(&mut stack), &dir);
assert!(merge_result.is_ok()); assert!(merge_result.is_ok());
// Add record value as example (dir, dir_str, engine_state, stack)
let record = "let actor = { name: 'Tom Hardy', age: 44 }"; }
// match a list of suggestions with the expected values
pub fn match_suggestions(expected: Vec<String>, suggestions: Vec<Suggestion>) {
expected.iter().zip(suggestions).for_each(|it| {
assert_eq!(it.0, &it.1.value);
});
}
// append the separator to the converted path
pub fn folder(path: PathBuf) -> String {
let mut converted_path = file(path);
converted_path.push(SEP);
converted_path
}
// convert a given path to string
pub fn file(path: PathBuf) -> String {
path.into_os_string().into_string().unwrap_or_default()
}
// merge_input executes the given input into the engine
// and merges the state
pub fn merge_input(
input: &[u8],
engine_state: &mut EngineState,
stack: &mut Stack,
dir: PathBuf,
) -> Result<(), ShellError> {
let (block, delta) = { let (block, delta) = {
let mut working_set = StateWorkingSet::new(&engine_state); let mut working_set = StateWorkingSet::new(&engine_state);
let (block, err) = parse(&mut working_set, None, record.as_bytes(), false, &[]); let (block, err) = parse(&mut working_set, None, input, false, &[]);
assert!(err.is_none()); assert!(err.is_none());
@ -61,7 +89,7 @@ pub fn new_engine() -> (PathBuf, String, EngineState, Stack) {
}; };
assert!(eval_block( assert!(eval_block(
&engine_state, &engine_state,
&mut stack, stack,
&block, &block,
PipelineData::Value( PipelineData::Value(
Value::Nothing { Value::Nothing {
@ -75,31 +103,5 @@ pub fn new_engine() -> (PathBuf, String, EngineState, Stack) {
.is_ok()); .is_ok());
// Merge delta // Merge delta
let merge_result = engine_state.merge_delta(delta, Some(&mut stack), &dir); engine_state.merge_delta(delta, Some(stack), &dir)
assert!(merge_result.is_ok());
(dir.clone(), dir_str, engine_state, stack)
}
#[allow(dead_code)]
// match a list of suggestions with the expected values
pub fn match_suggestions(expected: Vec<String>, suggestions: Vec<Suggestion>) {
expected.iter().zip(suggestions).for_each(|it| {
assert_eq!(it.0, &it.1.value);
});
}
#[allow(dead_code)]
// append the separator to the converted path
pub fn folder(path: PathBuf) -> String {
let mut converted_path = file(path);
converted_path.push(SEP);
converted_path
}
#[allow(dead_code)]
// convert a given path to string
pub fn file(path: PathBuf) -> String {
path.into_os_string().into_string().unwrap_or_default()
} }

View File

@ -1,3 +1,3 @@
pub mod completions_helpers; pub mod completions_helpers;
pub use completions_helpers::{file, folder, match_suggestions, new_engine}; pub use completions_helpers::{file, folder, match_suggestions, merge_input, new_engine};

View File

@ -1,4 +1,4 @@
mod support; pub mod support;
use nu_cli::NuCompleter; use nu_cli::NuCompleter;
use reedline::Completer; use reedline::Completer;
@ -7,7 +7,11 @@ use support::{match_suggestions, new_engine};
#[test] #[test]
fn variables_completions() { fn variables_completions() {
// Create a new engine // Create a new engine
let (_, _, engine, stack) = new_engine(); let (dir, _, mut engine, mut stack) = new_engine();
// Add record value as example
let record = "let actor = { name: 'Tom Hardy', age: 44 }";
assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack, dir).is_ok());
// Instatiate a new completer // Instatiate a new completer
let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack);

View File

@ -0,0 +1,2 @@
def animals [] { ["cat", "dog", "eel" ] }
def my-command [animal: string@animals] { print $animal }

View File

@ -1,3 +0,0 @@
def test[] {
Just a test
}