nu-cli: added tests for file completions (#5232)

* nu-cli: added tests for file completions

* test adding extra sort

* Feature/refactor completion options (#5228)

* Copy completion filter to custom completions

* Remove filter function from completer

This function was a no-op for FileCompletion and CommandCompletion.
Flag- and VariableCompletion just filters with `starts_with` which
happens in both completers anyway and should therefore also be a no-op.
The remaining use case in CustomCompletion was moved into the
CustomCompletion source file.

Filtering should probably happen immediately while fetching completions
to avoid unnecessary memory allocations.

* Add get_sort_by() to Completer trait

* Remove CompletionOptions from Completer::fetch()

* Fix clippy lints

* Apply Completer changes to DotNuCompletion

* add os to $nu based on rust's understanding (#5243)

* add os to $nu based on rust's understanding

* add a few more constants

Co-authored-by: Richard <Tropid@users.noreply.github.com>
Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com>
This commit is contained in:
Herlon Aguiar 2022-04-20 06:54:00 +02:00 committed by GitHub
parent f2d47f97da
commit 4d7b86f278
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 93 additions and 2 deletions

2
Cargo.lock generated
View File

@ -2289,10 +2289,12 @@ dependencies = [
"miette 4.5.0",
"nu-ansi-term",
"nu-color-config",
"nu-command",
"nu-engine",
"nu-parser",
"nu-path",
"nu-protocol",
"nu-test-support",
"nu-utils",
"reedline",
"thiserror",

View File

@ -6,6 +6,10 @@ license = "MIT"
name = "nu-cli"
version = "0.61.1"
[dev-dependencies]
nu-test-support = { path="../nu-test-support", version = "0.61.1" }
nu-command = { path = "../nu-command", version = "0.61.1" }
[dependencies]
nu-engine = { path = "../nu-engine", version = "0.61.1" }
nu-path = { path = "../nu-path", version = "0.61.1" }

View File

@ -60,6 +60,7 @@ impl Completer for FileCompletion {
// Sort items
let mut sorted_items = items;
sorted_items.sort_by(|a, b| a.value.cmp(&b.value));
sorted_items.sort_by(|a, b| {
let a_distance = levenshtein_distance(&prefix_str, &a.value);
let b_distance = levenshtein_distance(&prefix_str, &b.value);

View File

@ -15,7 +15,7 @@ mod util;
mod validation;
pub use commands::evaluate_commands;
pub use completions::NuCompleter;
pub use completions::{FileCompletion, NuCompleter};
pub use config_files::eval_config_contents;
pub use errors::CliError;
pub use eval_file::evaluate_file;

View File

@ -0,0 +1,84 @@
use std::path::PathBuf;
use nu_cli::NuCompleter;
use nu_command::create_default_context;
use nu_protocol::engine::{EngineState, Stack};
use nu_test_support::fs;
use reedline::{Completer, Suggestion};
const SEP: char = std::path::MAIN_SEPARATOR;
#[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.clone());
// 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<String> = vec![
file(dir.clone().join("nushell")),
folder(dir.clone().join("test_a")),
folder(dir.clone().join("test_b")),
folder(dir.clone().join("another")),
file(dir.clone().join(".hidden_file")),
folder(dir.clone().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.clone().join("another")));
let suggestions = completer.complete(&target_dir, target_dir.len());
// Create the expected values
let expected_paths: Vec<String> = vec![file(dir.clone().join("another").join("newfile"))];
// Match the results
match_suggestions(expected_paths, suggestions);
}
// creates a new engine with the current path into the completions fixtures folder
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("".to_string());
dir_str.push(SEP);
// Create a default engine
(dir.clone(), dir_str, create_default_context(dir))
}
// match a list of suggestions with the expected values
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
fn folder(path: PathBuf) -> String {
let mut converted_path = file(path);
converted_path.push(SEP);
converted_path
}
// convert a given path to string
fn file(path: PathBuf) -> String {
path.clone()
.into_os_string()
.into_string()
.unwrap_or("".to_string())
}

View File

@ -258,7 +258,7 @@ pub fn binaries() -> PathBuf {
}
pub fn fixtures() -> PathBuf {
root().join("tests/fixtures")
root().join("tests").join("fixtures")
}
pub fn assets() -> PathBuf {

View File

View File

View File

0
tests/fixtures/completions/nushell vendored Normal file
View File

View File

View File