From 1d64863585127f5dc97ab893de839db5ab5a3760 Mon Sep 17 00:00:00 2001 From: Herlon Aguiar Date: Tue, 10 May 2022 22:17:07 +0200 Subject: [PATCH] nu-cli/completions: add variable completions test + refactor tests (#5504) * refactor tests * removed old test file --- crates/nu-cli/tests/dotnu_completions.rs | 28 +++ crates/nu-cli/tests/file_completions.rs | 42 ++++ crates/nu-cli/tests/flag_completions.rs | 36 ++++ crates/nu-cli/tests/folder_completions.rs | 29 +++ .../tests/support/completions_helpers.rs | 105 +++++++++ crates/nu-cli/tests/support/mod.rs | 3 + crates/nu-cli/tests/test_completions.rs | 204 ------------------ crates/nu-cli/tests/variables_completions.rs | 53 +++++ 8 files changed, 296 insertions(+), 204 deletions(-) create mode 100644 crates/nu-cli/tests/dotnu_completions.rs create mode 100644 crates/nu-cli/tests/file_completions.rs create mode 100644 crates/nu-cli/tests/flag_completions.rs create mode 100644 crates/nu-cli/tests/folder_completions.rs create mode 100644 crates/nu-cli/tests/support/completions_helpers.rs create mode 100644 crates/nu-cli/tests/support/mod.rs delete mode 100644 crates/nu-cli/tests/test_completions.rs create mode 100644 crates/nu-cli/tests/variables_completions.rs diff --git a/crates/nu-cli/tests/dotnu_completions.rs b/crates/nu-cli/tests/dotnu_completions.rs new file mode 100644 index 0000000000..cf884d51dd --- /dev/null +++ b/crates/nu-cli/tests/dotnu_completions.rs @@ -0,0 +1,28 @@ +mod support; + +use nu_cli::NuCompleter; +use reedline::Completer; +use support::new_engine; + +#[test] +fn dotnu_completions() { + // Create a new engine + let (_, _, engine, stack) = new_engine(); + + // Instatiate a new completer + let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + + // Test source completion + let completion_str = "source ".to_string(); + let suggestions = completer.complete(&completion_str, completion_str.len()); + + assert_eq!(1, suggestions.len()); + assert_eq!("test_dotnu.nu", suggestions.get(0).unwrap().value); + + // Test use completion + let completion_str = "use ".to_string(); + let suggestions = completer.complete(&completion_str, completion_str.len()); + + assert_eq!(1, suggestions.len()); + assert_eq!("test_dotnu.nu", suggestions.get(0).unwrap().value); +} diff --git a/crates/nu-cli/tests/file_completions.rs b/crates/nu-cli/tests/file_completions.rs new file mode 100644 index 0000000000..85e6a474cf --- /dev/null +++ b/crates/nu-cli/tests/file_completions.rs @@ -0,0 +1,42 @@ +mod support; + +use nu_cli::NuCompleter; +use reedline::Completer; +use support::{file, folder, match_suggestions, new_engine}; + +#[test] +fn file_completions() { + // Create a new engine + let (dir, dir_str, engine, stack) = new_engine(); + + // Instatiate a new completer + let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + + // Test completions for the current folder + let target_dir = format!("cp {}", dir_str); + let suggestions = completer.complete(&target_dir, target_dir.len()); + + // Create the expected values + let expected_paths: Vec = vec![ + file(dir.join("nushell")), + folder(dir.join("test_a")), + folder(dir.join("test_b")), + folder(dir.join("another")), + file(dir.join("test_dotnu.nu")), + file(dir.join(".hidden_file")), + folder(dir.join(".hidden_folder")), + ]; + + // Match the results + match_suggestions(expected_paths, suggestions); + + // Test completions for the completions/another folder + let target_dir = format!("cd {}", folder(dir.join("another"))); + let suggestions = completer.complete(&target_dir, target_dir.len()); + + // Create the expected values + let expected_paths: Vec = vec![file(dir.join("another").join("newfile"))]; + + // Match the results + match_suggestions(expected_paths, suggestions); +} diff --git a/crates/nu-cli/tests/flag_completions.rs b/crates/nu-cli/tests/flag_completions.rs new file mode 100644 index 0000000000..861020b20a --- /dev/null +++ b/crates/nu-cli/tests/flag_completions.rs @@ -0,0 +1,36 @@ +mod support; + +use nu_cli::NuCompleter; +use reedline::Completer; +use support::{match_suggestions, new_engine}; + +#[test] +fn flag_completions() { + // Create a new engine + let (_, _, engine, stack) = new_engine(); + + // Instatiate a new completer + let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + // Test completions for the 'ls' flags + let suggestions = completer.complete("ls -".into(), 4); + + assert_eq!(12, suggestions.len()); + + let expected: Vec = vec![ + "--all".into(), + "--du".into(), + "--full-paths".into(), + "--help".into(), + "--long".into(), + "--short-names".into(), + "-a".into(), + "-d".into(), + "-f".into(), + "-h".into(), + "-l".into(), + "-s".into(), + ]; + + // Match results + match_suggestions(expected, suggestions); +} diff --git a/crates/nu-cli/tests/folder_completions.rs b/crates/nu-cli/tests/folder_completions.rs new file mode 100644 index 0000000000..239033500d --- /dev/null +++ b/crates/nu-cli/tests/folder_completions.rs @@ -0,0 +1,29 @@ +mod support; + +use nu_cli::NuCompleter; +use reedline::Completer; +use support::{folder, match_suggestions, new_engine}; + +#[test] +fn folder_completions() { + // Create a new engine + let (dir, dir_str, engine, stack) = new_engine(); + + // Instatiate a new completer + let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + + // Test completions for the current folder + let target_dir = format!("cd {}", dir_str); + let suggestions = completer.complete(&target_dir, target_dir.len()); + + // Create the expected values + let expected_paths: Vec = vec![ + folder(dir.join("test_a")), + folder(dir.join("test_b")), + folder(dir.join("another")), + folder(dir.join(".hidden_folder")), + ]; + + // Match the results + match_suggestions(expected_paths, suggestions); +} diff --git a/crates/nu-cli/tests/support/completions_helpers.rs b/crates/nu-cli/tests/support/completions_helpers.rs new file mode 100644 index 0000000000..e428f4c3f4 --- /dev/null +++ b/crates/nu-cli/tests/support/completions_helpers.rs @@ -0,0 +1,105 @@ +use std::path::PathBuf; + +use nu_command::create_default_context; +use nu_engine::eval_block; +use nu_parser::parse; +use nu_protocol::{ + engine::{EngineState, Stack, StateDelta, StateWorkingSet}, + PipelineData, Span, Value, +}; +use nu_test_support::fs; +use reedline::Suggestion; +const SEP: char = std::path::MAIN_SEPARATOR; + +#[allow(dead_code)] +// creates a new engine with the current path into the completions fixtures folder +pub fn new_engine() -> (PathBuf, String, EngineState, Stack) { + // Target folder inside assets + let dir = fs::fixtures().join("completions"); + let mut dir_str = dir + .clone() + .into_os_string() + .into_string() + .unwrap_or_default(); + dir_str.push(SEP); + + // Create a new engine with default context + let mut engine_state = create_default_context(&dir); + + // New stack + let mut stack = Stack::new(); + + // New delta state + let delta = StateDelta::new(&engine_state); + + // Add pwd as env var + stack.add_env_var( + "PWD".to_string(), + Value::String { + val: dir_str.clone(), + span: nu_protocol::Span { + start: 0, + end: dir_str.len(), + }, + }, + ); + + // Merge delta + let merge_result = engine_state.merge_delta(delta, Some(&mut stack), &dir); + assert!(merge_result.is_ok()); + + // Add record value as example + let record = "let actor = { name: 'Tom Hardy', age: 44 }"; + let (block, delta) = { + let mut working_set = StateWorkingSet::new(&engine_state); + + let (block, err) = parse(&mut working_set, None, record.as_bytes(), false, &[]); + + assert!(err.is_none()); + + (block, working_set.render()) + }; + assert!(eval_block( + &engine_state, + &mut stack, + &block, + PipelineData::Value( + Value::Nothing { + span: Span { start: 0, end: 0 }, + }, + None + ), + false, + false + ) + .is_ok()); + + // Merge delta + let merge_result = engine_state.merge_delta(delta, Some(&mut 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, suggestions: Vec) { + 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() +} diff --git a/crates/nu-cli/tests/support/mod.rs b/crates/nu-cli/tests/support/mod.rs new file mode 100644 index 0000000000..5bc4546148 --- /dev/null +++ b/crates/nu-cli/tests/support/mod.rs @@ -0,0 +1,3 @@ +pub mod completions_helpers; + +pub use completions_helpers::{file, folder, match_suggestions, new_engine}; diff --git a/crates/nu-cli/tests/test_completions.rs b/crates/nu-cli/tests/test_completions.rs deleted file mode 100644 index 0807902fbc..0000000000 --- a/crates/nu-cli/tests/test_completions.rs +++ /dev/null @@ -1,204 +0,0 @@ -use std::path::PathBuf; - -use nu_cli::NuCompleter; -use nu_command::create_default_context; -use nu_protocol::{ - engine::{EngineState, Stack, StateDelta}, - Value, -}; -use nu_test_support::fs; -use reedline::{Completer, Suggestion}; -const SEP: char = std::path::MAIN_SEPARATOR; - -#[test] -fn dotnu_completions() { - // Create a new engine - let (_, dir_str, engine) = new_engine(); - - let mut stack = Stack::new(); - - // Add pwd as env var - stack.add_env_var( - "PWD".to_string(), - Value::String { - val: dir_str.clone(), - span: nu_protocol::Span { - start: 0, - end: dir_str.len(), - }, - }, - ); - - // Instatiate a new completer - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); - - // Test source completion - let completion_str = "source ".to_string(); - let suggestions = completer.complete(&completion_str, completion_str.len()); - - assert_eq!(1, suggestions.len()); - assert_eq!("test_dotnu.nu", suggestions.get(0).unwrap().value); - - // Test use completion - let completion_str = "use ".to_string(); - let suggestions = completer.complete(&completion_str, completion_str.len()); - - assert_eq!(1, suggestions.len()); - assert_eq!("test_dotnu.nu", suggestions.get(0).unwrap().value); -} - -#[test] -fn flag_completions() { - // Create a new engine - let (_, _, engine) = new_engine(); - - let stack = Stack::new(); - - // Instatiate a new completer - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); - // Test completions for the 'ls' flags - let suggestions = completer.complete("ls -", 4); - - assert_eq!(12, suggestions.len()); - - let expected: Vec = vec![ - "--all".into(), - "--du".into(), - "--full-paths".into(), - "--help".into(), - "--long".into(), - "--short-names".into(), - "-a".into(), - "-d".into(), - "-f".into(), - "-h".into(), - "-l".into(), - "-s".into(), - ]; - - // Match results - match_suggestions(expected, suggestions); -} - -#[test] -fn file_completions() { - // Create a new engine - let (dir, dir_str, engine) = new_engine(); - - let stack = Stack::new(); - - // Instatiate a new completer - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); - - // Test completions for the current folder - let target_dir = format!("cp {}", dir_str); - let suggestions = completer.complete(&target_dir, target_dir.len()); - - // Create the expected values - let expected_paths: Vec = vec![ - file(dir.join("nushell")), - folder(dir.join("test_a")), - folder(dir.join("test_b")), - folder(dir.join("another")), - file(dir.join("test_dotnu.nu")), - file(dir.join(".hidden_file")), - folder(dir.join(".hidden_folder")), - ]; - - // Match the results - match_suggestions(expected_paths, suggestions); - - // Test completions for the completions/another folder - let target_dir = format!("cd {}", folder(dir.join("another"))); - let suggestions = completer.complete(&target_dir, target_dir.len()); - - // Create the expected values - let expected_paths: Vec = vec![file(dir.join("another").join("newfile"))]; - - // Match the results - match_suggestions(expected_paths, suggestions); -} - -#[test] -fn folder_completions() { - // Create a new engine - let (dir, dir_str, engine) = new_engine(); - - let stack = Stack::new(); - - // Instatiate a new completer - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); - - // Test completions for the current folder - let target_dir = format!("cd {}", dir_str); - let suggestions = completer.complete(&target_dir, target_dir.len()); - - // Create the expected values - let expected_paths: Vec = vec![ - folder(dir.join("test_a")), - folder(dir.join("test_b")), - folder(dir.join("another")), - folder(dir.join(".hidden_folder")), - ]; - - // Match the results - match_suggestions(expected_paths, suggestions); -} - -// creates a new engine with the current path into the completions fixtures folder -pub fn new_engine() -> (PathBuf, String, EngineState) { - // Target folder inside assets - let dir = fs::fixtures().join("completions"); - let mut dir_str = dir - .clone() - .into_os_string() - .into_string() - .unwrap_or_default(); - dir_str.push(SEP); - - // Create a new engine with default context - let mut engine_state = create_default_context(&dir); - - // New stack - let mut stack = Stack::new(); - - // New delta - let delta = StateDelta::new(&engine_state); - - // Add pwd as env var - stack.add_env_var( - "PWD".to_string(), - Value::String { - val: dir_str.clone(), - span: nu_protocol::Span { - start: 0, - end: dir_str.len(), - }, - }, - ); - - // Merge delta - let _ = engine_state.merge_delta(delta, Some(&mut stack), &dir); - - (dir.clone(), dir_str, engine_state) -} - -// match a list of suggestions with the expected values -pub fn match_suggestions(expected: Vec, suggestions: Vec) { - 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() -} diff --git a/crates/nu-cli/tests/variables_completions.rs b/crates/nu-cli/tests/variables_completions.rs new file mode 100644 index 0000000000..df89461664 --- /dev/null +++ b/crates/nu-cli/tests/variables_completions.rs @@ -0,0 +1,53 @@ +mod support; + +use nu_cli::NuCompleter; +use reedline::Completer; +use support::{match_suggestions, new_engine}; + +#[test] +fn variables_completions() { + // Create a new engine + let (_, _, engine, stack) = new_engine(); + + // Instatiate a new completer + let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + + // Test completions for $nu + let suggestions = completer.complete("$nu.".into(), 4); + + assert_eq!(8, suggestions.len()); + + let expected: Vec = vec![ + "config-path".into(), + "env-path".into(), + "history-path".into(), + "home-path".into(), + "os-info".into(), + "pid".into(), + "scope".into(), + "temp-path".into(), + ]; + + // Match results + match_suggestions(expected, suggestions); + + // Test completions for custom var + let suggestions = completer.complete("$actor.".into(), 7); + + assert_eq!(2, suggestions.len()); + + let expected: Vec = vec!["age".into(), "name".into()]; + + // Match results + match_suggestions(expected, suggestions); + + // Test completions for $env + let suggestions = completer.complete("$env.".into(), 5); + + assert_eq!(1, suggestions.len()); + + let expected: Vec = vec!["PWD".into()]; + + // Match results + match_suggestions(expected, suggestions); +}