Expand Nushell's help system (#7611)

This commit is contained in:
Jakub Žádník
2022-12-30 17:44:37 +02:00
committed by GitHub
parent f3d2be7a56
commit 8bfcea8054
23 changed files with 1509 additions and 446 deletions

View File

@ -47,7 +47,7 @@ fn alias_fails_with_invalid_name() {
let actual = nu!(
cwd: ".", pipeline(
r#"
alias 1234 = echo "test"
alias 1234 = echo "test"
"#
));
assert!(actual.err.contains(err_msg));
@ -55,7 +55,7 @@ fn alias_fails_with_invalid_name() {
let actual = nu!(
cwd: ".", pipeline(
r#"
alias 5gib = echo "test"
alias 5gib = echo "test"
"#
));
assert!(actual.err.contains(err_msg));
@ -63,7 +63,7 @@ fn alias_fails_with_invalid_name() {
let actual = nu!(
cwd: ".", pipeline(
r#"
alias "te#t" = echo "test"
alias "te#t" = echo "test"
"#
));
assert!(actual.err.contains(err_msg));
@ -85,5 +85,5 @@ fn alias_alone_lists_aliases() {
alias a = 3; alias
"#
));
assert!(actual.out.contains("alias") && actual.out.contains("expansion"));
assert!(actual.out.contains("name") && actual.out.contains("expansion"));
}

View File

@ -1,9 +1,11 @@
use nu_test_support::{nu, pipeline};
use nu_test_support::fs::Stub::FileWithContent;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, nu_repl_code, pipeline};
#[test]
fn help_commands_length() {
let actual = nu!(
cwd: ".", pipeline(
cwd: ".", pipeline(
r#"
help commands | length
"#
@ -26,3 +28,289 @@ fn help_shows_signature() {
let actual = nu!(cwd: ".", pipeline("help alias"));
assert!(!actual.out.contains("Signatures"));
}
#[test]
fn help_aliases() {
let code = &[
"alias SPAM = print 'spam'",
"help aliases | where name == SPAM | length",
];
let actual = nu!(cwd: ".", nu_repl_code(code));
assert_eq!(actual.out, "1");
}
#[test]
fn help_alias_usage_1() {
Playground::setup("help_alias_usage_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"spam.nu",
r#"
# line1
alias SPAM = print 'spam'
"#,
)]);
let code = &[
"source spam.nu",
"help aliases | where name == SPAM | get 0.usage",
];
let actual = nu!(cwd: dirs.test(), nu_repl_code(code));
assert_eq!(actual.out, "line1");
})
}
#[test]
fn help_alias_usage_2() {
let code = &[
"alias SPAM = print 'spam' # line2",
"help aliases | where name == SPAM | get 0.usage",
];
let actual = nu!(cwd: ".", nu_repl_code(code));
assert_eq!(actual.out, "line2");
}
#[test]
fn help_alias_usage_3() {
Playground::setup("help_alias_usage_3", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"spam.nu",
r#"
# line1
alias SPAM = print 'spam' # line2
"#,
)]);
let code = &[
"source spam.nu",
"help aliases | where name == SPAM | get 0.usage",
];
let actual = nu!(cwd: dirs.test(), nu_repl_code(code));
assert!(actual.out.contains("line1"));
assert!(actual.out.contains("line2"));
})
}
#[test]
fn help_alias_name() {
Playground::setup("help_alias_name", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"spam.nu",
r#"
# line1
alias SPAM = print 'spam' # line2
"#,
)]);
let code = &["source spam.nu", "help aliases SPAM"];
let actual = nu!(cwd: dirs.test(), nu_repl_code(code));
assert!(actual.out.contains("line1"));
assert!(actual.out.contains("line2"));
assert!(actual.out.contains("SPAM"));
assert!(actual.out.contains("print 'spam'"));
})
}
#[test]
fn help_alias_name_f() {
Playground::setup("help_alias_name_f", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"spam.nu",
r#"
# line1
alias SPAM = print 'spam' # line2
"#,
)]);
let code = &["source spam.nu", "help aliases -f SPAM | get 0.usage"];
let actual = nu!(cwd: dirs.test(), nu_repl_code(code));
assert!(actual.out.contains("line1"));
assert!(actual.out.contains("line2"));
})
}
#[test]
fn help_export_alias_name_single_word() {
Playground::setup("help_export_alias_name_single_word", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"spam.nu",
r#"
# line1
export alias SPAM = print 'spam' # line2
"#,
)]);
let code = &["use spam.nu SPAM", "help aliases SPAM"];
let actual = nu!(cwd: dirs.test(), nu_repl_code(code));
assert!(actual.out.contains("line1"));
assert!(actual.out.contains("line2"));
assert!(actual.out.contains("SPAM"));
assert!(actual.out.contains("print 'spam'"));
})
}
#[test]
fn help_export_alias_name_multi_word() {
Playground::setup("help_export_alias_name_multi_word", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"spam.nu",
r#"
# line1
export alias SPAM = print 'spam' # line2
"#,
)]);
let code = &["use spam.nu", "help aliases spam SPAM"];
let actual = nu!(cwd: dirs.test(), nu_repl_code(code));
assert!(actual.out.contains("line1"));
assert!(actual.out.contains("line2"));
assert!(actual.out.contains("SPAM"));
assert!(actual.out.contains("print 'spam'"));
})
}
#[test]
fn help_module_usage_1() {
Playground::setup("help_module_usage", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"spam.nu",
r#"
# line1
module SPAM {
# line2
} #line3
"#,
)]);
let code = &[
"source spam.nu",
"help modules | where name == SPAM | get 0.usage",
];
let actual = nu!(cwd: dirs.test(), nu_repl_code(code));
assert!(actual.out.contains("line1"));
assert!(actual.out.contains("line2"));
assert!(actual.out.contains("line3"));
})
}
#[test]
fn help_module_name() {
Playground::setup("help_module_name", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"spam.nu",
r#"
# line1
module SPAM {
# line2
} #line3
"#,
)]);
let code = &["source spam.nu", "help modules SPAM"];
let actual = nu!(cwd: dirs.test(), nu_repl_code(code));
assert!(actual.out.contains("line1"));
assert!(actual.out.contains("line2"));
assert!(actual.out.contains("line3"));
assert!(actual.out.contains("SPAM"));
})
}
#[test]
fn help_module_sorted_decls() {
Playground::setup("help_module_sorted_decls", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"spam.nu",
r#"
module SPAM {
export def z [] {}
export def a [] {}
}
"#,
)]);
let code = &["source spam.nu", "help modules SPAM"];
let actual = nu!(cwd: dirs.test(), nu_repl_code(code));
assert!(actual.out.contains("a, z"));
})
}
#[test]
fn help_module_sorted_aliases() {
Playground::setup("help_module_sorted_aliases", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"spam.nu",
r#"
module SPAM {
export alias z = 'z'
export alias a = 'a'
}
"#,
)]);
let code = &["source spam.nu", "help modules SPAM"];
let actual = nu!(cwd: dirs.test(), nu_repl_code(code));
assert!(actual.out.contains("a, z"));
})
}
#[test]
fn help_usage_extra_usage() {
Playground::setup("help_usage_extra_usage", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"spam.nu",
r#"
# module_line1
#
# module_line2
# def_line1
#
# def_line2
export def foo [] {}
# alias_line1
#
# alias_line2
export alias bar = 'bar'
"#,
)]);
let actual = nu!(cwd: dirs.test(), pipeline("use spam.nu *; help modules spam"));
assert!(actual.out.contains("module_line1"));
assert!(actual.out.contains("module_line2"));
let actual = nu!(cwd: dirs.test(),
pipeline("use spam.nu *; help modules | where name == spam | get 0.usage"));
assert!(actual.out.contains("module_line1"));
assert!(!actual.out.contains("module_line2"));
let actual = nu!(cwd: dirs.test(), pipeline("use spam.nu *; help commands foo"));
assert!(actual.out.contains("def_line1"));
assert!(actual.out.contains("def_line2"));
let actual = nu!(cwd: dirs.test(),
pipeline("use spam.nu *; help commands | where name == foo | get 0.usage"));
assert!(actual.out.contains("def_line1"));
assert!(!actual.out.contains("def_line2"));
let actual = nu!(cwd: dirs.test(), pipeline("use spam.nu *; help aliases bar"));
assert!(actual.out.contains("alias_line1"));
assert!(actual.out.contains("alias_line2"));
let actual = nu!(cwd: dirs.test(),
pipeline("use spam.nu *; help aliases | where name == bar | get 0.usage"));
assert!(actual.out.contains("alias_line1"));
assert!(!actual.out.contains("alias_line2"));
})
}

View File

@ -185,15 +185,29 @@ fn use_export_env_combined() {
}
#[test]
fn use_module_creates_accurate_did_you_mean() {
fn use_module_creates_accurate_did_you_mean_1() {
let actual = nu!(
cwd: ".", pipeline(
r#"
module spam { export def foo [] { "foo" } }; use spam; foo
"#
module spam { export def foo [] { "foo" } }; use spam; foo
"#
)
);
assert!(actual.err.contains(
"command 'foo' was not found but it exists in module 'spam'; try using `spam foo`"
"command 'foo' was not found but it was imported from module 'spam'; try using `spam foo`"
));
}
#[test]
fn use_module_creates_accurate_did_you_mean_2() {
let actual = nu!(
cwd: ".", pipeline(
r#"
module spam { export def foo [] { "foo" } }; foo
"#
)
);
assert!(actual.err.contains(
"command 'foo' was not found but it exists in module 'spam'; try importing it with `use`"
));
}

View File

@ -26,12 +26,12 @@ fn quickcheck_parse(data: String) -> bool {
#[test]
fn signature_name_matches_command_name() {
let ctx = crate::create_default_context();
let decls = ctx.get_decl_ids_sorted(true);
let decls = ctx.get_decls_sorted(true);
let mut failures = Vec::new();
for decl_id in decls {
for (name_bytes, decl_id) in decls {
let cmd = ctx.get_decl(decl_id);
let cmd_name = cmd.name();
let cmd_name = String::from_utf8_lossy(&name_bytes);
let sig_name = cmd.signature().name;
let category = cmd.signature().category;
@ -52,10 +52,10 @@ fn signature_name_matches_command_name() {
#[test]
fn commands_declare_input_output_types() {
let ctx = crate::create_default_context();
let decls = ctx.get_decl_ids_sorted(true);
let decls = ctx.get_decls_sorted(true);
let mut failures = Vec::new();
for decl_id in decls {
for (_, decl_id) in decls {
let cmd = ctx.get_decl(decl_id);
let sig_name = cmd.signature().name;
let category = cmd.signature().category;
@ -83,12 +83,12 @@ fn commands_declare_input_output_types() {
#[test]
fn no_search_term_duplicates() {
let ctx = crate::create_default_context();
let decls = ctx.get_decl_ids_sorted(true);
let decls = ctx.get_decls_sorted(true);
let mut failures = Vec::new();
for decl_id in decls {
for (name_bytes, decl_id) in decls {
let cmd = ctx.get_decl(decl_id);
let cmd_name = cmd.name();
let cmd_name = String::from_utf8_lossy(&name_bytes);
let search_terms = cmd.search_terms();
let category = cmd.signature().category;