Allow source to accept paths with emojis (#3939)

* Allow sourcing paths with emojis

* Add source command tests for emoji paths

* Fmt

* Disable source tests on Windows with illegal paths

* Test sourcing also ASCII and single-quoted paths
This commit is contained in:
Jakub Žádník 2021-08-19 10:06:18 +03:00 committed by GitHub
parent 6db5692be4
commit e11b400a75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 110 additions and 3 deletions

View File

@ -52,6 +52,7 @@ mod select;
mod semicolon;
mod skip;
mod sort_by;
mod source;
mod split_by;
mod split_column;
mod split_row;

View File

@ -0,0 +1,95 @@
use nu_test_support::fs::Stub::FileWithContent;
use nu_test_support::nu;
use nu_test_support::playground::Playground;
fn try_source_foo_with_double_quotes_in(testdir: &str, playdir: &str) {
Playground::setup(playdir, |dirs, sandbox| {
let testdir = String::from(testdir);
let mut foo_file = testdir.clone();
foo_file.push_str("/foo.nu");
sandbox.mkdir(&testdir);
sandbox.with_files(vec![FileWithContent(&foo_file, "echo foo")]);
let cmd = String::from("source ") + r#"""# + &foo_file + r#"""#;
let actual = nu!(cwd: dirs.test(), &cmd);
assert_eq!(actual.out, "foo");
});
}
fn try_source_foo_with_single_quotes_in(testdir: &str, playdir: &str) {
Playground::setup(playdir, |dirs, sandbox| {
let testdir = String::from(testdir);
let mut foo_file = testdir.clone();
foo_file.push_str("/foo.nu");
sandbox.mkdir(&testdir);
sandbox.with_files(vec![FileWithContent(&foo_file, "echo foo")]);
let cmd = String::from("source ") + r#"'"# + &foo_file + r#"'"#;
let actual = nu!(cwd: dirs.test(), &cmd);
assert_eq!(actual.out, "foo");
});
}
fn try_source_foo_without_quotes_in(testdir: &str, playdir: &str) {
Playground::setup(playdir, |dirs, sandbox| {
let testdir = String::from(testdir);
let mut foo_file = testdir.clone();
foo_file.push_str("/foo.nu");
sandbox.mkdir(&testdir);
sandbox.with_files(vec![FileWithContent(&foo_file, "echo foo")]);
let cmd = String::from("source ") + &foo_file;
let actual = nu!(cwd: dirs.test(), &cmd);
assert_eq!(actual.out, "foo");
});
}
#[test]
fn sources_unicode_file_in_normal_dir() {
try_source_foo_with_single_quotes_in("foo", "source_test_1");
try_source_foo_with_double_quotes_in("foo", "source_test_2");
try_source_foo_without_quotes_in("foo", "source_test_3");
}
#[test]
fn sources_unicode_file_in_unicode_dir_without_spaces_1() {
try_source_foo_with_single_quotes_in("🚒", "source_test_4");
try_source_foo_with_double_quotes_in("🚒", "source_test_5");
try_source_foo_without_quotes_in("🚒", "source_test_6");
}
#[cfg(not(windows))] // ':' is not allowed in Windows paths
#[test]
fn sources_unicode_file_in_unicode_dir_without_spaces_2() {
try_source_foo_with_single_quotes_in(":fire_engine:", "source_test_7");
try_source_foo_with_double_quotes_in(":fire_engine:", "source_test_8");
try_source_foo_without_quotes_in(":fire_engine:", "source_test_9");
}
#[test]
fn sources_unicode_file_in_unicode_dir_with_spaces_1() {
try_source_foo_with_single_quotes_in("e-$ èрт🚒♞中片-j", "source_test_8");
try_source_foo_with_double_quotes_in("e-$ èрт🚒♞中片-j", "source_test_9");
}
#[cfg(not(windows))] // ':' is not allowed in Windows paths
#[test]
fn sources_unicode_file_in_unicode_dir_with_spaces_2() {
try_source_foo_with_single_quotes_in("e-$ èрт:fire_engine:♞中片-j", "source_test_10");
try_source_foo_with_double_quotes_in("e-$ èрт:fire_engine:♞中片-j", "source_test_11");
}
#[ignore]
#[test]
fn sources_unicode_file_in_non_utf8_dir() {
// How do I create non-UTF-8 path???
}

View File

@ -1889,9 +1889,20 @@ fn parse_call(
)),
);
}
if let Ok(contents) = std::fs::read_to_string(&expand_path(Cow::Borrowed(Path::new(
&lite_cmd.parts[1].item,
)))) {
let script_path = if let Some(ref positional_args) = internal_command.args.positional {
if let Expression::FilePath(ref p) = positional_args[0].expr {
p
} else {
Path::new(&lite_cmd.parts[1].item)
}
} else {
Path::new(&lite_cmd.parts[1].item)
};
if let Ok(contents) =
std::fs::read_to_string(&expand_path(Cow::Borrowed(Path::new(script_path))))
{
let _ = parse(&contents, 0, scope);
} else {
return (