mirror of
https://github.com/nushell/nushell.git
synced 2025-05-30 06:39:33 +02:00
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:
parent
f2d47f97da
commit
4d7b86f278
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -2289,10 +2289,12 @@ dependencies = [
|
|||||||
"miette 4.5.0",
|
"miette 4.5.0",
|
||||||
"nu-ansi-term",
|
"nu-ansi-term",
|
||||||
"nu-color-config",
|
"nu-color-config",
|
||||||
|
"nu-command",
|
||||||
"nu-engine",
|
"nu-engine",
|
||||||
"nu-parser",
|
"nu-parser",
|
||||||
"nu-path",
|
"nu-path",
|
||||||
"nu-protocol",
|
"nu-protocol",
|
||||||
|
"nu-test-support",
|
||||||
"nu-utils",
|
"nu-utils",
|
||||||
"reedline",
|
"reedline",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
@ -6,6 +6,10 @@ license = "MIT"
|
|||||||
name = "nu-cli"
|
name = "nu-cli"
|
||||||
version = "0.61.1"
|
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]
|
[dependencies]
|
||||||
nu-engine = { path = "../nu-engine", version = "0.61.1" }
|
nu-engine = { path = "../nu-engine", version = "0.61.1" }
|
||||||
nu-path = { path = "../nu-path", version = "0.61.1" }
|
nu-path = { path = "../nu-path", version = "0.61.1" }
|
||||||
|
@ -60,6 +60,7 @@ impl Completer for FileCompletion {
|
|||||||
|
|
||||||
// Sort items
|
// Sort items
|
||||||
let mut sorted_items = items;
|
let mut sorted_items = items;
|
||||||
|
sorted_items.sort_by(|a, b| a.value.cmp(&b.value));
|
||||||
sorted_items.sort_by(|a, b| {
|
sorted_items.sort_by(|a, b| {
|
||||||
let a_distance = levenshtein_distance(&prefix_str, &a.value);
|
let a_distance = levenshtein_distance(&prefix_str, &a.value);
|
||||||
let b_distance = levenshtein_distance(&prefix_str, &b.value);
|
let b_distance = levenshtein_distance(&prefix_str, &b.value);
|
||||||
|
@ -15,7 +15,7 @@ mod util;
|
|||||||
mod validation;
|
mod validation;
|
||||||
|
|
||||||
pub use commands::evaluate_commands;
|
pub use commands::evaluate_commands;
|
||||||
pub use completions::NuCompleter;
|
pub use completions::{FileCompletion, NuCompleter};
|
||||||
pub use config_files::eval_config_contents;
|
pub use config_files::eval_config_contents;
|
||||||
pub use errors::CliError;
|
pub use errors::CliError;
|
||||||
pub use eval_file::evaluate_file;
|
pub use eval_file::evaluate_file;
|
||||||
|
84
crates/nu-cli/tests/test_completions.rs
Normal file
84
crates/nu-cli/tests/test_completions.rs
Normal 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())
|
||||||
|
}
|
@ -258,7 +258,7 @@ pub fn binaries() -> PathBuf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn fixtures() -> PathBuf {
|
pub fn fixtures() -> PathBuf {
|
||||||
root().join("tests/fixtures")
|
root().join("tests").join("fixtures")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assets() -> PathBuf {
|
pub fn assets() -> PathBuf {
|
||||||
|
0
tests/fixtures/completions/.hidden_file
vendored
Normal file
0
tests/fixtures/completions/.hidden_file
vendored
Normal file
0
tests/fixtures/completions/.hidden_folder/.gitkeep
vendored
Normal file
0
tests/fixtures/completions/.hidden_folder/.gitkeep
vendored
Normal file
0
tests/fixtures/completions/another/newfile
vendored
Normal file
0
tests/fixtures/completions/another/newfile
vendored
Normal file
0
tests/fixtures/completions/nushell
vendored
Normal file
0
tests/fixtures/completions/nushell
vendored
Normal file
0
tests/fixtures/completions/test_a/myfile
vendored
Normal file
0
tests/fixtures/completions/test_a/myfile
vendored
Normal file
0
tests/fixtures/completions/test_b/testfile
vendored
Normal file
0
tests/fixtures/completions/test_b/testfile
vendored
Normal file
Loading…
x
Reference in New Issue
Block a user