Command tests (#922)

* WIP command tests

* Finish marking todo tests

* update

* update

* Windows cd test ignoring
This commit is contained in:
JT 2022-02-03 21:01:45 -05:00 committed by GitHub
parent ac0b331f00
commit a008f1aa80
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
139 changed files with 10298 additions and 348 deletions

View File

@ -426,7 +426,7 @@ fn display(help: &str, engine_state: &EngineState, stack: &mut Stack, span: Span
if let Ok(output) = decl.run(
engine_state,
stack,
&Call::new(),
&Call::new(span),
Value::String {
val: item.to_string(),
span: Span { start: 0, end: 0 },

View File

@ -142,7 +142,7 @@ impl Command for Open {
Some(converter_id) => engine_state.get_decl(converter_id).run(
engine_state,
stack,
&Call::new(),
&Call::new(call_span),
output,
),
None => Ok(output),

View File

@ -71,7 +71,7 @@ impl Command for Save {
let output = engine_state.get_decl(converter_id).run(
engine_state,
stack,
&Call::new(),
&Call::new(span),
input,
)?;

View File

@ -82,6 +82,10 @@ fn getcol(
.map(move |x| Value::String { val: x, span })
.into_pipeline_data(engine_state.ctrlc.clone()))
}
PipelineData::Value(Value::Record { cols, .. }, ..) => Ok(cols
.into_iter()
.map(move |x| Value::String { val: x, span })
.into_pipeline_data(engine_state.ctrlc.clone())),
PipelineData::Value(..) | PipelineData::RawStream(..) => {
let cols = vec![];
let vals = vec![];

View File

@ -30,7 +30,7 @@ impl Command for Lines {
input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
let head = call.head;
let skip_empty = call.has_flag("skip-emtpy");
let skip_empty = call.has_flag("skip-empty");
match input {
#[allow(clippy::needless_collect)]
// Collect is needed because the string may not live long enough for
@ -39,13 +39,21 @@ impl Command for Lines {
PipelineData::Value(Value::String { val, span }, ..) => {
let split_char = if val.contains("\r\n") { "\r\n" } else { "\n" };
let lines = val
let mut lines = val
.split(split_char)
.map(|s| s.to_string())
.collect::<Vec<String>>();
// if the last one is empty, remove it, as it was just
// a newline at the end of the input we got
if let Some(last) = lines.last() {
if last.is_empty() {
lines.pop();
}
}
let iter = lines.into_iter().filter_map(move |s| {
if skip_empty && s.is_empty() {
if skip_empty && s.trim().is_empty() {
None
} else {
Some(Value::string(s, span))
@ -65,21 +73,30 @@ impl Command for Lines {
split_char = "\r\n";
}
let inner = val
let mut lines = val
.split(split_char)
.filter_map(|s| {
if skip_empty && s.is_empty() {
if skip_empty && s.trim().is_empty() {
None
} else {
Some(Value::String {
val: s.into(),
span,
})
Some(s.to_string())
}
})
.collect::<Vec<Value>>();
.collect::<Vec<_>>();
Some(inner)
// if the last one is empty, remove it, as it was just
// a newline at the end of the input we got
if let Some(last) = lines.last() {
if last.is_empty() {
lines.pop();
}
}
Some(
lines
.into_iter()
.map(move |x| Value::String { val: x, span }),
)
} else {
None
}
@ -102,13 +119,21 @@ impl Command for Lines {
let split_char = if s.contains("\r\n") { "\r\n" } else { "\n" };
#[allow(clippy::needless_collect)]
let lines = s
let mut lines = s
.split(split_char)
.map(|s| s.to_string())
.collect::<Vec<String>>();
// if the last one is empty, remove it, as it was just
// a newline at the end of the input we got
if let Some(last) = lines.last() {
if last.is_empty() {
lines.pop();
}
}
let iter = lines.into_iter().filter_map(move |s| {
if skip_empty && s.is_empty() {
if skip_empty && s.trim().is_empty() {
None
} else {
Some(Value::string(s, head))

View File

@ -94,6 +94,13 @@ END:VCALENDAR' | from ics",
fn from_ics(input: PipelineData, head: Span, config: &Config) -> Result<PipelineData, ShellError> {
let input_string = input.collect_string("", config)?;
let input_string = input_string
.lines()
.map(|x| x.trim().to_string())
.collect::<Vec<_>>()
.join("\n");
let input_bytes = input_string.as_bytes();
let buf_reader = BufReader::new(input_bytes);
let parser = ical::IcalParser::new(buf_reader);
@ -103,9 +110,9 @@ fn from_ics(input: PipelineData, head: Span, config: &Config) -> Result<Pipeline
for calendar in parser {
match calendar {
Ok(c) => output.push(calendar_to_value(c, head)),
Err(_) => output.push(Value::Error {
Err(e) => output.push(Value::Error {
error: ShellError::UnsupportedInput(
"input cannot be parsed as .ics".to_string(),
format!("input cannot be parsed as .ics ({})", e),
head,
),
}),

View File

@ -125,14 +125,24 @@ END:VCARD' | from vcf",
fn from_vcf(input: PipelineData, head: Span, config: &Config) -> Result<PipelineData, ShellError> {
let input_string = input.collect_string("", config)?;
let input_string = input_string
.lines()
.map(|x| x.trim().to_string())
.collect::<Vec<_>>()
.join("\n");
let input_bytes = input_string.as_bytes();
let cursor = std::io::Cursor::new(input_bytes);
let parser = ical::VcardParser::new(cursor);
let iter = parser.map(move |contact| match contact {
Ok(c) => contact_to_value(c, head),
Err(_) => Value::Error {
error: ShellError::UnsupportedInput("input cannot be parsed as .vcf".to_string(), head),
Err(e) => Value::Error {
error: ShellError::UnsupportedInput(
format!("input cannot be parsed as .vcf ({})", e),
head,
),
},
});

View File

@ -265,7 +265,7 @@ fn helper(
Some(converter_id) => engine_state.get_decl(converter_id).run(
engine_state,
stack,
&Call::new(),
&Call::new(span),
output,
),
None => Ok(output),

View File

@ -2,14 +2,14 @@ use nu_engine::CallExt;
use nu_protocol::{
ast::{Call, CellPath},
engine::{Command, EngineState, Stack},
Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Value,
};
#[derive(Clone)]
pub struct SubCommand;
struct Arguments {
character: Option<Value>,
character: Option<Spanned<String>>,
column_paths: Vec<CellPath>,
}
@ -143,7 +143,16 @@ where
input,
);
let to_trim = match options.character.as_ref() {
Some(v) => v.as_string()?.chars().next(),
Some(v) => {
if v.item.chars().count() > 1 {
return Err(ShellError::SpannedLabeledError(
"Trim only works with single character".into(),
"needs single character".into(),
v.span,
));
}
v.item.chars().next()
}
None => None,
};

View File

@ -220,7 +220,7 @@ impl ExternalCommand {
&crate::Table,
&engine_state,
&mut stack,
&Call::new(),
&Call::new(head),
input,
);

View File

@ -0,0 +1,57 @@
use nu_test_support::{nu, pipeline};
#[test]
fn checks_all_rows_are_true() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [ "Andrés", "Andrés", "Andrés" ]
| all? $it == "Andrés"
"#
));
assert_eq!(actual.out, "true");
}
#[test]
fn checks_all_rows_are_false_with_param() {
let actual = nu!(
cwd: ".", pipeline(
r#"
[1, 2, 3, 4] | all? { |a| $a >= 5 }
"#
));
assert_eq!(actual.out, "false");
}
#[test]
fn checks_all_rows_are_true_with_param() {
let actual = nu!(
cwd: ".", pipeline(
r#"
[1, 2, 3, 4] | all? { |a| $a < 5 }
"#
));
assert_eq!(actual.out, "true");
}
#[test]
fn checks_all_columns_of_a_table_is_true() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [
[ first_name, last_name, rusty_at, likes ];
[ Andrés, Robalino, 10/11/2013, 1 ]
[ Jonathan, Turner, 10/12/2013, 1 ]
[ Darren, Schroeder, 10/11/2013, 1 ]
[ Yehuda, Katz, 10/11/2013, 1 ]
]
| all? likes > 0
"#
));
assert_eq!(actual.out, "true");
}

View File

@ -0,0 +1,33 @@
use nu_test_support::{nu, pipeline};
#[test]
fn checks_any_row_is_true() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [ "Ecuador", "USA", "New Zealand" ]
| any? $it == "New Zealand"
"#
));
assert_eq!(actual.out, "true");
}
#[test]
fn checks_any_column_of_a_table_is_true() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [
[ first_name, last_name, rusty_at, likes ];
[ Andrés, Robalino, 10/11/2013, 1 ]
[ Jonathan, Turner, 10/12/2013, 1 ]
[ Darren, Schroeder, 10/11/2013, 1 ]
[ Yehuda, Katz, 10/11/2013, 1 ]
]
| any? rusty_at == 10/12/2013
"#
));
assert_eq!(actual.out, "true");
}

View File

@ -0,0 +1,15 @@
use nu_test_support::{nu, pipeline};
#[test]
fn adds_a_row_to_the_end() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [ "Andrés N. Robalino", "Jonathan Turner", "Yehuda Katz" ]
| append "pollo loco"
| nth 3
"#
));
assert_eq!(actual.out, "pollo loco");
}

View File

@ -0,0 +1,87 @@
use nu_test_support::{nu, pipeline};
// FIXME: jt: needs more work
#[ignore]
#[test]
fn cal_full_year() {
let actual = nu!(
cwd: ".", pipeline(
r#"
cal -y --full-year 2010 | first | to json
"#
));
let first_week_2010_json = r#"{"year":2010,"sunday":null,"monday":null,"tuesday":null,"wednesday":null,"thursday":null,"friday":1,"saturday":2}"#;
assert_eq!(actual.out, first_week_2010_json);
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn cal_february_2020_leap_year() {
let actual = nu!(
cwd: ".", pipeline(
r#"
cal -ym --full-year 2020 --month-names | where month == "february" | to json
"#
));
let cal_february_json = r#"[{"year":2020,"month":"february","sunday":null,"monday":null,"tuesday":null,"wednesday":null,"thursday":null,"friday":null,"saturday":1},{"year":2020,"month":"february","sunday":2,"monday":3,"tuesday":4,"wednesday":5,"thursday":6,"friday":7,"saturday":8},{"year":2020,"month":"february","sunday":9,"monday":10,"tuesday":11,"wednesday":12,"thursday":13,"friday":14,"saturday":15},{"year":2020,"month":"february","sunday":16,"monday":17,"tuesday":18,"wednesday":19,"thursday":20,"friday":21,"saturday":22},{"year":2020,"month":"february","sunday":23,"monday":24,"tuesday":25,"wednesday":26,"thursday":27,"friday":28,"saturday":29}]"#;
assert_eq!(actual.out, cal_february_json);
}
#[test]
fn cal_friday_the_thirteenths_in_2015() {
let actual = nu!(
cwd: ".", pipeline(
r#"
cal --full-year 2015 | default friday 0 | where friday == 13 | length
"#
));
assert!(actual.out.contains('3'));
}
#[test]
fn cal_rows_in_2020() {
let actual = nu!(
cwd: ".", pipeline(
r#"
cal --full-year 2020 | length
"#
));
assert!(actual.out.contains("62"));
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn cal_week_day_start_monday() {
let actual = nu!(
cwd: ".", pipeline(
r#"
cal --full-year 2020 -m --month-names --week-start monday | where month == january | to json
"#
));
let cal_january_json = r#"[{"month":"january","monday":null,"tuesday":null,"wednesday":1,"thursday":2,"friday":3,"saturday":4,"sunday":5},{"month":"january","monday":6,"tuesday":7,"wednesday":8,"thursday":9,"friday":10,"saturday":11,"sunday":12},{"month":"january","monday":13,"tuesday":14,"wednesday":15,"thursday":16,"friday":17,"saturday":18,"sunday":19},{"month":"january","monday":20,"tuesday":21,"wednesday":22,"thursday":23,"friday":24,"saturday":25,"sunday":26},{"month":"january","monday":27,"tuesday":28,"wednesday":29,"thursday":30,"friday":31,"saturday":null,"sunday":null}]"#;
assert_eq!(actual.out, cal_january_json);
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn cal_sees_pipeline_year() {
let actual = nu!(
cwd: ".", pipeline(
r#"
cal --full-year 1020 | get monday | first 3 | to json
"#
));
assert_eq!(actual.out, "[3,10,17]");
}

View File

@ -0,0 +1,277 @@
use nu_test_support::fs::Stub::EmptyFile;
use nu_test_support::nu;
use nu_test_support::playground::Playground;
use std::path::PathBuf;
// FIXME: jt: needs more work
#[ignore]
#[test]
fn filesystem_change_from_current_directory_using_relative_path() {
Playground::setup("cd_test_1", |dirs, _| {
let actual = nu!(
cwd: dirs.root(),
r#"
cd cd_test_1
echo (pwd)
"#
);
assert_eq!(PathBuf::from(actual.out), *dirs.test());
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn filesystem_change_from_current_directory_using_absolute_path() {
Playground::setup("cd_test_2", |dirs, _| {
let actual = nu!(
cwd: dirs.test(),
r#"
cd "{}"
echo (pwd)
"#,
dirs.formats()
);
assert_eq!(PathBuf::from(actual.out), dirs.formats());
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn filesystem_switch_back_to_previous_working_directory() {
Playground::setup("cd_test_3", |dirs, sandbox| {
sandbox.mkdir("odin");
let actual = nu!(
cwd: dirs.test().join("odin"),
r#"
cd {}
cd -
echo (pwd)
"#,
dirs.test()
);
assert_eq!(PathBuf::from(actual.out), dirs.test().join("odin"));
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn filesytem_change_from_current_directory_using_relative_path_and_dash() {
Playground::setup("cd_test_4", |dirs, sandbox| {
sandbox.within("odin").mkdir("-");
let actual = nu!(
cwd: dirs.test(),
r#"
cd odin/-
echo (pwd)
"#
);
assert_eq!(
PathBuf::from(actual.out),
dirs.test().join("odin").join("-")
);
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn filesystem_change_current_directory_to_parent_directory() {
Playground::setup("cd_test_5", |dirs, _| {
let actual = nu!(
cwd: dirs.test(),
r#"
cd ..
echo (pwd)
"#
);
assert_eq!(PathBuf::from(actual.out), *dirs.root());
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn filesystem_change_current_directory_to_two_parents_up_using_multiple_dots() {
Playground::setup("cd_test_6", |dirs, sandbox| {
sandbox.within("foo").mkdir("bar");
let actual = nu!(
cwd: dirs.test().join("foo/bar"),
r#"
cd ...
echo (pwd)
"#
);
assert_eq!(PathBuf::from(actual.out), *dirs.test());
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn filesystem_change_current_directory_to_parent_directory_after_delete_cwd() {
Playground::setup("cd_test_7", |dirs, sandbox| {
sandbox.within("foo").mkdir("bar");
let actual = nu!(
cwd: dirs.test().join("foo/bar"),
r#"
rm {}/foo/bar
echo ","
cd ..
echo (pwd)
"#,
dirs.test()
);
let actual = actual.out.split(',').nth(1).unwrap();
assert_eq!(PathBuf::from(actual), *dirs.test().join("foo"));
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn filesystem_change_to_home_directory() {
Playground::setup("cd_test_8", |dirs, _| {
let actual = nu!(
cwd: dirs.test(),
r#"
cd ~
echo (pwd)
"#
);
assert_eq!(Some(PathBuf::from(actual.out)), dirs_next::home_dir());
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn filesystem_change_to_a_directory_containing_spaces() {
Playground::setup("cd_test_9", |dirs, sandbox| {
sandbox.mkdir("robalino turner katz");
let actual = nu!(
cwd: dirs.test(),
r#"
cd "robalino turner katz"
echo (pwd)
"#
);
assert_eq!(
PathBuf::from(actual.out),
dirs.test().join("robalino turner katz")
);
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn filesystem_not_a_directory() {
Playground::setup("cd_test_10", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("ferris_did_it.txt")]);
let actual = nu!(
cwd: dirs.test(),
"cd ferris_did_it.txt"
);
assert!(
actual.err.contains("ferris_did_it.txt"),
"actual={:?}",
actual.err
);
assert!(
actual.err.contains("is not a directory"),
"actual={:?}",
actual.err
);
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn filesystem_directory_not_found() {
Playground::setup("cd_test_11", |dirs, _| {
let actual = nu!(
cwd: dirs.test(),
"cd dir_that_does_not_exist"
);
assert!(
actual.err.contains("dir_that_does_not_exist"),
"actual={:?}",
actual.err
);
assert!(
actual.err.contains("directory not found"),
"actual={:?}",
actual.err
);
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn filesystem_change_directory_to_symlink_relative() {
Playground::setup("cd_test_12", |dirs, sandbox| {
sandbox.mkdir("foo");
sandbox.mkdir("boo");
sandbox.symlink("foo", "foo_link");
let actual = nu!(
cwd: dirs.test().join("boo"),
r#"
cd ../foo_link
echo (pwd)
"#
);
assert_eq!(PathBuf::from(actual.out), dirs.test().join("foo"));
})
}
// FIXME: jt: needs more work
#[ignore]
#[cfg(target_os = "windows")]
#[test]
fn test_change_windows_drive() {
Playground::setup("cd_test_20", |dirs, sandbox| {
sandbox.mkdir("test_folder");
let _actual = nu!(
cwd: dirs.test(),
r#"
subst Z: test_folder
Z:
echo "some text" | save test_file.txt
cd ~
subst Z: /d
"#
);
assert!(dirs
.test()
.join("test_folder")
.join("test_file.txt")
.exists());
})
}

View File

@ -0,0 +1,50 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn discards_rows_where_given_column_is_empty() {
Playground::setup("compact_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_amigos.json",
r#"
{
"amigos": [
{"name": "Yehuda", "rusty_luck": 1},
{"name": "Jonathan", "rusty_luck": 1},
{"name": "Andres", "rusty_luck": 1},
{"name":"GorbyPuff"}
]
}
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_amigos.json
| get amigos
| compact rusty_luck
| length
"#
));
assert_eq!(actual.out, "3");
});
}
#[test]
fn discards_empty_rows_by_default() {
Playground::setup("compact_test_2", |dirs, _| {
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo "[1,2,3,14,null]"
| from json
| compact
| length
"#
));
assert_eq!(actual.out, "4");
});
}

View File

@ -0,0 +1,241 @@
use nu_test_support::fs::{files_exist_at, AbsoluteFile, Stub::EmptyFile};
use nu_test_support::nu;
use nu_test_support::playground::Playground;
use std::path::Path;
#[test]
fn copies_a_file() {
Playground::setup("cp_test_1", |dirs, _| {
nu!(
cwd: dirs.root(),
"cp \"{}\" cp_test_1/sample.ini",
dirs.formats().join("sample.ini")
);
assert!(dirs.test().join("sample.ini").exists());
});
}
#[test]
fn copies_the_file_inside_directory_if_path_to_copy_is_directory() {
Playground::setup("cp_test_2", |dirs, _| {
let expected_file = AbsoluteFile::new(dirs.test().join("sample.ini"));
nu!(
cwd: dirs.formats(),
"cp ../formats/sample.ini {}",
expected_file.dir()
);
assert!(dirs.test().join("sample.ini").exists());
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn error_if_attempting_to_copy_a_directory_to_another_directory() {
Playground::setup("cp_test_3", |dirs, _| {
let actual = nu!(
cwd: dirs.formats(),
"cp ../formats {}", dirs.test()
);
assert!(actual.err.contains("../formats"));
assert!(actual.err.contains("resolves to a directory (not copied)"));
});
}
#[test]
fn copies_the_directory_inside_directory_if_path_to_copy_is_directory_and_with_recursive_flag() {
Playground::setup("cp_test_4", |dirs, sandbox| {
sandbox
.within("originals")
.with_files(vec![
EmptyFile("yehuda.txt"),
EmptyFile("jonathan.txt"),
EmptyFile("andres.txt"),
])
.mkdir("expected");
let expected_dir = dirs.test().join("expected").join("originals");
nu!(
cwd: dirs.test(),
"cp originals expected -r"
);
assert!(expected_dir.exists());
assert!(files_exist_at(
vec![
Path::new("yehuda.txt"),
Path::new("jonathan.txt"),
Path::new("andres.txt")
],
expected_dir
));
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn deep_copies_with_recursive_flag() {
Playground::setup("cp_test_5", |dirs, sandbox| {
sandbox
.within("originals")
.with_files(vec![EmptyFile("manifest.txt")])
.within("originals/contributors")
.with_files(vec![
EmptyFile("yehuda.txt"),
EmptyFile("jonathan.txt"),
EmptyFile("andres.txt"),
])
.within("originals/contributors/jonathan")
.with_files(vec![EmptyFile("errors.txt"), EmptyFile("multishells.txt")])
.within("originals/contributors/andres")
.with_files(vec![EmptyFile("coverage.txt"), EmptyFile("commands.txt")])
.within("originals/contributors/yehuda")
.with_files(vec![EmptyFile("defer-evaluation.txt")])
.mkdir("expected");
let expected_dir = dirs.test().join("expected").join("originals");
let jonathans_expected_copied_dir = expected_dir.join("contributors").join("jonathan");
let andres_expected_copied_dir = expected_dir.join("contributors").join("andres");
let yehudas_expected_copied_dir = expected_dir.join("contributors").join("yehuda");
nu!(
cwd: dirs.test(),
"cp originals expected --recursive"
);
assert!(expected_dir.exists());
assert!(files_exist_at(
vec![Path::new("errors.txt"), Path::new("multishells.txt")],
jonathans_expected_copied_dir
));
assert!(files_exist_at(
vec![Path::new("coverage.txt"), Path::new("commands.txt")],
andres_expected_copied_dir
));
assert!(files_exist_at(
vec![Path::new("defer-evaluation.txt")],
yehudas_expected_copied_dir
));
})
}
#[test]
fn copies_using_path_with_wildcard() {
Playground::setup("cp_test_6", |dirs, _| {
nu!(
cwd: dirs.formats(),
"cp ../formats/* {}", dirs.test()
);
assert!(files_exist_at(
vec![
Path::new("caco3_plastics.csv"),
Path::new("cargo_sample.toml"),
Path::new("jonathan.xml"),
Path::new("sample.ini"),
Path::new("sgml_description.json"),
Path::new("utf16.ini"),
],
dirs.test()
));
})
}
#[test]
fn copies_using_a_glob() {
Playground::setup("cp_test_7", |dirs, _| {
nu!(
cwd: dirs.formats(),
"cp * {}", dirs.test()
);
assert!(files_exist_at(
vec![
Path::new("caco3_plastics.csv"),
Path::new("cargo_sample.toml"),
Path::new("jonathan.xml"),
Path::new("sample.ini"),
Path::new("sgml_description.json"),
Path::new("utf16.ini"),
],
dirs.test()
));
});
}
#[test]
fn copies_same_file_twice() {
Playground::setup("cp_test_8", |dirs, _| {
nu!(
cwd: dirs.root(),
"cp \"{}\" cp_test_8/sample.ini",
dirs.formats().join("sample.ini")
);
nu!(
cwd: dirs.root(),
"cp \"{}\" cp_test_8/sample.ini",
dirs.formats().join("sample.ini")
);
assert!(dirs.test().join("sample.ini").exists());
});
}
#[test]
fn copy_files_using_glob_two_parents_up_using_multiple_dots() {
Playground::setup("cp_test_9", |dirs, sandbox| {
sandbox.within("foo").within("bar").with_files(vec![
EmptyFile("jonathan.json"),
EmptyFile("andres.xml"),
EmptyFile("yehuda.yaml"),
EmptyFile("kevin.txt"),
EmptyFile("many_more.ppl"),
]);
nu!(
cwd: dirs.test().join("foo/bar"),
r#"
cp * ...
"#
);
assert!(files_exist_at(
vec![
"yehuda.yaml",
"jonathan.json",
"andres.xml",
"kevin.txt",
"many_more.ppl",
],
dirs.test()
));
})
}
#[test]
fn copy_file_and_dir_from_two_parents_up_using_multiple_dots_to_current_dir_recursive() {
Playground::setup("cp_test_10", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("hello_there")]);
sandbox.mkdir("hello_again");
sandbox.within("foo").mkdir("bar");
nu!(
cwd: dirs.test().join("foo/bar"),
r#"
cp -r .../hello* .
"#
);
let expected = dirs.test().join("foo/bar");
assert!(files_exist_at(vec!["hello_there", "hello_again"], expected));
})
}

View File

@ -0,0 +1,22 @@
use nu_test_support::nu;
use nu_test_support::playground::Playground;
use std::fs;
// FIXME: jt: needs more work
#[ignore]
#[test]
fn def_with_comment() {
Playground::setup("def_with_comment", |dirs, _| {
let data = r#"
#My echo
def e [arg] {echo $arg}
"#;
fs::write(dirs.root().join("def_test"), data).expect("Unable to write file");
let actual = nu!(
cwd: dirs.root(),
"source def_test; help e | to json"
);
assert!(actual.out.contains("My echo\\n\\n"));
});
}

View File

@ -0,0 +1,35 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn adds_row_data_if_column_missing() {
Playground::setup("default_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_amigos.json",
r#"
{
"amigos": [
{"name": "Yehuda"},
{"name": "Jonathan", "rusty_luck": 0},
{"name": "Andres", "rusty_luck": 0},
{"name":"GorbyPuff"}
]
}
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_amigos.json
| get amigos
| default rusty_luck 1
| where rusty_luck == 1
| length
"#
));
assert_eq!(actual.out, "2");
});
}

View File

@ -0,0 +1,72 @@
use nu_test_support::{nu, pipeline};
// FIXME: jt: needs more work
#[ignore]
#[test]
fn columns() {
let actual = nu!(
cwd: ".", pipeline(r#"
echo [
[arepas, color];
[3, white]
[8, yellow]
[4, white]
]
| drop column
| get
| length
"#)
);
assert_eq!(actual.out, "1");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn more_columns_than_table_has() {
let actual = nu!(
cwd: ".", pipeline(r#"
echo [
[arepas, color];
[3, white]
[8, yellow]
[4, white]
]
| drop column 3
| get
| empty?
"#)
);
assert_eq!(actual.out, "true");
}
#[test]
fn rows() {
let actual = nu!(
cwd: ".", pipeline(r#"
echo [
[arepas];
[3]
[8]
[4]
]
| drop 2
| get arepas
| math sum
"#)
);
assert_eq!(actual.out, "3");
}
#[test]
fn more_rows_than_table_has() {
let actual = nu!(cwd: ".", "date | drop 50 | length");
assert_eq!(actual.out, "0");
}

View File

@ -0,0 +1,83 @@
use nu_test_support::{nu, pipeline};
// FIXME: jt: needs more work
#[ignore]
#[test]
fn each_works_separately() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
echo [1 2 3] | each { echo $it 10 | math sum } | to json
"#
));
assert_eq!(actual.out, "[11,12,13]");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn each_group_works() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
echo [1 2 3 4 5 6] | each group 3 { $it } | to json
"#
));
assert_eq!(actual.out, "[[1,2,3],[4,5,6]]");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn each_window() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
echo [1 2 3 4] | each window 3 { $it } | to json
"#
));
assert_eq!(actual.out, "[[1,2,3],[2,3,4]]");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn each_window_stride() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
echo [1 2 3 4 5 6] | each window 3 -s 2 { echo $it } | to json
"#
));
assert_eq!(actual.out, "[[1,2,3],[3,4,5]]");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn each_no_args_in_block() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
echo [[foo bar]; [a b] [c d] [e f]] | each { to json } | nth 1 | str collect
"#
));
assert_eq!(actual.out, r#"{"foo":"c","bar":"d"}"#);
}
#[test]
fn each_implicit_it_in_block() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
echo [[foo bar]; [a b] [c d] [e f]] | each { nu --testbin cococo $it.foo }
"#
));
assert_eq!(actual.out, "ace");
}

View File

@ -0,0 +1,61 @@
use nu_test_support::{nu, pipeline};
#[test]
fn echo_range_is_lazy() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
echo 1..10000000000 | first 3 | to json --raw
"#
));
assert_eq!(actual.out, "[1,2,3]");
}
#[test]
fn echo_range_handles_inclusive() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
echo 1..3 | each { $it } | to json --raw
"#
));
assert_eq!(actual.out, "[1,2,3]");
}
#[test]
fn echo_range_handles_exclusive() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
echo 1..<3 | each { $it } | to json --raw
"#
));
assert_eq!(actual.out, "[1,2]");
}
#[test]
fn echo_range_handles_inclusive_down() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
echo 3..1 | each { $it } | to json --raw
"#
));
assert_eq!(actual.out, "[3,2,1]");
}
#[test]
fn echo_range_handles_exclusive_down() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
echo 3..<1 | each { $it } | to json --raw
"#
));
assert_eq!(actual.out, "[3,2]");
}

View File

@ -0,0 +1,94 @@
use nu_test_support::{nu, pipeline};
// FIXME: jt: needs more work
#[ignore]
#[test]
fn reports_emptiness() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [[are_empty];
[([[check]; [[]] ])]
[([[check]; [""] ])]
[([[check]; [(wrap)] ])]
]
| get are_empty
| empty? check
| where check
| length
"#
));
assert_eq!(actual.out, "3");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn sets_block_run_value_for_an_empty_column() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [
[ first_name, last_name, rusty_at, likes ];
[ Andrés, Robalino, 10/11/2013, 1 ]
[ Jonathan, Turner, 10/12/2013, 1 ]
[ Jason, Gedge, 10/11/2013, 1 ]
[ Yehuda, Katz, 10/11/2013, '' ]
]
| empty? likes -b { 1 }
| get likes
| math sum
"#
));
assert_eq!(actual.out, "4");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn sets_block_run_value_for_many_empty_columns() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [
[ boost check ];
[ 1, [] ]
[ 1, "" ]
[ 1, (wrap) ]
]
| empty? boost check -b { 1 }
| get boost check
| math sum
"#
));
assert_eq!(actual.out, "6");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn passing_a_block_will_set_contents_on_empty_cells_and_leave_non_empty_ones_untouched() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [
[ NAME, LVL, HP ];
[ Andrés, 30, 3000 ]
[ Alistair, 29, 2900 ]
[ Arepas, "", "" ]
[ Jorge, 30, 3000 ]
]
| empty? LVL -b { 9 }
| empty? HP -b {
$it.LVL * 1000
}
| math sum
| get HP
"#
));
assert_eq!(actual.out, "17900");
}

View File

@ -0,0 +1,73 @@
use nu_test_support::fs::{files_exist_at, Stub::EmptyFile};
use nu_test_support::nu;
use nu_test_support::playground::Playground;
use std::path::Path;
#[test]
fn knows_the_filesystems_entered() {
Playground::setup("enter_test_1", |dirs, sandbox| {
sandbox
.within("red_pill")
.with_files(vec![
EmptyFile("andres.nu"),
EmptyFile("jonathan.nu"),
EmptyFile("yehuda.nu"),
])
.within("blue_pill")
.with_files(vec![
EmptyFile("bash.nxt"),
EmptyFile("korn.nxt"),
EmptyFile("powedsh.nxt"),
])
.mkdir("expected");
let red_pill_dir = dirs.test().join("red_pill");
let blue_pill_dir = dirs.test().join("blue_pill");
let expected = dirs.test().join("expected");
let expected_recycled = expected.join("recycled");
nu!(
cwd: dirs.test(),
r#"
enter expected
mkdir recycled
enter ../red_pill
mv jonathan.nu ../expected
enter ../blue_pill
cp *.nxt ../expected/recycled
p
p
mv ../red_pill/yehuda.nu .
n
mv andres.nu ../expected/andres.nu
exit
cd ..
rm red_pill --recursive
exit
n
rm blue_pill --recursive
exit
"#
);
assert!(!red_pill_dir.exists());
assert!(files_exist_at(
vec![
Path::new("andres.nu"),
Path::new("jonathan.nu"),
Path::new("yehuda.nu"),
],
expected
));
assert!(!blue_pill_dir.exists());
assert!(files_exist_at(
vec![
Path::new("bash.nxt"),
Path::new("korn.nxt"),
Path::new("powedsh.nxt"),
],
expected_recycled
));
})
}

View File

@ -0,0 +1,211 @@
use nu_test_support::fs::Stub::EmptyFile;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn gets_all_rows_by_every_zero() {
Playground::setup("every_test_1", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("amigos.txt"),
EmptyFile("arepas.clu"),
EmptyFile("los.txt"),
EmptyFile("tres.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| get name
| every 0
| to json --raw
"#
));
assert_eq!(
actual.out,
r#"["amigos.txt","arepas.clu","los.txt","tres.txt"]"#
);
})
}
#[test]
fn gets_no_rows_by_every_skip_zero() {
Playground::setup("every_test_2", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("amigos.txt"),
EmptyFile("arepas.clu"),
EmptyFile("los.txt"),
EmptyFile("tres.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| get name
| every 0 --skip
| to json --raw
"#
));
assert_eq!(actual.out, "[]");
})
}
#[test]
fn gets_all_rows_by_every_one() {
Playground::setup("every_test_3", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("amigos.txt"),
EmptyFile("arepas.clu"),
EmptyFile("los.txt"),
EmptyFile("tres.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| get name
| every 1
| to json --raw
"#
));
assert_eq!(
actual.out,
r#"["amigos.txt","arepas.clu","los.txt","tres.txt"]"#
);
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn gets_no_rows_by_every_skip_one() {
Playground::setup("every_test_4", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("amigos.txt"),
EmptyFile("arepas.clu"),
EmptyFile("los.txt"),
EmptyFile("tres.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| get name
| every 1 --skip
| to json --raw
"#
));
assert_eq!(actual.out, "");
})
}
#[test]
fn gets_first_row_by_every_too_much() {
Playground::setup("every_test_5", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("amigos.txt"),
EmptyFile("arepas.clu"),
EmptyFile("los.txt"),
EmptyFile("tres.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| get name
| every 999
"#
));
let expected = nu!(
cwd: dirs.test(), pipeline(
r#"
echo [ amigos.txt ]
"#
));
assert_eq!(actual.out, expected.out);
})
}
#[test]
fn gets_all_rows_except_first_by_every_skip_too_much() {
Playground::setup("every_test_6", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("amigos.txt"),
EmptyFile("arepas.clu"),
EmptyFile("los.txt"),
EmptyFile("tres.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| get name
| every 999 --skip
| to json --raw
"#
));
assert_eq!(actual.out, r#"["arepas.clu","los.txt","tres.txt"]"#);
})
}
#[test]
fn gets_every_third_row() {
Playground::setup("every_test_7", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("amigos.txt"),
EmptyFile("arepas.clu"),
EmptyFile("los.txt"),
EmptyFile("quatro.txt"),
EmptyFile("tres.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| get name
| every 3
| to json --raw
"#
));
assert_eq!(actual.out, r#"["amigos.txt","quatro.txt"]"#);
})
}
#[test]
fn skips_every_third_row() {
Playground::setup("every_test_8", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("amigos.txt"),
EmptyFile("arepas.clu"),
EmptyFile("los.txt"),
EmptyFile("quatro.txt"),
EmptyFile("tres.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| get name
| every 3 --skip
| to json --raw
"#
));
assert_eq!(actual.out, r#"["arepas.clu","los.txt","tres.txt"]"#);
})
}

View File

@ -0,0 +1,117 @@
use nu_test_support::fs::Stub::EmptyFile;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn find_with_list_search_with_string() {
let actual = nu!(
cwd: ".", pipeline(
r#"
[moe larry curly] | find moe
"#
));
assert_eq!(actual.out, "moe");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn find_with_list_search_with_char() {
let actual = nu!(
cwd: ".", pipeline(
r#"
[moe larry curly] | find l | to json
"#
));
assert_eq!(actual.out, r#"["larry","curly"]"#);
}
#[test]
fn find_with_list_search_with_number() {
let actual = nu!(
cwd: ".", pipeline(
r#"
[1 2 3 4 5] | find 3
"#
));
assert_eq!(actual.out, "3");
}
#[test]
fn find_with_string_search_with_string() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo Cargo.toml | find toml
"#
));
assert_eq!(actual.out, "Cargo.toml");
}
#[test]
fn find_with_string_search_with_string_not_found() {
let actual = nu!(
cwd: ".", pipeline(
r#"
[moe larry curly] | find shemp
"#
));
assert_eq!(actual.out, "");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn find_with_filepath_search_with_string() {
Playground::setup("filepath_test_1", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("amigos.txt"),
EmptyFile("arepas.clu"),
EmptyFile("los.txt"),
EmptyFile("tres.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| get name
| find arep
| to json
"#
));
assert_eq!(actual.out, r#""arepas.clu""#);
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn find_with_filepath_search_with_multiple_patterns() {
Playground::setup("filepath_test_2", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("amigos.txt"),
EmptyFile("arepas.clu"),
EmptyFile("los.txt"),
EmptyFile("tres.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| get name
| find arep ami
| to json
"#
));
assert_eq!(actual.out, r#"["amigos.txt","arepas.clu"]"#);
})
}

View File

@ -0,0 +1,67 @@
use nu_test_support::fs::Stub::EmptyFile;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn gets_first_rows_by_amount() {
Playground::setup("first_test_1", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("los.txt"),
EmptyFile("tres.txt"),
EmptyFile("amigos.txt"),
EmptyFile("arepas.clu"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| first 3
| length
"#
));
assert_eq!(actual.out, "3");
})
}
#[test]
fn gets_all_rows_if_amount_higher_than_all_rows() {
Playground::setup("first_test_2", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("los.txt"),
EmptyFile("tres.txt"),
EmptyFile("amigos.txt"),
EmptyFile("arepas.clu"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| first 99
| length
"#
));
assert_eq!(actual.out, "4");
})
}
#[test]
fn gets_first_row_when_no_amount_given() {
Playground::setup("first_test_3", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("caballeros.txt"), EmptyFile("arepas.clu")]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| first
| length
"#
));
assert_eq!(actual.out, "1");
})
}

View File

@ -0,0 +1,192 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
// FIXME: jt: needs more work
#[ignore]
#[test]
fn flatten_nested_tables_with_columns() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [[origin, people]; [Ecuador, ('Andres' | wrap name)]]
[[origin, people]; [Nu, ('nuno' | wrap name)]]
| flatten
| get name
| str collect ','
"#
));
assert_eq!(actual.out, "Andres,nuno");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn flatten_nested_tables_that_have_many_columns() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [[origin, people]; [Ecuador, (echo [[name, meal]; ['Andres', 'arepa']])]]
[[origin, people]; [USA, (echo [[name, meal]; ['Katz', 'nurepa']])]]
| flatten
| get meal
| str collect ','
"#
));
assert_eq!(actual.out, "arepa,nurepa");
}
#[test]
fn flatten_nested_tables() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [[Andrés, Nicolás, Robalino]] | flatten | nth 1
"#
));
assert_eq!(actual.out, "Nicolás");
}
#[test]
fn flatten_row_column_explicitly() {
Playground::setup("flatten_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"katz.json",
r#"
[
{
"people": {
"name": "Andres",
"meal": "arepa"
}
},
{
"people": {
"name": "Katz",
"meal": "nurepa"
}
}
]
"#,
)]);
let actual = nu!(
cwd: dirs.test(),
"open katz.json | flatten people | where name == Andres | length"
);
assert_eq!(actual.out, "1");
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn flatten_row_columns_having_same_column_names_flats_separately() {
Playground::setup("flatten_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"katz.json",
r#"
[
{
"people": {
"name": "Andres",
"meal": "arepa"
},
"city": [{"name": "Guayaquil"}, {"name": "Samborondón"}]
},
{
"people": {
"name": "Katz",
"meal": "nurepa"
},
"city": [{"name": "Oregon"}, {"name": "Brooklin"}]
}
]
"#,
)]);
let actual = nu!(
cwd: dirs.test(),
"open katz.json | flatten | flatten people city | get city_name | length"
);
assert_eq!(actual.out, "4");
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn flatten_table_columns_explicitly() {
Playground::setup("flatten_test_3", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"katz.json",
r#"
[
{
"people": {
"name": "Andres",
"meal": "arepa"
},
"city": ["Guayaquil", "Samborondón"]
},
{
"people": {
"name": "Katz",
"meal": "nurepa"
},
"city": ["Oregon", "Brooklin"]
}
]
"#,
)]);
let actual = nu!(
cwd: dirs.test(),
"open katz.json | flatten city | where people.name == Katz | length"
);
assert_eq!(actual.out, "2");
})
}
#[test]
fn flatten_more_than_one_column_that_are_subtables_not_supported() {
Playground::setup("flatten_test_4", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"katz.json",
r#"
[
{
"people": {
"name": "Andres",
"meal": "arepa"
}
"tags": ["carbohydrate", "corn", "maiz"],
"city": ["Guayaquil", "Samborondón"]
},
{
"people": {
"name": "Katz",
"meal": "nurepa"
},
"tags": ["carbohydrate", "shell food", "amigos flavor"],
"city": ["Oregon", "Brooklin"]
}
]
"#,
)]);
let actual = nu!(
cwd: dirs.test(),
"open katz.json | flatten tags city"
);
assert!(actual.err.contains("tried flattening"));
assert!(actual.err.contains("but is flattened already"));
})
}

View File

@ -0,0 +1,101 @@
use nu_test_support::fs::Stub::{EmptyFile, FileWithContentToBeTrimmed};
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn creates_the_resulting_string_from_the_given_fields() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open cargo_sample.toml
| get package
| format "{name} has license {license}"
"#
));
assert_eq!(actual.out, "nu has license ISC");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn given_fields_can_be_column_paths() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open cargo_sample.toml
| format "{package.name} is {package.description}"
"#
));
assert_eq!(actual.out, "nu is a new type of shell");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn can_use_variables() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open cargo_sample.toml
| format "{$it.package.name} is {$it.package.description}"
"#
));
assert_eq!(actual.out, "nu is a new type of shell");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn format_filesize_works() {
Playground::setup("format_filesize_test_1", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("yehuda.txt"),
EmptyFile("jonathan.txt"),
EmptyFile("andres.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| format filesize size KB
| get size
| first
"#
));
assert_eq!(actual.out, "0.0 KB");
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn format_filesize_works_with_nonempty_files() {
Playground::setup(
"format_filesize_works_with_nonempty_files",
|dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"sample.toml",
r#"
[dependency]
name = "nu"
"#,
)]);
let actual = nu!(
cwd: dirs.test(),
"ls sample.toml | format filesize size B | get size | first"
);
#[cfg(not(windows))]
assert_eq!(actual.out, "25");
#[cfg(windows)]
assert_eq!(actual.out, "27");
},
)
}

View File

@ -0,0 +1,229 @@
use nu_test_support::fs::Stub::FileWithContent;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn fetches_a_row() {
Playground::setup("get_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
nu_party_venue = "zion"
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| get nu_party_venue
"#
));
assert_eq!(actual.out, "zion");
})
}
#[test]
fn fetches_by_index() {
Playground::setup("get_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[package]
name = "nu"
version = "0.4.1"
authors = ["Yehuda Katz <wycats@gmail.com>", "Jonathan Turner <jonathan.d.turner@gmail.com>", "Andrés N. Robalino <andres@androbtech.com>"]
description = "When arepas shells are tasty and fun."
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| get package.authors.2
"#
));
assert_eq!(actual.out, "Andrés N. Robalino <andres@androbtech.com>");
})
}
#[test]
fn fetches_by_column_path() {
Playground::setup("get_test_3", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[package]
name = "nu"
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| get package.name
"#
));
assert_eq!(actual.out, "nu");
})
}
#[test]
fn column_paths_are_either_double_quoted_or_regular_unquoted_words_separated_by_dot() {
Playground::setup("get_test_4", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[package]
9999 = ["Yehuda Katz <wycats@gmail.com>", "Jonathan Turner <jonathan.d.turner@gmail.com>", "Andrés N. Robalino <andres@androbtech.com>"]
description = "When arepas shells are tasty and fun."
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| get package."9999"
| length
"#
));
assert_eq!(actual.out, "3");
})
}
#[test]
fn fetches_more_than_one_column_path() {
Playground::setup("get_test_5", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[[fortune_tellers]]
name = "Andrés N. Robalino"
arepas = 1
[[fortune_tellers]]
name = "Jonathan Turner"
arepas = 1
[[fortune_tellers]]
name = "Yehuda Katz"
arepas = 1
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| get fortune_tellers.2.name fortune_tellers.0.name fortune_tellers.1.name
| nth 2
"#
));
assert_eq!(actual.out, "Jonathan Turner");
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn errors_fetching_by_column_not_present() {
Playground::setup("get_test_6", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[taconushell]
sentence_words = ["Yo", "quiero", "taconushell"]
[pizzanushell]
sentence-words = ["I", "want", "pizza"]
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| get taco
"#
));
assert!(actual.err.contains("Unknown column"),);
assert!(actual.err.contains("There isn't a column named 'taco'"),);
assert!(actual.err.contains("Perhaps you meant 'taconushell'?"),);
assert!(actual
.err
.contains("Columns available: pizzanushell, taconushell"),);
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn errors_fetching_by_column_using_a_number() {
Playground::setup("get_test_7", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[spanish_lesson]
0 = "can only be fetched with 0 double quoted."
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| get spanish_lesson.0
"#
));
assert!(actual.err.contains("No rows available"),);
assert!(actual.err.contains("A row at '0' can't be indexed."),);
assert!(actual
.err
.contains("Appears to contain columns. Columns available: 0"),)
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn errors_fetching_by_index_out_of_bounds() {
Playground::setup("get_test_8", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[spanish_lesson]
sentence_words = ["Yo", "quiero", "taconushell"]
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| get spanish_lesson.sentence_words.3
"#
));
assert!(actual.err.contains("Row not found"),);
assert!(actual.err.contains("There isn't a row indexed at 3"),);
assert!(actual.err.contains("The table only has 3 rows (0 to 2)"),)
})
}
#[test]
fn quoted_column_access() {
let actual = nu!(
cwd: "tests/fixtures/formats",
r#"echo '[{"foo bar": {"baz": 4}}]' | from json | get "foo bar".baz "#
);
assert_eq!(actual.out, "4");
}

View File

@ -0,0 +1,99 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn groups() {
Playground::setup("group_by_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.csv",
r#"
first_name,last_name,rusty_at,type
Andrés,Robalino,10/11/2013,A
Jonathan,Turner,10/12/2013,B
Yehuda,Katz,10/11/2013,A
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_caballeros.csv
| group-by rusty_at
| get "10/11/2013"
| length
"#
));
assert_eq!(actual.out, "2");
})
}
#[test]
fn errors_if_given_unknown_column_name() {
Playground::setup("group_by_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.json",
r#"
{
"nu": {
"committers": [
{"name": "Andrés N. Robalino"},
{"name": "Jonathan Turner"},
{"name": "Yehuda Katz"}
],
"releases": [
{"version": "0.2"}
{"version": "0.8"},
{"version": "0.9999999"}
],
"0xATYKARNU": [
["Th", "e", " "],
["BIG", " ", "UnO"],
["punto", "cero"]
]
}
}
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_caballeros.json
| group-by { get nu.releases.version }
"#
));
assert!(actual
.err
.contains("requires a table with one value for grouping"));
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn errors_if_block_given_evaluates_more_than_one_row() {
Playground::setup("group_by_test_3", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.csv",
r#"
first_name,last_name,rusty_at,type
Andrés,Robalino,10/11/2013,A
Jonathan,Turner,10/12/2013,B
Yehuda,Katz,10/11/2013,A
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_caballeros.csv
| group-by ttype
"#
));
assert!(actual.err.contains("Unknown column"));
})
}

View File

@ -0,0 +1,122 @@
use nu_test_support::{nu, pipeline};
#[test]
fn base64_defaults_to_encoding_with_standard_character_type() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo 'username:password' | hash base64
"#
)
);
assert_eq!(actual.out, "dXNlcm5hbWU6cGFzc3dvcmQ=");
}
#[test]
fn base64_encode_characterset_binhex() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo 'username:password' | hash base64 --character_set binhex --encode
"#
)
);
assert_eq!(actual.out, "F@0NEPjJD97kE\'&bEhFZEP3");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn error_when_invalid_character_set_given() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo 'username:password' | hash base64 --character_set 'this is invalid' --encode
"#
)
);
assert!(actual
.err
.contains("this is invalid is not a valid character-set"));
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn base64_decode_characterset_binhex() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo "F@0NEPjJD97kE'&bEhFZEP3" | hash base64 --character_set binhex --decode
"#
)
);
assert_eq!(actual.out, "username:password");
}
#[test]
fn error_invalid_decode_value() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo "this should not be a valid encoded value" | hash base64 --character_set url-safe --decode
"#
)
);
assert!(actual
.err
.contains("invalid base64 input for character set url-safe"));
}
#[test]
fn error_use_both_flags() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo 'username:password' | hash base64 --encode --decode
"#
)
);
assert!(actual
.err
.contains("only one of --decode and --encode flags can be used"));
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn md5_works_with_file() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample.db | hash md5
"#
)
);
assert_eq!(actual.out, "4de97601d232c427977ef11db396c951");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn sha256_works_with_file() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample.db | hash sha256
"#
)
);
assert_eq!(
actual.out,
"2f5050e7eea415c1f3d80b5d93355efd15043ec9157a2bb167a9e73f2ae651f2"
);
}

View File

@ -0,0 +1,35 @@
use nu_test_support::{nu, pipeline};
// FIXME: jt: needs more work
#[ignore]
#[test]
fn headers_uses_first_row_as_header() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample_headers.xlsx
| get Sheet1
| headers
| get header0
| from json"#
));
assert_eq!(actual.out, "r1c0r2c0")
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn headers_adds_missing_column_name() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample_headers.xlsx
| get Sheet1
| headers
| get Column1
| from json"#
));
assert_eq!(actual.out, "r1c1r2c1")
}

View File

@ -0,0 +1,33 @@
use nu_test_support::{nu, pipeline};
#[test]
fn help_commands_length() {
let actual = nu!(
cwd: ".", pipeline(
r#"
help commands | length
"#
));
let output = actual.out;
let output_int: i32 = output.parse().unwrap();
let is_positive = output_int.is_positive();
assert!(is_positive);
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn help_generate_docs_length() {
let actual = nu!(
cwd: ".", pipeline(
r#"
help generate_docs | flatten | length
"#
));
let output = actual.out;
let output_int: i32 = output.parse().unwrap();
let is_positive = output_int.is_positive();
assert!(is_positive);
}

View File

@ -0,0 +1,117 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
// FIXME: jt: needs more work
#[ignore]
#[test]
fn summarizes_by_column_given() {
Playground::setup("histogram_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.csv",
r#"
first_name,last_name,rusty_at
Andrés,Robalino,Ecuador
Jonathan,Turner,Estados Unidos
Yehuda,Katz,Estados Unidos
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_caballeros.csv
| histogram rusty_at countries
| where rusty_at == "Ecuador"
| get countries
"#
));
assert_eq!(
actual.out,
"**************************************************"
);
// 50%
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn summarizes_by_values() {
Playground::setup("histogram_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.csv",
r#"
first_name,last_name,rusty_at
Andrés,Robalino,Ecuador
Jonathan,Turner,Estados Unidos
Yehuda,Katz,Estados Unidos
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_caballeros.csv
| get rusty_at
| histogram
| where value == "Estados Unidos"
| get count
"#
));
assert_eq!(actual.out, "2");
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn help() {
Playground::setup("histogram_test_3", |dirs, _sandbox| {
let help_command = nu!(
cwd: dirs.test(), pipeline(
r#"
help histogram
"#
));
let help_short = nu!(
cwd: dirs.test(), pipeline(
r#"
histogram -h
"#
));
let help_long = nu!(
cwd: dirs.test(), pipeline(
r#"
histogram --help
"#
));
assert_eq!(help_short.out, help_command.out);
assert_eq!(help_long.out, help_command.out);
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn count() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [[bit]; [1] [0] [0] [0] [0] [0] [0] [1]]
| histogram bit
| sort-by count
| reject frequency
| to json
"#
));
let bit_json = r#"[{"bit":"1","count":2,"percentage":"33.33%"},{"bit":"0","count":6,"percentage":"100.00%"}]"#;
assert_eq!(actual.out, bit_json);
}

View File

@ -0,0 +1,80 @@
use nu_test_support::{nu, pipeline};
#[test]
fn into_filesize_int() {
let actual = nu!(
cwd: ".", pipeline(
r#"
1 | into filesize
"#
));
assert!(actual.out.contains("1 B"));
}
#[test]
fn into_filesize_decimal() {
let actual = nu!(
cwd: ".", pipeline(
r#"
1.2 | into filesize
"#
));
assert!(actual.out.contains("1 B"));
}
#[test]
fn into_filesize_str() {
let actual = nu!(
cwd: ".", pipeline(
r#"
'2000' | into filesize
"#
));
assert!(actual.out.contains("2.0 KiB"));
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn into_filesize_str_newline() {
let actual = nu!(
cwd: ".", pipeline(
r#"
"2000
" | into filesize
"#
));
assert!(actual.out.contains("2.0 KiB"));
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn into_filesize_str_many_newlines() {
let actual = nu!(
cwd: ".", pipeline(
r#"
"2000
" | into filesize
"#
));
assert!(actual.out.contains("2.0 KiB"));
}
#[test]
fn into_filesize_filesize() {
let actual = nu!(
cwd: ".", pipeline(
r#"
3kib | into filesize
"#
));
assert!(actual.out.contains("3.0 KiB"));
}

View File

@ -0,0 +1,37 @@
use nu_test_support::{nu, pipeline};
#[test]
fn into_int_filesize() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo 1kb | into int | each { $it / 1000 }
"#
));
assert!(actual.out.contains('1'));
}
#[test]
fn into_int_filesize2() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo 1kib | into int | each { $it / 1024 }
"#
));
assert!(actual.out.contains('1'));
}
#[test]
fn into_int_int() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo 1024 | into int | each { $it / 1024 }
"#
));
assert!(actual.out.contains('1'));
}

View File

@ -0,0 +1,3 @@
mod rows;
mod until;
mod while_;

View File

@ -0,0 +1,31 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn rows() {
Playground::setup("keep_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"caballeros.csv",
r#"
name,lucky_code
Andrés,1
Jonathan,1
Jason,2
Yehuda,1
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open caballeros.csv
| keep 3
| get lucky_code
| math sum
"#
));
assert_eq!(actual.out, "4");
})
}

View File

@ -0,0 +1,52 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn condition_is_met() {
Playground::setup("keep_until_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"caballeros.txt",
r#"
CHICKEN SUMMARY report date: April 29th, 2020
--------------------------------------------------------------------
Chicken Collection,29/04/2020,30/04/2020,31/04/2020
Yellow Chickens,,,
Andrés,1,1,1
Jonathan,1,1,1
Jason,1,1,1
Yehuda,1,1,1
Blue Chickens,,,
Andrés,1,1,2
Jonathan,1,1,2
Jason,1,1,2
Yehuda,1,1,2
Red Chickens,,,
Andrés,1,1,3
Jonathan,1,1,3
Jason,1,1,3
Yehuda,1,1,3
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open --raw caballeros.txt
| lines
| skip 2
| str trim
| str collect (char nl)
| from csv
| skip while "Chicken Collection" != "Blue Chickens"
| keep until "Chicken Collection" == "Red Chickens"
| skip 1
| into int "31/04/2020"
| get "31/04/2020"
| math sum
"#
));
assert_eq!(actual.out, "8");
})
}

View File

@ -0,0 +1,51 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn condition_is_met() {
Playground::setup("keep_while_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"caballeros.txt",
r#"
CHICKEN SUMMARY report date: April 29th, 2020
--------------------------------------------------------------------
Chicken Collection,29/04/2020,30/04/2020,31/04/2020
Yellow Chickens,,,
Andrés,1,1,1
Jonathan,1,1,1
Jason,1,1,1
Yehuda,1,1,1
Blue Chickens,,,
Andrés,1,1,2
Jonathan,1,1,2
Jason,1,1,2
Yehuda,1,1,2
Red Chickens,,,
Andrés,1,1,3
Jonathan,1,1,3
Jason,1,1,3
Yehuda,1,1,3
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open --raw caballeros.txt
| lines
| skip 2
| str trim
| str collect (char nl)
| from csv
| skip 1
| keep while "Chicken Collection" != "Blue Chickens"
| into int "31/04/2020"
| get "31/04/2020"
| math sum
"#
));
assert_eq!(actual.out, "4");
})
}

View File

@ -0,0 +1,66 @@
use nu_test_support::fs::Stub::EmptyFile;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn gets_the_last_row() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"ls | sort-by name | last 1 | get name | str trim"
);
assert_eq!(actual.out, "utf16.ini");
}
#[test]
fn gets_last_rows_by_amount() {
Playground::setup("last_test_1", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("los.txt"),
EmptyFile("tres.txt"),
EmptyFile("amigos.txt"),
EmptyFile("arepas.clu"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| last 3
| length
"#
));
assert_eq!(actual.out, "3");
})
}
#[test]
fn gets_last_row_when_no_amount_given() {
Playground::setup("last_test_2", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("caballeros.txt"), EmptyFile("arepas.clu")]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| last
| length
"#
));
assert_eq!(actual.out, "1");
})
}
#[test]
fn requests_more_rows_than_table_has() {
let actual = nu!(
cwd: ".", pipeline(
r#"
date | last 50 | length
"#
));
assert_eq!(actual.out, "1");
}

View File

@ -0,0 +1,25 @@
use nu_test_support::{nu, pipeline};
#[test]
fn length_columns_in_cal_table() {
let actual = nu!(
cwd: ".", pipeline(
r#"
cal | length -c
"#
));
assert_eq!(actual.out, "7");
}
#[test]
fn length_columns_no_rows() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [] | length -c
"#
));
assert_eq!(actual.out, "0");
}

View File

@ -0,0 +1,54 @@
use nu_test_support::{nu, pipeline};
#[test]
fn lines() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open cargo_sample.toml -r
| lines
| skip while $it != "[dependencies]"
| skip 1
| first 1
| split column "="
| get Column1
| str trim
"#
));
assert_eq!(actual.out, "rustyline");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn lines_proper_buffering() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open lines_test.txt -r
| lines
| str length
| to json
"#
));
assert_eq!(actual.out, "[8193,3]");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn lines_multi_value_split() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample-simple.json
| get first second
| lines
| length
"#
));
assert_eq!(actual.out, "5");
}

View File

@ -0,0 +1,352 @@
use nu_test_support::fs::Stub::EmptyFile;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn lists_regular_files() {
Playground::setup("ls_test_1", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("yehuda.txt"),
EmptyFile("jonathan.txt"),
EmptyFile("andres.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| length
"#
));
assert_eq!(actual.out, "3");
})
}
#[test]
fn lists_regular_files_using_asterisk_wildcard() {
Playground::setup("ls_test_2", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("los.txt"),
EmptyFile("tres.txt"),
EmptyFile("amigos.txt"),
EmptyFile("arepas.clu"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls *.txt
| length
"#
));
assert_eq!(actual.out, "3");
})
}
#[test]
fn lists_regular_files_using_question_mark_wildcard() {
Playground::setup("ls_test_3", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("yehuda.10.txt"),
EmptyFile("jonathan.10.txt"),
EmptyFile("andres.10.txt"),
EmptyFile("chicken_not_to_be_picked_up.100.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls *.??.txt
| length
"#
));
assert_eq!(actual.out, "3");
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn lists_all_files_in_directories_from_stream() {
Playground::setup("ls_test_4", |dirs, sandbox| {
sandbox
.with_files(vec![EmptyFile("root1.txt"), EmptyFile("root2.txt")])
.within("dir_a")
.with_files(vec![
EmptyFile("yehuda.10.txt"),
EmptyFile("jonathan.10.txt"),
])
.within("dir_b")
.with_files(vec![
EmptyFile("andres.10.txt"),
EmptyFile("chicken_not_to_be_picked_up.100.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo dir_a dir_b
| each { ls $it }
| length
"#
));
assert_eq!(actual.out, "4");
})
}
#[test]
fn does_not_fail_if_glob_matches_empty_directory() {
Playground::setup("ls_test_5", |dirs, sandbox| {
sandbox.within("dir_a");
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls dir_a
| length
"#
));
assert_eq!(actual.out, "0");
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn fails_when_glob_doesnt_match() {
Playground::setup("ls_test_5", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("root1.txt"), EmptyFile("root2.txt")]);
let actual = nu!(
cwd: dirs.test(),
"ls root3*"
);
assert!(actual.err.contains("no matches found"));
})
}
#[test]
fn list_files_from_two_parents_up_using_multiple_dots() {
Playground::setup("ls_test_6", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("yahuda.yaml"),
EmptyFile("jonathan.json"),
EmptyFile("andres.xml"),
EmptyFile("kevin.txt"),
]);
sandbox.within("foo").mkdir("bar");
let actual = nu!(
cwd: dirs.test().join("foo/bar"),
r#"
ls ... | length
"#
);
assert_eq!(actual.out, "5");
})
}
#[test]
fn lists_hidden_file_when_explicitly_specified() {
Playground::setup("ls_test_7", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("los.txt"),
EmptyFile("tres.txt"),
EmptyFile("amigos.txt"),
EmptyFile("arepas.clu"),
EmptyFile(".testdotfile"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls .testdotfile
| length
"#
));
assert_eq!(actual.out, "1");
})
}
#[test]
fn lists_all_hidden_files_when_glob_contains_dot() {
Playground::setup("ls_test_8", |dirs, sandbox| {
sandbox
.with_files(vec![
EmptyFile("root1.txt"),
EmptyFile("root2.txt"),
EmptyFile(".dotfile1"),
])
.within("dir_a")
.with_files(vec![
EmptyFile("yehuda.10.txt"),
EmptyFile("jonathan.10.txt"),
EmptyFile(".dotfile2"),
])
.within("dir_b")
.with_files(vec![
EmptyFile("andres.10.txt"),
EmptyFile("chicken_not_to_be_picked_up.100.txt"),
EmptyFile(".dotfile3"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls **/.*
| length
"#
));
assert_eq!(actual.out, "3");
})
}
#[test]
// TODO Remove this cfg value when we have an OS-agnostic way
// of creating hidden files using the playground.
#[cfg(unix)]
fn lists_all_hidden_files_when_glob_does_not_contain_dot() {
Playground::setup("ls_test_8", |dirs, sandbox| {
sandbox
.with_files(vec![
EmptyFile("root1.txt"),
EmptyFile("root2.txt"),
EmptyFile(".dotfile1"),
])
.within("dir_a")
.with_files(vec![
EmptyFile("yehuda.10.txt"),
EmptyFile("jonathan.10.txt"),
EmptyFile(".dotfile2"),
])
.within(".dir_b")
.with_files(vec![
EmptyFile("andres.10.txt"),
EmptyFile("chicken_not_to_be_picked_up.100.txt"),
EmptyFile(".dotfile3"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls **/*
| length
"#
));
assert_eq!(actual.out, "5");
})
}
#[test]
#[cfg(unix)]
fn fails_with_ls_to_dir_without_permission() {
Playground::setup("ls_test_1", |dirs, sandbox| {
sandbox.within("dir_a").with_files(vec![
EmptyFile("yehuda.11.txt"),
EmptyFile("jonathan.10.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
chmod 000 dir_a; ls dir_a
"#
));
assert!(actual
.err
.contains("The permissions of 0 do not allow access for this user"));
})
}
#[test]
fn lists_files_including_starting_with_dot() {
Playground::setup("ls_test_9", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("yehuda.txt"),
EmptyFile("jonathan.txt"),
EmptyFile("andres.txt"),
EmptyFile(".hidden1.txt"),
EmptyFile(".hidden2.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls -a
| length
"#
));
assert_eq!(actual.out, "5");
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn list_all_columns() {
Playground::setup("ls_test_all_columns", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("Leonardo.yaml"),
EmptyFile("Raphael.json"),
EmptyFile("Donatello.xml"),
EmptyFile("Michelangelo.txt"),
]);
// Normal Operation
let actual = nu!(
cwd: dirs.test(),
"ls | get | to md"
);
let expected = ["name", "type", "size", "modified"].join("");
assert_eq!(actual.out, expected, "column names are incorrect for ls");
// Long
let actual = nu!(
cwd: dirs.test(),
"ls -l | get | to md"
);
let expected = {
#[cfg(unix)]
{
[
"name",
"type",
"target",
"num_links",
"inode",
"readonly",
"mode",
"uid",
"group",
"size",
"created",
"accessed",
"modified",
]
.join("")
}
#[cfg(windows)]
{
[
"name", "type", "target", "readonly", "size", "created", "accessed", "modified",
]
.join("")
}
};
assert_eq!(
actual.out, expected,
"column names are incorrect for ls long"
);
});
}

View File

@ -0,0 +1,27 @@
use nu_test_support::{nu, pipeline};
#[test]
fn can_average_numbers() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sgml_description.json
| get glossary.GlossDiv.GlossList.GlossEntry.Sections
| math avg
"#
));
assert_eq!(actual.out, "101.5")
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn can_average_bytes() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"ls | sort-by name | skip 1 | first 2 | get size | math avg | format \"{$it}\" "
);
assert_eq!(actual.out, "1.6 KB");
}

View File

@ -0,0 +1,93 @@
use nu_test_support::{nu, pipeline};
// FIXME: jt: needs more work
#[ignore]
#[test]
fn evaluates_two_plus_two() {
let actual = nu!(
cwd: ".", pipeline(
r#"
math eval "2 + 2"
"#
));
assert!(actual.out.contains("4.0"));
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn evaluates_two_to_the_power_four() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo "2 ^ 4" | math eval
"#
));
assert!(actual.out.contains("16.0"));
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn evaluates_three_multiplied_by_five() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo "3 * 5" | math eval
"#
));
assert!(actual.out.contains("15.0"));
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn evaluates_twenty_four_divided_by_two() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo "24 / 2" | math eval
"#
));
assert!(actual.out.contains("12.0"));
}
#[test]
fn evaluates_twenty_eight_minus_seven() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo "28 - 7" | math eval
"#
));
assert!(actual.out.contains("21"));
}
#[test]
fn evaluates_pi() {
let actual = nu!(
cwd: ".", pipeline(
r#"
math eval pi
"#
));
assert!(actual.out.contains("3.14"));
}
#[test]
fn evaluates_tau() {
let actual = nu!(
cwd: ".", pipeline(
r#"
math eval tau
"#
));
assert!(actual.out.contains("6.28"));
}

View File

@ -0,0 +1,40 @@
use nu_test_support::{nu, pipeline};
#[test]
fn median_numbers_with_even_rows() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [10 6 19 21 4]
| math median
"#
));
assert_eq!(actual.out, "10")
}
#[test]
fn median_numbers_with_odd_rows() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [3 8 9 12 12 15]
| math median
"#
));
assert_eq!(actual.out, "10.5")
}
#[test]
fn median_mixed_numbers() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [-11.5 -13.5 10]
| math median
"#
));
assert_eq!(actual.out, "-11.5")
}

View File

@ -0,0 +1,288 @@
mod avg;
mod eval;
mod median;
mod round;
mod sqrt;
mod sum;
use nu_test_support::{nu, pipeline};
#[test]
fn one_arg() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1
"#
));
assert_eq!(actual.out, "1");
}
#[test]
fn add() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1 + 1
"#
));
assert_eq!(actual.out, "2");
}
#[test]
fn add_compound() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1 + 2 + 2
"#
));
assert_eq!(actual.out, "5");
}
#[test]
fn precedence_of_operators() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1 + 2 * 2
"#
));
assert_eq!(actual.out, "5");
}
#[test]
fn precedence_of_operators2() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1 + 2 * 2 + 1
"#
));
assert_eq!(actual.out, "6");
}
#[test]
fn division_of_ints() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
4 / 2
"#
));
assert_eq!(actual.out, "2");
}
#[test]
fn division_of_ints2() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1 / 4
"#
));
assert_eq!(actual.out, "0.25");
}
#[test]
fn error_zero_division_int_int() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1 / 0
"#
));
assert!(actual.err.contains("division by zero"));
}
#[test]
fn error_zero_division_decimal_int() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1.0 / 0
"#
));
assert!(actual.err.contains("division by zero"));
}
#[test]
fn error_zero_division_int_decimal() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1 / 0.0
"#
));
assert!(actual.err.contains("division by zero"));
}
#[test]
fn error_zero_division_decimal_decimal() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1.0 / 0.0
"#
));
assert!(actual.err.contains("division by zero"));
}
#[test]
fn proper_precedence_history() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
2 / 2 / 2 + 1
"#
));
assert_eq!(actual.out, "1.5");
}
#[test]
fn parens_precedence() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
4 * (6 - 3)
"#
));
assert_eq!(actual.out, "12");
}
#[test]
fn modulo() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
9 mod 2
"#
));
assert_eq!(actual.out, "1");
}
#[test]
fn duration_math() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1wk + 1day
"#
));
assert_eq!(actual.out, "8day");
}
#[test]
fn duration_decimal_math() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
5.5day + 0.5day
"#
));
assert_eq!(actual.out, "6day");
}
#[test]
fn duration_math_with_nanoseconds() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1wk + 10ns
"#
));
assert_eq!(actual.out, "7day 10ns");
}
#[test]
fn duration_decimal_math_with_nanoseconds() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1.5wk + 10ns
"#
));
assert_eq!(actual.out, "10day 10ns");
}
#[test]
fn duration_math_with_negative() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
1day - 1wk
"#
));
assert_eq!(actual.out, "-6day");
}
#[test]
fn compound_comparison() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
4 > 3 && 2 > 1
"#
));
assert_eq!(actual.out, "true");
}
#[test]
fn compound_comparison2() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
4 < 3 || 2 > 1
"#
));
assert_eq!(actual.out, "true");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn compound_where() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
echo '[{"a": 1, "b": 1}, {"a": 2, "b": 1}, {"a": 2, "b": 2}]' | from json | where a == 2 && b == 1 | to json
"#
));
assert_eq!(actual.out, r#"{"a":2,"b":1}"#);
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn compound_where_paren() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
echo '[{"a": 1, "b": 1}, {"a": 2, "b": 1}, {"a": 2, "b": 2}]' | from json | where ($it.a == 2 && $it.b == 1) || $it.b == 2 | to json
"#
));
assert_eq!(actual.out, r#"[{"a":2,"b":1},{"a":2,"b":2}]"#);
}

View File

@ -0,0 +1,21 @@
use nu_test_support::nu;
#[test]
fn can_round_very_large_numbers() {
let actual = nu!(
cwd: ".",
"echo 18.1372544780074142289927665486772012345 | math round"
);
assert_eq!(actual.out, "18")
}
#[test]
fn can_round_very_large_numbers_with_precision() {
let actual = nu!(
cwd: ".",
"echo 18.13725447800741422899276654867720121457878988 | math round -p 10"
);
assert_eq!(actual.out, "18.137254478")
}

View File

@ -0,0 +1,35 @@
use nu_test_support::nu;
// FIXME: jt: needs more work
#[ignore]
#[test]
fn can_sqrt_numbers() {
let actual = nu!(
cwd: ".",
"echo [0.25 2 4] | math sqrt | math sum"
);
assert_eq!(actual.out, "3.914213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641573");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn can_sqrt_irrational() {
let actual = nu!(
cwd: ".",
"echo 2 | math sqrt"
);
assert_eq!(actual.out, "1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641573");
}
#[test]
fn can_sqrt_perfect_square() {
let actual = nu!(
cwd: ".",
"echo 4 | math sqrt"
);
assert_eq!(actual.out, "2");
}

View File

@ -0,0 +1,89 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
use std::str::FromStr;
#[test]
fn all() {
Playground::setup("sum_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"meals.json",
r#"
{
meals: [
{description: "1 large egg", calories: 90},
{description: "1 cup white rice", calories: 250},
{description: "1 tablespoon fish oil", calories: 108}
]
}
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open meals.json
| get meals
| get calories
| math sum
"#
));
assert_eq!(actual.out, "448");
})
}
#[test]
#[allow(clippy::unreadable_literal)]
#[allow(clippy::float_cmp)]
fn compute_sum_of_individual_row() -> Result<(), String> {
let answers_for_columns = [
("cpu", 88.257434),
("mem", 3032375296.),
("virtual", 102579965952.),
];
for (column_name, expected_value) in answers_for_columns {
let actual = nu!(
cwd: "tests/fixtures/formats/",
format!("open sample-ps-output.json | select {} | math sum | get {}", column_name, column_name)
);
let result =
f64::from_str(&actual.out).map_err(|_| String::from("Failed to parse float."))?;
assert_eq!(result, expected_value);
}
Ok(())
}
#[test]
#[allow(clippy::unreadable_literal)]
#[allow(clippy::float_cmp)]
fn compute_sum_of_table() -> Result<(), String> {
let answers_for_columns = [
("cpu", 88.257434),
("mem", 3032375296.),
("virtual", 102579965952.),
];
for (column_name, expected_value) in answers_for_columns {
let actual = nu!(
cwd: "tests/fixtures/formats/",
format!("open sample-ps-output.json | select cpu mem virtual | math sum | get {}", column_name)
);
let result =
f64::from_str(&actual.out).map_err(|_| String::from("Failed to parse float."))?;
assert_eq!(result, expected_value);
}
Ok(())
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn sum_of_a_row_containing_a_table_is_an_error() {
let actual = nu!(
cwd: "tests/fixtures/formats/",
"open sample-sys-output.json | math sum"
);
assert!(actual
.err
.contains("Attempted to compute values that can't be operated on"));
}

View File

@ -0,0 +1,44 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
// FIXME: jt: needs more work
#[ignore]
#[test]
fn row() {
Playground::setup("merge_test_1", |dirs, sandbox| {
sandbox.with_files(vec![
FileWithContentToBeTrimmed(
"caballeros.csv",
r#"
name,country,luck
Andrés,Ecuador,0
Jonathan,USA,0
Jason,Canada,0
Yehuda,USA,0
"#,
),
FileWithContentToBeTrimmed(
"new_caballeros.csv",
r#"
name,country,luck
Andrés Robalino,Guayaquil Ecuador,1
Jonathan Turner,New Zealand,1
"#,
),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open caballeros.csv
| merge { open new_caballeros.csv }
| where country in ["Guayaquil Ecuador" "New Zealand"]
| get luck
| math sum
"#
));
assert_eq!(actual.out, "2");
})
}

View File

@ -0,0 +1,84 @@
use nu_test_support::fs::files_exist_at;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
use std::path::Path;
#[test]
fn creates_directory() {
Playground::setup("mkdir_test_1", |dirs, _| {
nu!(
cwd: dirs.test(),
"mkdir my_new_directory"
);
let expected = dirs.test().join("my_new_directory");
assert!(expected.exists());
})
}
#[test]
fn accepts_and_creates_directories() {
Playground::setup("mkdir_test_2", |dirs, _| {
nu!(
cwd: dirs.test(),
"mkdir dir_1 dir_2 dir_3"
);
assert!(files_exist_at(
vec![Path::new("dir_1"), Path::new("dir_2"), Path::new("dir_3")],
dirs.test()
));
})
}
#[test]
fn creates_intermediary_directories() {
Playground::setup("mkdir_test_3", |dirs, _| {
nu!(
cwd: dirs.test(),
"mkdir some_folder/another/deeper_one"
);
let expected = dirs.test().join("some_folder/another/deeper_one");
assert!(expected.exists());
})
}
#[test]
fn create_directory_two_parents_up_using_multiple_dots() {
Playground::setup("mkdir_test_4", |dirs, sandbox| {
sandbox.within("foo").mkdir("bar");
nu!(
cwd: dirs.test().join("foo/bar"),
"mkdir .../boo"
);
let expected = dirs.test().join("boo");
assert!(expected.exists());
})
}
#[test]
fn show_created_paths() {
Playground::setup("mkdir_test_2", |dirs, _| {
let actual = nu!(
cwd: dirs.test(),
pipeline(
r#"
mkdir -s dir_1 dir_2 dir_3
| length
"#
));
assert!(files_exist_at(
vec![Path::new("dir_1"), Path::new("dir_2"), Path::new("dir_3")],
dirs.test()
));
assert_eq!(actual.out, "3");
})
}

View File

@ -0,0 +1,66 @@
mod all;
mod any;
mod append;
mod cal;
mod cd;
mod compact;
mod cp;
mod def;
mod default;
mod drop;
mod each;
mod echo;
mod empty;
mod enter;
mod every;
mod find;
mod first;
mod flatten;
mod format;
mod get;
mod group_by;
mod hash_;
mod headers;
mod help;
mod histogram;
mod into_filesize;
mod into_int;
mod keep;
mod last;
mod length;
mod lines;
mod ls;
mod math;
mod merge;
mod mkdir;
mod move_;
mod open;
mod parse;
mod path;
mod prepend;
mod random;
mod range;
mod reduce;
mod rename;
mod reverse;
mod rm;
mod roll;
mod rotate;
mod save;
mod select;
mod semicolon;
mod skip;
mod sort_by;
mod source;
mod split_by;
mod split_column;
mod split_row;
mod str_;
mod touch;
mod uniq;
mod update;
mod where_;
mod which;
mod with_env;
mod wrap;
mod zip;

View File

@ -0,0 +1,143 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn moves_a_column_before() {
Playground::setup("move_column_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"sample.csv",
r#"
column1,column2,column3,...,column98,column99,column100
-------,-------,-------,---,--------, A ,---------
-------,-------,-------,---,--------, N ,---------
-------,-------,-------,---,--------, D ,---------
-------,-------,-------,---,--------, R ,---------
-------,-------,-------,---,--------, E ,---------
-------,-------,-------,---,--------, S ,---------
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.csv
| move column99 --before column1
| rename chars
| get chars
| str trim
| str collect
"#
));
assert!(actual.out.contains("ANDRES"));
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn moves_columns_before() {
Playground::setup("move_column_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"sample.csv",
r#"
column1,column2,column3,...,column98,column99,column100
-------,-------, A ,---,--------, N ,---------
-------,-------, D ,---,--------, R ,---------
-------,-------, E ,---,--------, S ,---------
-------,-------, : ,---,--------, : ,---------
-------,-------, J ,---,--------, O ,---------
-------,-------, N ,---,--------, A ,---------
-------,-------, T ,---,--------, H ,---------
-------,-------, A ,---,--------, N ,---------
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.csv
| move column99 column3 --before column2
| rename _ chars_1 chars_2
| get chars_2 chars_1
| str trim
| str collect
"#
));
assert!(actual.out.contains("ANDRES::JONATHAN"));
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn moves_a_column_after() {
Playground::setup("move_column_test_3", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"sample.csv",
r#"
column1,column2,letters,...,column98,and_more,column100
-------,-------, A ,---,--------, N ,---------
-------,-------, D ,---,--------, R ,---------
-------,-------, E ,---,--------, S ,---------
-------,-------, : ,---,--------, : ,---------
-------,-------, J ,---,--------, O ,---------
-------,-------, N ,---,--------, A ,---------
-------,-------, T ,---,--------, H ,---------
-------,-------, A ,---,--------, N ,---------
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.csv
| move letters --after and_more
| move letters and_more --before column2
| rename _ chars_1 chars_2
| get chars_1 chars_2
| str trim
| str collect
"#
));
assert!(actual.out.contains("ANDRES::JONATHAN"));
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn moves_columns_after() {
Playground::setup("move_column_test_4", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"sample.csv",
r#"
column1,column2,letters,...,column98,and_more,column100
-------,-------, A ,---,--------, N ,---------
-------,-------, D ,---,--------, R ,---------
-------,-------, E ,---,--------, S ,---------
-------,-------, : ,---,--------, : ,---------
-------,-------, J ,---,--------, O ,---------
-------,-------, N ,---,--------, A ,---------
-------,-------, T ,---,--------, H ,---------
-------,-------, A ,---,--------, N ,---------
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.csv
| move letters and_more --after column1
| get
| nth 1 2
| str collect
"#
));
assert!(actual.out.contains("lettersand_more"));
})
}

View File

@ -0,0 +1,2 @@
mod column;
mod mv;

View File

@ -0,0 +1,371 @@
use nu_test_support::fs::{files_exist_at, Stub::EmptyFile};
use nu_test_support::nu;
use nu_test_support::playground::Playground;
#[test]
fn moves_a_file() {
Playground::setup("mv_test_1", |dirs, sandbox| {
sandbox
.with_files(vec![EmptyFile("andres.txt")])
.mkdir("expected");
let original = dirs.test().join("andres.txt");
let expected = dirs.test().join("expected/yehuda.txt");
nu!(
cwd: dirs.test(),
"mv andres.txt expected/yehuda.txt"
);
assert!(!original.exists());
assert!(expected.exists());
})
}
#[test]
fn overwrites_if_moving_to_existing_file() {
Playground::setup("mv_test_2", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("andres.txt"), EmptyFile("jonathan.txt")]);
let original = dirs.test().join("andres.txt");
let expected = dirs.test().join("jonathan.txt");
nu!(
cwd: dirs.test(),
"mv andres.txt jonathan.txt"
);
assert!(!original.exists());
assert!(expected.exists());
})
}
#[test]
fn moves_a_directory() {
Playground::setup("mv_test_3", |dirs, sandbox| {
sandbox.mkdir("empty_dir");
let original_dir = dirs.test().join("empty_dir");
let expected = dirs.test().join("renamed_dir");
nu!(
cwd: dirs.test(),
"mv empty_dir renamed_dir"
);
assert!(!original_dir.exists());
assert!(expected.exists());
})
}
#[test]
fn moves_the_file_inside_directory_if_path_to_move_is_existing_directory() {
Playground::setup("mv_test_4", |dirs, sandbox| {
sandbox
.with_files(vec![EmptyFile("jonathan.txt")])
.mkdir("expected");
let original_dir = dirs.test().join("jonathan.txt");
let expected = dirs.test().join("expected/jonathan.txt");
nu!(
cwd: dirs.test(),
"mv jonathan.txt expected"
);
assert!(!original_dir.exists());
assert!(expected.exists());
})
}
#[test]
fn moves_the_directory_inside_directory_if_path_to_move_is_existing_directory() {
Playground::setup("mv_test_5", |dirs, sandbox| {
sandbox
.within("contributors")
.with_files(vec![EmptyFile("jonathan.txt")])
.mkdir("expected");
let original_dir = dirs.test().join("contributors");
let expected = dirs.test().join("expected/contributors");
nu!(
cwd: dirs.test(),
"mv contributors expected"
);
assert!(!original_dir.exists());
assert!(expected.exists());
assert!(files_exist_at(vec!["jonathan.txt"], expected))
})
}
#[test]
fn moves_using_path_with_wildcard() {
Playground::setup("mv_test_7", |dirs, sandbox| {
sandbox
.within("originals")
.with_files(vec![
EmptyFile("andres.ini"),
EmptyFile("caco3_plastics.csv"),
EmptyFile("cargo_sample.toml"),
EmptyFile("jonathan.ini"),
EmptyFile("jonathan.xml"),
EmptyFile("sgml_description.json"),
EmptyFile("sample.ini"),
EmptyFile("utf16.ini"),
EmptyFile("yehuda.ini"),
])
.mkdir("work_dir")
.mkdir("expected");
let work_dir = dirs.test().join("work_dir");
let expected = dirs.test().join("expected");
nu!(cwd: work_dir, "mv ../originals/*.ini ../expected");
assert!(files_exist_at(
vec!["yehuda.ini", "jonathan.ini", "sample.ini", "andres.ini",],
expected
));
})
}
#[test]
fn moves_using_a_glob() {
Playground::setup("mv_test_8", |dirs, sandbox| {
sandbox
.within("meals")
.with_files(vec![
EmptyFile("arepa.txt"),
EmptyFile("empanada.txt"),
EmptyFile("taquiza.txt"),
])
.mkdir("work_dir")
.mkdir("expected");
let meal_dir = dirs.test().join("meals");
let work_dir = dirs.test().join("work_dir");
let expected = dirs.test().join("expected");
nu!(cwd: work_dir, "mv ../meals/* ../expected");
assert!(meal_dir.exists());
assert!(files_exist_at(
vec!["arepa.txt", "empanada.txt", "taquiza.txt",],
expected
));
})
}
#[test]
fn moves_a_directory_with_files() {
Playground::setup("mv_test_9", |dirs, sandbox| {
sandbox
.mkdir("vehicles/car")
.mkdir("vehicles/bicycle")
.with_files(vec![
EmptyFile("vehicles/car/car1.txt"),
EmptyFile("vehicles/car/car2.txt"),
])
.with_files(vec![
EmptyFile("vehicles/bicycle/bicycle1.txt"),
EmptyFile("vehicles/bicycle/bicycle2.txt"),
]);
let original_dir = dirs.test().join("vehicles");
let expected_dir = dirs.test().join("expected");
nu!(
cwd: dirs.test(),
"mv vehicles expected"
);
assert!(!original_dir.exists());
assert!(expected_dir.exists());
assert!(files_exist_at(
vec![
"car/car1.txt",
"car/car2.txt",
"bicycle/bicycle1.txt",
"bicycle/bicycle2.txt"
],
expected_dir
));
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn errors_if_source_doesnt_exist() {
Playground::setup("mv_test_10", |dirs, sandbox| {
sandbox.mkdir("test_folder");
let actual = nu!(
cwd: dirs.test(),
"mv non-existing-file test_folder/"
);
assert!(actual.err.contains("Invalid file or pattern"));
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn errors_if_destination_doesnt_exist() {
Playground::setup("mv_test_10_1", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("empty.txt")]);
let actual = nu!(
cwd: dirs.test(),
"mv empty.txt does/not/exist"
);
assert!(actual.err.contains("Destination directory does not exist"));
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn errors_if_multiple_sources_but_destination_not_a_directory() {
Playground::setup("mv_test_10_2", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("file1.txt"),
EmptyFile("file2.txt"),
EmptyFile("file3.txt"),
]);
let actual = nu!(
cwd: dirs.test(),
"mv file?.txt not_a_dir"
);
assert!(actual
.err
.contains("Can only move multiple sources if destination is a directory"));
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn errors_if_renaming_directory_to_an_existing_file() {
Playground::setup("mv_test_10_3", |dirs, sandbox| {
sandbox
.mkdir("mydir")
.with_files(vec![EmptyFile("empty.txt")]);
let actual = nu!(
cwd: dirs.test(),
"mv mydir empty.txt"
);
assert!(actual.err.contains("Cannot rename a directory to a file"));
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn errors_if_moving_to_itself() {
Playground::setup("mv_test_10_4", |dirs, sandbox| {
sandbox.mkdir("mydir").mkdir("mydir/mydir_2");
let actual = nu!(
cwd: dirs.test(),
"mv mydir mydir/mydir_2/"
);
assert!(actual.err.contains("cannot move to itself"));
})
}
#[test]
fn does_not_error_on_relative_parent_path() {
Playground::setup("mv_test_11", |dirs, sandbox| {
sandbox
.mkdir("first")
.with_files(vec![EmptyFile("first/william_hartnell.txt")]);
let original = dirs.test().join("first/william_hartnell.txt");
let expected = dirs.test().join("william_hartnell.txt");
nu!(
cwd: dirs.test().join("first"),
"mv william_hartnell.txt ./.."
);
assert!(!original.exists());
assert!(expected.exists());
})
}
#[test]
fn move_files_using_glob_two_parents_up_using_multiple_dots() {
Playground::setup("mv_test_12", |dirs, sandbox| {
sandbox.within("foo").within("bar").with_files(vec![
EmptyFile("jonathan.json"),
EmptyFile("andres.xml"),
EmptyFile("yehuda.yaml"),
EmptyFile("kevin.txt"),
EmptyFile("many_more.ppl"),
]);
nu!(
cwd: dirs.test().join("foo/bar"),
r#"
mv * ...
"#
);
let files = vec![
"yehuda.yaml",
"jonathan.json",
"andres.xml",
"kevin.txt",
"many_more.ppl",
];
let original_dir = dirs.test().join("foo/bar");
let destination_dir = dirs.test();
assert!(files_exist_at(files.clone(), destination_dir));
assert!(!files_exist_at(files, original_dir))
})
}
#[test]
fn move_file_from_two_parents_up_using_multiple_dots_to_current_dir() {
Playground::setup("cp_test_10", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("hello_there")]);
sandbox.within("foo").mkdir("bar");
nu!(
cwd: dirs.test().join("foo/bar"),
r#"
mv .../hello_there .
"#
);
let expected = dirs.test().join("foo/bar/hello_there");
let original = dirs.test().join("hello_there");
assert!(expected.exists());
assert!(!original.exists());
})
}
#[test]
fn does_not_error_when_some_file_is_moving_into_itself() {
Playground::setup("mv_test_13", |dirs, sandbox| {
sandbox.mkdir("11").mkdir("12");
let original_dir = dirs.test().join("11");
let expected = dirs.test().join("12/11");
nu!(cwd: dirs.test(), "mv 1* 12");
assert!(!original_dir.exists());
assert!(expected.exists());
})
}

View File

@ -0,0 +1,37 @@
#[test]
fn selects_a_row() {
Playground::setup("nth_test_1", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("notes.txt"), EmptyFile("arepas.txt")]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| sort-by name
| nth 0
| get name
"#
));
assert_eq!(actual.out, "arepas.txt");
});
}
#[test]
fn selects_many_rows() {
Playground::setup("nth_test_2", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("notes.txt"), EmptyFile("arepas.txt")]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| get name
| nth 1 0
| length
"#
));
assert_eq!(actual.out, "2");
});
}

View File

@ -0,0 +1,245 @@
use nu_test_support::fs::Stub::EmptyFile;
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn parses_csv() {
Playground::setup("open_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"nu.zion.csv",
r#"
author,lang,source
Jonathan Turner,Rust,New Zealand
Andres N. Robalino,Rust,Ecuador
Yehuda Katz,Rust,Estados Unidos
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open nu.zion.csv
| where author == "Andres N. Robalino"
| get source
"#
));
assert_eq!(actual.out, "Ecuador");
})
}
// sample.bson has the following format:
// ━━━━━━━━━━┯━━━━━━━━━━━
// _id │ root
// ──────────┼───────────
// [object] │ [9 items]
// ━━━━━━━━━━┷━━━━━━━━━━━
//
// the root value is:
// ━━━┯━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━┯━━━━━━━━━━
// # │ _id │ a │ b │ c
// ───┼───────────────────┼─────────────────────────┼──────────┼──────────
// 0 │ [object] │ 1.000000000000000 │ hello │ [2 items]
// 1 │ [object] │ 42.00000000000000 │ whel │ hello
// 2 │ [object] │ [object] │ │
// 3 │ [object] │ │ [object] │
// 4 │ [object] │ │ │ [object]
// 5 │ [object] │ │ │ [object]
// 6 │ [object] │ [object] │ [object] │
// 7 │ [object] │ <date value> │ [object] │
// 8 │ 1.000000 │ <decimal value> │ [object] │
//
// The decimal value is supposed to be π, but is currently wrong due to
// what appears to be an issue in the bson library that is under investigation.
//
#[cfg(feature = "bson")]
#[test]
fn parses_bson() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"open sample.bson | get root | nth 0 | get b"
);
assert_eq!(actual.out, "hello");
}
#[cfg(feature = "bson")]
#[test]
fn parses_more_bson_complexity() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample.bson
| get root
| nth 6
| get b
| get '$binary_subtype'
"#
));
assert_eq!(actual.out, "function");
}
// sample.db has the following format:
//
// ━━━┯━━━━━━━━━━━━┯━━━━━━━━━━━━━━
// # │ table_name │ table_values
// ───┼────────────┼──────────────
// 0 │ strings │ [6 items]
// 1 │ ints │ [5 items]
// 2 │ floats │ [4 items]
// ━━━┷━━━━━━━━━━━━┷━━━━━━━━━━━━━━
//
// In this case, this represents a sqlite database
// with three tables named `strings`, `ints`, and `floats`.
// The table_values represent the values for the tables:
//
// ━━━━┯━━━━━━━┯━━━━━━━━━━┯━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// # │ x │ y │ z │ f
// ────┼───────┼──────────┼──────┼──────────────────────────────────────────────────────────────────────
// 0 │ hello │ <binary> │ │
// 1 │ hello │ <binary> │ │
// 2 │ hello │ <binary> │ │
// 3 │ hello │ <binary> │ │
// 4 │ world │ <binary> │ │
// 5 │ world │ <binary> │ │
// 6 │ │ │ 1 │
// 7 │ │ │ 42 │
// 8 │ │ │ 425 │
// 9 │ │ │ 4253 │
// 10 │ │ │ │
// 11 │ │ │ │ 3.400000000000000
// 12 │ │ │ │ 3.141592650000000
// 13 │ │ │ │ 23.00000000000000
// 14 │ │ │ │ this string that doesn't really belong here but sqlite is what it is
// ━━━━┷━━━━━━━┷━━━━━━━━━━┷━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
//
// We can see here that each table has different columns. `strings` has `x` and `y`, while
// `ints` has just `z`, and `floats` has only the column `f`. This means, in general, when working
// with sqlite, one will want to select a single table, e.g.:
//
// open sample.db | nth 1 | get table_values
// ━━━┯━━━━━━
// # │ z
// ───┼──────
// 0 │ 1
// 1 │ 42
// 2 │ 425
// 3 │ 4253
// 4 │
// ━━━┷━━━━━━
#[cfg(feature = "sqlite")]
#[test]
fn parses_sqlite() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample.db
| get table_values
| nth 2
| get x
"#
));
assert_eq!(actual.out, "hello");
}
#[test]
fn parses_toml() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"open cargo_sample.toml | get package.edition"
);
assert_eq!(actual.out, "2018");
}
#[test]
fn parses_tsv() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open caco3_plastics.tsv
| first 1
| get origin
"#
));
assert_eq!(actual.out, "SPAIN")
}
#[test]
fn parses_json() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sgml_description.json
| get glossary.GlossDiv.GlossList.GlossEntry.GlossSee
"#
));
assert_eq!(actual.out, "markup")
}
#[test]
fn parses_ini() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"open sample.ini | get SectionOne.integer"
);
assert_eq!(actual.out, "1234")
}
#[test]
fn parses_utf16_ini() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"open ./utf16.ini --raw | decode utf-16 | from ini | rename info | get info | get IconIndex"
);
assert_eq!(actual.out, "-236")
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn errors_if_file_not_found() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"open i_dont_exist.txt"
);
let expected = "Cannot find file";
assert!(
actual.err.contains(expected),
"Error:\n{}\ndoes not contain{}",
actual.err,
expected
);
}
// FIXME: jt: I think `open` on a directory is confusing. We should make discuss this one a bit more
#[ignore]
#[test]
fn open_dir_is_ls() {
Playground::setup("open_dir", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("yehuda.txt"),
EmptyFile("jonathan.txt"),
EmptyFile("andres.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open .
| length
"#
));
assert_eq!(actual.out, "3");
})
}

View File

@ -0,0 +1,191 @@
use nu_test_support::fs::Stub;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
mod simple {
use super::*;
// FIXME: jt: needs more work
#[ignore]
#[test]
fn extracts_fields_from_the_given_the_pattern() {
Playground::setup("parse_test_1", |dirs, sandbox| {
sandbox.with_files(vec![Stub::FileWithContentToBeTrimmed(
"key_value_separated_arepa_ingredients.txt",
r#"
VAR1=Cheese
VAR2=JonathanParsed
VAR3=NushellSecretIngredient
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open key_value_separated_arepa_ingredients.txt
| lines
| each { echo $it | parse "{Name}={Value}" }
| nth 1
| get Value
"#
));
assert_eq!(actual.out, "JonathanParsed");
})
}
#[test]
fn double_open_curly_evalutes_to_a_single_curly() {
Playground::setup("parse_test_regex_2", |dirs, _sandbox| {
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo "{abc}123"
| parse "{{abc}{name}"
| get name
"#
));
assert_eq!(actual.out, "123");
})
}
#[test]
fn properly_escapes_text() {
Playground::setup("parse_test_regex_3", |dirs, _sandbox| {
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo "(abc)123"
| parse "(abc){name}"
| get name
"#
));
assert_eq!(actual.out, "123");
})
}
#[test]
fn properly_captures_empty_column() {
Playground::setup("parse_test_regex_4", |dirs, _sandbox| {
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo ["1:INFO:component:all is well" "2:ERROR::something bad happened"]
| parse "{timestamp}:{level}:{tag}:{entry}"
| get entry
| nth 1
"#
));
assert_eq!(actual.out, "something bad happened");
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn errors_when_missing_closing_brace() {
Playground::setup("parse_test_regex_5", |dirs, _sandbox| {
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo "(abc)123"
| parse "(abc){name"
| get name
"#
));
assert!(actual.err.contains("invalid parse pattern"));
})
}
}
mod regex {
use super::*;
fn nushell_git_log_oneline<'a>() -> Vec<Stub<'a>> {
vec![Stub::FileWithContentToBeTrimmed(
"nushell_git_log_oneline.txt",
r#"
ae87582c Fix missing invocation errors (#1846)
b89976da let format access variables also (#1842)
"#,
)]
}
#[test]
fn extracts_fields_with_all_named_groups() {
Playground::setup("parse_test_regex_1", |dirs, sandbox| {
sandbox.with_files(nushell_git_log_oneline());
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open nushell_git_log_oneline.txt
| parse --regex "(?P<Hash>\w+) (?P<Message>.+) \(#(?P<PR>\d+)\)"
| nth 1
| get PR
"#
));
assert_eq!(actual.out, "1842");
})
}
#[test]
fn extracts_fields_with_all_unnamed_groups() {
Playground::setup("parse_test_regex_2", |dirs, sandbox| {
sandbox.with_files(nushell_git_log_oneline());
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open nushell_git_log_oneline.txt
| parse --regex "(\w+) (.+) \(#(\d+)\)"
| nth 1
| get Capture1
"#
));
assert_eq!(actual.out, "b89976da");
})
}
#[test]
fn extracts_fields_with_named_and_unnamed_groups() {
Playground::setup("parse_test_regex_3", |dirs, sandbox| {
sandbox.with_files(nushell_git_log_oneline());
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open nushell_git_log_oneline.txt
| parse --regex "(?P<Hash>\w+) (.+) \(#(?P<PR>\d+)\)"
| nth 1
| get Capture2
"#
));
assert_eq!(actual.out, "let format access variables also");
})
}
#[test]
fn errors_with_invalid_regex() {
Playground::setup("parse_test_regex_1", |dirs, sandbox| {
sandbox.with_files(nushell_git_log_oneline());
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open nushell_git_log_oneline.txt
| parse --regex "(?P<Hash>\w+ unfinished capture group"
"#
));
assert!(actual.err.contains("unclosed group"));
})
}
}

View File

@ -0,0 +1,83 @@
use nu_test_support::{nu, pipeline};
use super::join_path_sep;
#[test]
fn returns_basename_of_empty_input() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo ""
| path basename
"#
));
assert_eq!(actual.out, "");
}
#[test]
fn replaces_basename_of_empty_input() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo ""
| path basename -r newname.txt
"#
));
assert_eq!(actual.out, "newname.txt");
}
#[test]
fn returns_basename_of_path_ending_with_dot() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo "some/file.txt/."
| path basename
"#
));
assert_eq!(actual.out, "file.txt");
}
#[test]
fn replaces_basename_of_path_ending_with_dot() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo "some/file.txt/."
| path basename -r viking.txt
"#
));
let expected = join_path_sep(&["some", "viking.txt"]);
assert_eq!(actual.out, expected);
}
#[test]
fn returns_basename_of_path_ending_with_double_dot() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo "some/file.txt/.."
| path basename
"#
));
assert_eq!(actual.out, "");
}
#[test]
fn replaces_basename_of_path_ending_with_double_dot() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo "some/file.txt/.."
| path basename -r eggs
"#
));
let expected = join_path_sep(&["some/file.txt/..", "eggs"]);
assert_eq!(actual.out, expected);
}

View File

@ -0,0 +1,137 @@
use nu_test_support::{nu, pipeline};
use super::join_path_sep;
#[test]
fn returns_dirname_of_empty_input() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo ""
| path dirname
"#
));
assert_eq!(actual.out, "");
}
#[test]
fn replaces_dirname_of_empty_input() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo ""
| path dirname -r newdir
"#
));
assert_eq!(actual.out, "newdir");
}
#[test]
fn returns_dirname_of_path_ending_with_dot() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo "some/dir/."
| path dirname
"#
));
assert_eq!(actual.out, "some");
}
#[test]
fn replaces_dirname_of_path_ending_with_dot() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo "some/dir/."
| path dirname -r eggs
"#
));
let expected = join_path_sep(&["eggs", "dir"]);
assert_eq!(actual.out, expected);
}
#[test]
fn returns_dirname_of_path_ending_with_double_dot() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo "some/dir/.."
| path dirname
"#
));
assert_eq!(actual.out, "some/dir");
}
#[test]
fn replaces_dirname_of_path_with_double_dot() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo "some/dir/.."
| path dirname -r eggs
"#
));
let expected = join_path_sep(&["eggs", ".."]);
assert_eq!(actual.out, expected);
}
#[test]
fn returns_dirname_of_zero_levels() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo "some/dir/with/spam.txt"
| path dirname -n 0
"#
));
assert_eq!(actual.out, "some/dir/with/spam.txt");
}
#[test]
fn replaces_dirname_of_zero_levels_with_empty_string() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo "some/dir/with/spam.txt"
| path dirname -n 0 -r ""
"#
));
assert_eq!(actual.out, "");
}
#[test]
fn replaces_dirname_of_more_levels() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo "some/dir/with/spam.txt"
| path dirname -r eggs -n 2
"#
));
let expected = join_path_sep(&["eggs", "with/spam.txt"]);
assert_eq!(actual.out, expected);
}
#[test]
fn replaces_dirname_of_way_too_many_levels() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo "some/dir/with/spam.txt"
| path dirname -r eggs -n 999
"#
));
let expected = join_path_sep(&["eggs", "some/dir/with/spam.txt"]);
assert_eq!(actual.out, expected);
}

View File

@ -0,0 +1,55 @@
use nu_test_support::fs::Stub::EmptyFile;
use nu_test_support::nu;
use nu_test_support::playground::Playground;
// FIXME: jt: needs more work
#[ignore]
#[test]
fn checks_if_existing_file_exists() {
Playground::setup("path_exists_1", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("spam.txt")]);
let actual = nu!(
cwd: dirs.test(),
"echo spam.txt | path exists"
);
assert_eq!(actual.out, "true");
})
}
#[test]
fn checks_if_missing_file_exists() {
Playground::setup("path_exists_2", |dirs, _| {
let actual = nu!(
cwd: dirs.test(),
"echo spam.txt | path exists"
);
assert_eq!(actual.out, "false");
})
}
#[test]
fn checks_if_dot_exists() {
Playground::setup("path_exists_3", |dirs, _| {
let actual = nu!(
cwd: dirs.test(),
"echo '.' | path exists"
);
assert_eq!(actual.out, "true");
})
}
#[test]
fn checks_if_double_dot_exists() {
Playground::setup("path_exists_4", |dirs, _| {
let actual = nu!(
cwd: dirs.test(),
"echo '..' | path exists"
);
assert_eq!(actual.out, "true");
})
}

View File

@ -0,0 +1,78 @@
use nu_test_support::fs::Stub::EmptyFile;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
use std::path::PathBuf;
#[test]
fn expands_path_with_dot() {
Playground::setup("path_expand_1", |dirs, sandbox| {
sandbox
.within("menu")
.with_files(vec![EmptyFile("spam.txt")]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo "menu/./spam.txt"
| path expand
"#
));
let expected = dirs.test.join("menu").join("spam.txt");
assert_eq!(PathBuf::from(actual.out), expected);
})
}
#[test]
fn expands_path_with_double_dot() {
Playground::setup("path_expand_2", |dirs, sandbox| {
sandbox
.within("menu")
.with_files(vec![EmptyFile("spam.txt")]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo "menu/../menu/spam.txt"
| path expand
"#
));
let expected = dirs.test.join("menu").join("spam.txt");
assert_eq!(PathBuf::from(actual.out), expected);
})
}
#[cfg(windows)]
mod windows {
use super::*;
#[test]
fn expands_path_with_tilde_backward_slash() {
Playground::setup("path_expand_2", |dirs, _| {
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo "~\tmp.txt" | path expand
"#
));
assert!(!PathBuf::from(actual.out).starts_with("~"));
})
}
#[test]
fn win_expands_path_with_tilde_forward_slash() {
Playground::setup("path_expand_2", |dirs, _| {
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo "~/tmp.txt" | path expand
"#
));
assert!(!PathBuf::from(actual.out).starts_with("~"));
})
}
}

View File

@ -0,0 +1,59 @@
use nu_test_support::{nu, pipeline};
use super::join_path_sep;
#[test]
fn returns_path_joined_with_column_path() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo [ [name]; [eggs] ]
| path join spam.txt -c [ name ]
| get name
"#
));
let expected = join_path_sep(&["eggs", "spam.txt"]);
assert_eq!(actual.out, expected);
}
#[test]
fn returns_path_joined_from_list() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo [ home viking spam.txt ]
| path join
"#
));
let expected = join_path_sep(&["home", "viking", "spam.txt"]);
assert_eq!(actual.out, expected);
}
#[test]
fn appends_slash_when_joined_with_empty_path() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo "/some/dir"
| path join ''
"#
));
let expected = join_path_sep(&["/some/dir", ""]);
assert_eq!(actual.out, expected);
}
#[test]
fn returns_joined_path_when_joining_empty_path() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo ""
| path join foo.txt
"#
));
assert_eq!(actual.out, "foo.txt");
}

View File

@ -0,0 +1,34 @@
mod basename;
mod dirname;
mod exists;
mod expand;
mod join;
mod parse;
mod split;
mod type_;
use std::path::MAIN_SEPARATOR;
/// Helper function that joins string literals with '/' or '\', based on host OS
fn join_path_sep(pieces: &[&str]) -> String {
let sep_string = String::from(MAIN_SEPARATOR);
pieces.join(&sep_string)
}
#[cfg(windows)]
#[test]
fn joins_path_on_windows() {
let pieces = ["sausage", "bacon", "spam"];
let actual = join_path_sep(&pieces);
assert_eq!(&actual, "sausage\\bacon\\spam");
}
#[cfg(not(windows))]
#[test]
fn joins_path_on_other_than_windows() {
let pieces = ["sausage", "bacon", "spam"];
let actual = join_path_sep(&pieces);
assert_eq!(&actual, "sausage/bacon/spam");
}

View File

@ -0,0 +1,138 @@
use nu_test_support::{nu, pipeline};
#[cfg(windows)]
#[test]
fn parses_single_path_prefix() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo 'C:\users\viking\spam.txt'
| path parse
| get prefix
"#
));
assert_eq!(actual.out, "C:");
}
#[test]
fn parses_single_path_parent() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo 'home/viking/spam.txt'
| path parse
| get parent
"#
));
assert_eq!(actual.out, "home/viking");
}
#[test]
fn parses_single_path_stem() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo 'home/viking/spam.txt'
| path parse
| get stem
"#
));
assert_eq!(actual.out, "spam");
}
#[test]
fn parses_custom_extension_gets_extension() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo 'home/viking/spam.tar.gz'
| path parse -e tar.gz
| get extension
"#
));
assert_eq!(actual.out, "tar.gz");
}
#[test]
fn parses_custom_extension_gets_stem() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo 'home/viking/spam.tar.gz'
| path parse -e tar.gz
| get stem
"#
));
assert_eq!(actual.out, "spam");
}
#[test]
fn parses_ignoring_extension_gets_extension() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo 'home/viking/spam.tar.gz'
| path parse -e ''
| get extension
"#
));
assert_eq!(actual.out, "");
}
#[test]
fn parses_ignoring_extension_gets_stem() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo 'home/viking/spam.tar.gz'
| path parse -e ""
| get stem
"#
));
assert_eq!(actual.out, "spam.tar.gz");
}
#[test]
fn parses_column_path_extension() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo [[home, barn]; ['home/viking/spam.txt', 'barn/cow/moo.png']]
| path parse -c [ home barn ]
| get barn
| get extension
"#
));
assert_eq!(actual.out, "png");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn parses_into_correct_number_of_columns() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo 'home/viking/spam.txt'
| path parse
| pivot
| get Column0
| length
"#
));
#[cfg(windows)]
let expected = "4";
#[cfg(not(windows))]
let expected = "3";
assert_eq!(actual.out, expected);
}

View File

@ -0,0 +1,48 @@
use nu_test_support::{nu, pipeline};
#[test]
fn splits_empty_path() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo '' | path split
"#
));
assert_eq!(actual.out, "");
}
#[test]
fn splits_correctly_single_path() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
'home/viking/spam.txt'
| path split
| last
"#
));
assert_eq!(actual.out, "spam.txt");
}
#[test]
fn splits_correctly_with_column_path() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo [
[home, barn];
['home/viking/spam.txt', 'barn/cow/moo.png']
['home/viking/eggs.txt', 'barn/goat/cheese.png']
]
| path split -c [ home barn ]
| get barn
| flatten
| length
"#
));
assert_eq!(actual.out, "6");
}

View File

@ -0,0 +1,58 @@
use nu_test_support::fs::Stub::EmptyFile;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn returns_type_of_missing_file() {
let actual = nu!(
cwd: "tests", pipeline(
r#"
echo "spam.txt"
| path type
"#
));
assert_eq!(actual.out, "");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn returns_type_of_existing_file() {
Playground::setup("path_expand_1", |dirs, sandbox| {
sandbox
.within("menu")
.with_files(vec![EmptyFile("spam.txt")]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo "menu"
| path type
"#
));
assert_eq!(actual.out, "dir");
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn returns_type_of_existing_directory() {
Playground::setup("path_expand_1", |dirs, sandbox| {
sandbox
.within("menu")
.with_files(vec![EmptyFile("spam.txt")]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
echo "menu/spam.txt"
| path type
"#
));
assert_eq!(actual.out, "file");
})
}

View File

@ -0,0 +1,29 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn adds_a_row_to_the_beginning() {
Playground::setup("prepend_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.txt",
r#"
Andrés N. Robalino
Jonathan Turner
Yehuda Katz
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_caballeros.txt
| lines
| prepend "pollo loco"
| nth 0
"#
));
assert_eq!(actual.out, "pollo loco");
})
}

View File

@ -0,0 +1,16 @@
use nu_test_support::{nu, pipeline};
#[test]
fn generates_a_bool() {
let actual = nu!(
cwd: ".", pipeline(
r#"
random bool
"#
));
let output = actual.out;
let is_boolean_output = output == "true" || output == "false";
assert!(is_boolean_output);
}

View File

@ -0,0 +1,14 @@
use nu_test_support::{nu, pipeline};
#[test]
fn generates_chars_of_specified_length() {
let actual = nu!(
cwd: ".", pipeline(
r#"
random chars -l 15 | size | get chars
"#
));
let result = actual.out;
assert_eq!(result, "15");
}

View File

@ -0,0 +1,43 @@
use nu_test_support::{nu, pipeline};
// FIXME: jt: needs more work
#[ignore]
#[test]
fn generates_an_decimal() {
let actual = nu!(
cwd: ".", pipeline(
r#"
random decimal 42..43
"#
));
assert!(actual.out.contains("42") || actual.out.contains("43"));
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn generates_55() {
let actual = nu!(
cwd: ".", pipeline(
r#"
random decimal 55..55
"#
));
assert!(actual.out.contains("55"));
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn generates_0() {
let actual = nu!(
cwd: ".", pipeline(
r#"
random decimal ..<1
"#
));
assert!(actual.out.contains('0'));
}

View File

@ -0,0 +1,13 @@
use nu_test_support::{nu, pipeline};
#[test]
fn rolls_4_roll() {
let actual = nu!(
cwd: ".", pipeline(
r#"
random dice -d 4 -s 10 | length
"#
));
assert_eq!(actual.out, "4");
}

View File

@ -0,0 +1,39 @@
use nu_test_support::{nu, pipeline};
#[test]
fn generates_an_integer() {
let actual = nu!(
cwd: ".", pipeline(
r#"
random integer 42..43
"#
));
assert!(actual.out.contains("42") || actual.out.contains("43"));
}
#[test]
fn generates_55() {
let actual = nu!(
cwd: ".", pipeline(
r#"
random integer 55..55
"#
));
assert!(actual.out.contains("55"));
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn generates_0() {
let actual = nu!(
cwd: ".", pipeline(
r#"
random integer ..<1
"#
));
assert!(actual.out.contains('0'));
}

View File

@ -0,0 +1,7 @@
mod bool;
mod chars;
mod decimal;
mod dice;
mod integer;
#[cfg(feature = "uuid_crate")]
mod uuid;

View File

@ -0,0 +1,16 @@
use nu_test_support::{nu, pipeline};
use uuid_crate::Uuid;
#[test]
fn generates_valid_uuid4() {
let actual = nu!(
cwd: ".", pipeline(
r#"
random uuid
"#
));
let result = Uuid::parse_str(actual.out.as_str());
assert!(result.is_ok());
}

View File

@ -0,0 +1,68 @@
use nu_test_support::fs::Stub::EmptyFile;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn selects_a_row() {
Playground::setup("range_test_1", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("notes.txt"), EmptyFile("tests.txt")]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| sort-by name
| range 0..0
| get name
"#
));
assert_eq!(actual.out, "notes.txt");
});
}
#[test]
fn selects_some_rows() {
Playground::setup("range_test_2", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("notes.txt"),
EmptyFile("tests.txt"),
EmptyFile("persons.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| get name
| range 1..2
| length
"#
));
assert_eq!(actual.out, "2");
});
}
#[test]
fn negative_indices() {
Playground::setup("range_test_negative_indices", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("notes.txt"),
EmptyFile("tests.txt"),
EmptyFile("persons.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| get name
| range (-1..)
| length
"#
));
assert_eq!(actual.out, "1");
});
}

View File

@ -0,0 +1,138 @@
use nu_test_support::{nu, pipeline};
// FIXME: jt: needs more work
#[ignore]
#[test]
fn reduce_table_column() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo "[{month:2,total:30}, {month:3,total:10}, {month:4,total:3}, {month:5,total:60}]"
| from json
| get total
| reduce -f 20 { $it.item + (math eval $"($item.acc)^1.05")}
| into string -d 1
"#
)
);
assert_eq!(actual.out, "180.6");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn reduce_table_column_with_path() {
let actual = nu!(
cwd: ".", pipeline(
r#"
[{month:2,total:30}, {month:3,total:10}, {month:4,total:3}, {month:5,total:60}]
| reduce -f 20 { $it.item.total + (math eval $"($item.acc)^1.05")}
| into string -d 1
"#
)
);
assert_eq!(actual.out, "180.6");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn reduce_rows_example() {
let actual = nu!(
cwd: ".", pipeline(
r#"
[[a,b]; [1,2] [3,4]]
| reduce -f 1.6 { $it.acc * ($it.item.a | into int) + ($it.item.b | into int) }
"#
)
);
assert_eq!(actual.out, "14.8");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn reduce_numbered_example() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo one longest three bar
| reduce -n { if ($it.item.item | str length) > ($it.acc.item | str length) {echo $it.item} else {echo $it.acc}}
| get index
"#
)
);
assert_eq!(actual.out, "1");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn reduce_numbered_integer_addition_example() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [1 2 3 4]
| reduce -n { $it.acc.item + $it.item.item }
| get item
"#
)
);
assert_eq!(actual.out, "10");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn folding_with_tables() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [10 20 30 40]
| reduce -f [] {
with-env [value $it.item] {
echo $acc | append (10 * ($env.value | into int))
}
}
| math sum
"#
)
);
assert_eq!(actual.out, "1000");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn error_reduce_fold_type_mismatch() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo a b c | reduce -f 0 { $it.acc + $it.item }
"#
)
);
assert!(actual.err.contains("mismatch"));
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn error_reduce_empty() {
let actual = nu!(
cwd: ".", pipeline(
r#"
reduce { $it.$acc + $it.item }
"#
)
);
assert!(actual.err.contains("needs input"));
}

View File

@ -0,0 +1,91 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn changes_the_column_name() {
Playground::setup("rename_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_cuatro_mosqueteros.txt",
r#"
Andrés N. Robalino
Jonathan Turner
Yehuda Katz
Jason Gedge
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_cuatro_mosqueteros.txt
| lines
| wrap name
| rename mosqueteros
| get mosqueteros
| length
"#
));
assert_eq!(actual.out, "4");
})
}
#[test]
fn keeps_remaining_original_names_given_less_new_names_than_total_original_names() {
Playground::setup("rename_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_cuatro_mosqueteros.txt",
r#"
Andrés N. Robalino
Jonathan Turner
Yehuda Katz
Jason Gedge
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_cuatro_mosqueteros.txt
| lines
| wrap name
| default hit "arepa!"
| rename mosqueteros
| get hit
| length
"#
));
assert_eq!(actual.out, "4");
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn errors_if_no_columns_present() {
Playground::setup("rename_test_3", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_cuatro_mosqueteros.txt",
r#"
Andrés N. Robalino
Jonathan Turner
Yehuda Katz
Jason Gedge
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_cuatro_mosqueteros.txt
| lines
| rename mosqueteros
"#
));
assert!(actual.err.contains("no column names available"));
assert!(actual.err.contains("can't rename"));
})
}

View File

@ -0,0 +1,11 @@
use nu_test_support::nu;
#[test]
fn can_get_reverse_first() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"ls | sort-by name | reverse | first 1 | get name | str trim "
);
assert_eq!(actual.out, "utf16.ini");
}

View File

@ -0,0 +1,334 @@
use nu_test_support::fs::{files_exist_at, Stub::EmptyFile};
use nu_test_support::nu;
use nu_test_support::playground::Playground;
#[test]
fn removes_a_file() {
Playground::setup("rm_test_1", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("i_will_be_deleted.txt")]);
nu!(
cwd: dirs.root(),
"rm rm_test_1/i_will_be_deleted.txt"
);
let path = dirs.test().join("i_will_be_deleted.txt");
assert!(!path.exists());
})
}
#[test]
fn removes_files_with_wildcard() {
Playground::setup("rm_test_2", |dirs, sandbox| {
sandbox
.within("src")
.with_files(vec![
EmptyFile("cli.rs"),
EmptyFile("lib.rs"),
EmptyFile("prelude.rs"),
])
.within("src/parser")
.with_files(vec![EmptyFile("parse.rs"), EmptyFile("parser.rs")])
.within("src/parser/parse")
.with_files(vec![EmptyFile("token_tree.rs")])
.within("src/parser/hir")
.with_files(vec![
EmptyFile("baseline_parse.rs"),
EmptyFile("baseline_parse_tokens.rs"),
]);
nu!(
cwd: dirs.test(),
r#"rm "src/*/*/*.rs""#
);
assert!(!files_exist_at(
vec![
"src/parser/parse/token_tree.rs",
"src/parser/hir/baseline_parse.rs",
"src/parser/hir/baseline_parse_tokens.rs"
],
dirs.test()
));
assert_eq!(
Playground::glob_vec(&format!("{}/src/*/*/*.rs", dirs.test().display())),
Vec::<std::path::PathBuf>::new()
);
})
}
#[test]
fn removes_deeply_nested_directories_with_wildcard_and_recursive_flag() {
Playground::setup("rm_test_3", |dirs, sandbox| {
sandbox
.within("src")
.with_files(vec![
EmptyFile("cli.rs"),
EmptyFile("lib.rs"),
EmptyFile("prelude.rs"),
])
.within("src/parser")
.with_files(vec![EmptyFile("parse.rs"), EmptyFile("parser.rs")])
.within("src/parser/parse")
.with_files(vec![EmptyFile("token_tree.rs")])
.within("src/parser/hir")
.with_files(vec![
EmptyFile("baseline_parse.rs"),
EmptyFile("baseline_parse_tokens.rs"),
]);
nu!(
cwd: dirs.test(),
"rm -r src/*"
);
assert!(!files_exist_at(
vec!["src/parser/parse", "src/parser/hir"],
dirs.test()
));
})
}
#[test]
fn removes_directory_contents_without_recursive_flag_if_empty() {
Playground::setup("rm_test_4", |dirs, _| {
nu!(
cwd: dirs.root(),
"rm rm_test_4"
);
assert!(!dirs.test().exists());
})
}
#[test]
fn removes_directory_contents_with_recursive_flag() {
Playground::setup("rm_test_5", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("yehuda.txt"),
EmptyFile("jonathan.txt"),
EmptyFile("andres.txt"),
]);
nu!(
cwd: dirs.root(),
"rm rm_test_5 --recursive"
);
assert!(!dirs.test().exists());
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn errors_if_attempting_to_delete_a_directory_with_content_without_recursive_flag() {
Playground::setup("rm_test_6", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("some_empty_file.txt")]);
let actual = nu!(
cwd: dirs.root(),
"rm rm_test_6"
);
assert!(dirs.test().exists());
assert!(actual.err.contains("cannot remove non-empty directory"));
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn errors_if_attempting_to_delete_single_dot_as_argument() {
Playground::setup("rm_test_7", |dirs, _| {
let actual = nu!(
cwd: dirs.root(),
"rm ."
);
assert!(actual.err.contains("cannot remove any parent directory"));
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn errors_if_attempting_to_delete_two_dot_as_argument() {
Playground::setup("rm_test_8", |dirs, _| {
let actual = nu!(
cwd: dirs.root(),
"rm .."
);
assert!(actual.err.contains("cannot remove any parent directory"));
})
}
#[test]
fn removes_multiple_directories() {
Playground::setup("rm_test_9", |dirs, sandbox| {
sandbox
.within("src")
.with_files(vec![EmptyFile("a.rs"), EmptyFile("b.rs")])
.within("src/cli")
.with_files(vec![EmptyFile("c.rs"), EmptyFile("d.rs")])
.within("test")
.with_files(vec![EmptyFile("a_test.rs"), EmptyFile("b_test.rs")]);
nu!(
cwd: dirs.test(),
"rm src test --recursive"
);
assert_eq!(
Playground::glob_vec(&format!("{}/*", dirs.test().display())),
Vec::<std::path::PathBuf>::new()
);
})
}
#[test]
fn removes_multiple_files() {
Playground::setup("rm_test_10", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("yehuda.txt"),
EmptyFile("jonathan.txt"),
EmptyFile("andres.txt"),
]);
nu!(
cwd: dirs.test(),
"rm yehuda.txt jonathan.txt andres.txt"
);
assert_eq!(
Playground::glob_vec(&format!("{}/*", dirs.test().display())),
Vec::<std::path::PathBuf>::new()
);
})
}
#[test]
fn removes_multiple_files_with_asterisks() {
Playground::setup("rm_test_11", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("yehuda.txt"),
EmptyFile("jonathan.txt"),
EmptyFile("andres.toml"),
]);
nu!(
cwd: dirs.test(),
"rm *.txt *.toml"
);
assert_eq!(
Playground::glob_vec(&format!("{}/*", dirs.test().display())),
Vec::<std::path::PathBuf>::new()
);
})
}
#[test]
fn allows_doubly_specified_file() {
Playground::setup("rm_test_12", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("yehuda.txt"), EmptyFile("jonathan.toml")]);
let actual = nu!(
cwd: dirs.test(),
"rm *.txt yehuda* *.toml"
);
assert_eq!(
Playground::glob_vec(&format!("{}/*", dirs.test().display())),
Vec::<std::path::PathBuf>::new()
);
assert!(!actual.out.contains("error"))
})
}
#[test]
fn remove_files_from_two_parents_up_using_multiple_dots_and_glob() {
Playground::setup("rm_test_13", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("yehuda.txt"),
EmptyFile("jonathan.txt"),
EmptyFile("kevin.txt"),
]);
sandbox.within("foo").mkdir("bar");
nu!(
cwd: dirs.test().join("foo/bar"),
"rm .../*.txt"
);
assert!(!files_exist_at(
vec!["yehuda.txt", "jonathan.txt", "kevin.txt"],
dirs.test()
));
})
}
#[test]
fn no_errors_if_attempting_to_delete_non_existent_file_with_f_flag() {
Playground::setup("rm_test_14", |dirs, _| {
let actual = nu!(
cwd: dirs.root(),
"rm -f non_existent_file.txt"
);
assert!(!actual.err.contains("no valid path"));
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn rm_wildcard_keeps_dotfiles() {
Playground::setup("rm_test_15", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("foo"), EmptyFile(".bar")]);
nu!(
cwd: dirs.test(),
r#"rm *"#
);
assert!(!files_exist_at(vec!["foo"], dirs.test()));
assert!(files_exist_at(vec![".bar"], dirs.test()));
})
}
#[test]
fn rm_wildcard_leading_dot_deletes_dotfiles() {
Playground::setup("rm_test_16", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("foo"), EmptyFile(".bar")]);
nu!(
cwd: dirs.test(),
r#"rm .*"#
);
assert!(files_exist_at(vec!["foo"], dirs.test()));
assert!(!files_exist_at(vec![".bar"], dirs.test()));
})
}
#[test]
fn removes_files_with_case_sensitive_glob_matches_by_default() {
Playground::setup("glob_test", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("A0"), EmptyFile("a1")]);
nu!(
cwd: dirs.root(),
"rm glob_test/A*"
);
let deleted_path = dirs.test().join("A0");
let skipped_path = dirs.test().join("a1");
assert!(!deleted_path.exists());
assert!(skipped_path.exists());
})
}

View File

@ -0,0 +1,178 @@
use nu_test_support::{nu, pipeline};
mod rows {
use super::*;
fn table() -> String {
pipeline(
r#"
echo [
[service, status];
[ruby, DOWN]
[db, DOWN]
[nud, DOWN]
[expected, HERE]
]"#,
)
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn roll_down_by_default() {
let actual = nu!(
cwd: ".",
format!("{} | {}", table(), pipeline(r#"
roll
| first
| get status
"#)));
assert_eq!(actual.out, "HERE");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn can_roll_up() {
let actual = nu!(
cwd: ".",
format!("{} | {}", table(), pipeline(r#"
roll up 3
| first
| get status
"#)));
assert_eq!(actual.out, "HERE");
}
}
mod columns {
use super::*;
fn table() -> String {
pipeline(
r#"
echo [
[commit_author, origin, stars];
[ "Andres", EC, amarillito]
[ "Darren", US, black]
[ "Jonathan", US, black]
[ "Yehuda", US, black]
[ "Jason", CA, gold]
]"#,
)
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn roll_left_by_default() {
let actual = nu!(
cwd: ".",
format!("{} | {}", table(), pipeline(r#"
roll column
| get
| str collect "-"
"#)));
assert_eq!(actual.out, "origin-stars-commit_author");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn can_roll_in_the_opposite_direction() {
let actual = nu!(
cwd: ".",
format!("{} | {}", table(), pipeline(r#"
roll column 2 --opposite
| get
| str collect "-"
"#)));
assert_eq!(actual.out, "origin-stars-commit_author");
}
struct ThirtieTwo<'a>(usize, &'a str);
// FIXME: jt: needs more work
#[ignore]
#[test]
fn can_roll_the_cells_only_keeping_the_header_names() {
let four_bitstring = bitstring_to_nu_row_pipeline("00000100");
let expected_value = ThirtieTwo(32, "bit1-bit2-bit3-bit4-bit5-bit6-bit7-bit8");
let actual = nu!(
cwd: ".",
format!("{} | roll column 3 --opposite --cells-only | get | str collect '-' ", four_bitstring)
);
assert_eq!(actual.out, expected_value.1);
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn four_in_bitstring_left_shifted_with_three_bits_should_be_32_in_decimal() {
let four_bitstring = "00000100";
let expected_value = ThirtieTwo(32, "00100000");
assert_eq!(
shift_three_bits_to_the_left_to_bitstring(four_bitstring),
expected_value.0.to_string()
);
}
fn shift_three_bits_to_the_left_to_bitstring(bits: &str) -> String {
// this pipeline takes the bitstring and outputs a nu row literal
// for example the number 4 in bitstring:
//
// input: 00000100
//
// output:
// [
// [Column1, Column2, Column3, Column4, Column5, Column6, Column7, Column8];
// [ 0, 0, 0, 0, 0, 1, 0, 0]
// ]
//
let bitstring_as_nu_row_pipeline = bitstring_to_nu_row_pipeline(bits);
// this pipeline takes the nu bitstring row literal, computes it's
// decimal value.
let nu_row_literal_bitstring_to_decimal_value_pipeline = pipeline(
r#"
pivot bit --ignore-titles
| get bit
| reverse
| each --numbered {
$it.item * (2 ** $it.index)
}
| math sum
"#,
);
nu!(
cwd: ".",
format!("{} | roll column 3 | {}", bitstring_as_nu_row_pipeline, nu_row_literal_bitstring_to_decimal_value_pipeline)
).out
}
fn bitstring_to_nu_row_pipeline(bits: &str) -> String {
format!(
"echo '{}' | {}",
bits,
pipeline(
r#"
split chars
| each { into int }
| rotate counter-clockwise _
| reject _
| rename bit1 bit2 bit3 bit4 bit5 bit6 bit7 bit8
"#
)
)
}
}

View File

@ -0,0 +1,85 @@
use nu_test_support::{nu, pipeline};
// FIXME: jt: needs more work
#[ignore]
#[test]
fn counter_clockwise() {
let table = pipeline(
r#"
echo [
[col1, col2, EXPECTED];
[---, "|||", XX1]
[---, "|||", XX2]
[---, "|||", XX3]
]
"#,
);
let expected = nu!(cwd: ".", pipeline(
r#"
echo [
[ Column0, Column1, Column2, Column3];
[ EXPECTED, XX1, XX2, XX3]
[ col2, "|||", "|||", "|||"]
[ col1, ---, ---, ---]
]
| where Column0 == EXPECTED
| get Column1 Column2 Column3
| str collect "-"
"#,
));
let actual = nu!(
cwd: ".",
format!("{} | {}", table, pipeline(r#"
rotate counter-clockwise
| where Column0 == EXPECTED
| get Column1 Column2 Column3
| str collect "-"
"#)));
assert_eq!(actual.out, expected.out);
}
#[test]
fn clockwise() {
let table = pipeline(
r#"
echo [
[col1, col2, EXPECTED];
[ ---, "|||", XX1]
[ ---, "|||", XX2]
[ ---, "|||", XX3]
]
"#,
);
let expected = nu!(cwd: ".", pipeline(
r#"
echo [
[ Column0, Column1, Column2, Column3];
[ ---, ---, ---, col1]
[ "|||", "|||", "|||", col2]
[ XX3, XX2, XX1, EXPECTED]
]
| where Column3 == EXPECTED
| get Column0 Column1 Column2
| str collect "-"
"#,
));
let actual = nu!(
cwd: ".",
format!("{} | {}", table, pipeline(r#"
rotate
| where Column3 == EXPECTED
| get Column0 Column1 Column2
| str collect "-"
"#)));
assert_eq!(actual.out, expected.out);
}

View File

@ -0,0 +1,69 @@
use nu_test_support::fs::{file_contents, Stub::FileWithContent};
use nu_test_support::nu;
use nu_test_support::playground::Playground;
#[test]
fn figures_out_intelligently_where_to_write_out_with_metadata() {
Playground::setup("save_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"cargo_sample.toml",
r#"
[package]
name = "nu"
version = "0.1.1"
authors = ["Yehuda Katz <wycats@gmail.com>"]
description = "A shell for the GitHub era"
license = "ISC"
edition = "2018"
"#,
)]);
let subject_file = dirs.test().join("cargo_sample.toml");
nu!(
cwd: dirs.root(),
"open save_test_1/cargo_sample.toml | save"
);
let actual = file_contents(&subject_file);
assert!(actual.contains("0.1.1"));
})
}
#[test]
fn writes_out_csv() {
Playground::setup("save_test_2", |dirs, sandbox| {
sandbox.with_files(vec![]);
let expected_file = dirs.test().join("cargo_sample.csv");
nu!(
cwd: dirs.root(),
r#"echo [[name, version, description, license, edition]; [nu, "0.14", "A new type of shell", "MIT", "2018"]] | save save_test_2/cargo_sample.csv"#,
);
let actual = file_contents(expected_file);
println!("{}", actual);
assert!(actual.contains("nu,0.14,A new type of shell,MIT,2018"));
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn save_append_will_create_file_if_not_exists() {
Playground::setup("save_test_3", |dirs, sandbox| {
sandbox.with_files(vec![]);
let expected_file = dirs.test().join("new-file.txt");
nu!(
cwd: dirs.root(),
r#"echo hello | save --raw --append save_test_3/new-file.txt"#,
);
let actual = file_contents(expected_file);
println!("{}", actual);
assert!(actual == "hello");
})
}

View File

@ -0,0 +1,128 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn regular_columns() {
let actual = nu!(cwd: ".", pipeline(
r#"
echo [
[first_name, last_name, rusty_at, type];
[Andrés Robalino 10/11/2013 A]
[Jonathan Turner 10/12/2013 B]
[Yehuda Katz 10/11/2013 A]
]
| select rusty_at last_name
| nth 0
| get last_name
"#
));
assert_eq!(actual.out, "Robalino");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn complex_nested_columns() {
Playground::setup("select_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.json",
r#"
{
"nu": {
"committers": [
{"name": "Andrés N. Robalino"},
{"name": "Jonathan Turner"},
{"name": "Yehuda Katz"}
],
"releases": [
{"version": "0.2"}
{"version": "0.8"},
{"version": "0.9999999"}
],
"0xATYKARNU": [
["Th", "e", " "],
["BIG", " ", "UnO"],
["punto", "cero"]
]
}
}
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_caballeros.json
| select nu."0xATYKARNU" nu.committers.name nu.releases.version
| where nu_releases_version > "0.8"
| get nu_releases_version
"#
));
assert_eq!(actual.out, "0.9999999");
})
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn allows_if_given_unknown_column_name_is_missing() {
let actual = nu!(cwd: ".", pipeline(
r#"
echo [
[first_name, last_name, rusty_at, type];
[Andrés Robalino 10/11/2013 A]
[Jonathan Turner 10/12/2013 B]
[Yehuda Katz 10/11/2013 A]
]
| select rrusty_at first_name
| length
"#
));
assert_eq!(actual.out, "3");
}
#[test]
fn column_names_with_spaces() {
let actual = nu!(cwd: ".", pipeline(
r#"
echo [
["first name", "last name"];
[Andrés Robalino]
[Andrés Jnth]
]
| select "last name"
| get "last name"
| str collect " "
"#
));
assert_eq!(actual.out, "Robalino Jnth");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn ignores_duplicate_columns_selected() {
let actual = nu!(cwd: ".", pipeline(
r#"
echo [
["first name", "last name"];
[Andrés Robalino]
[Andrés Jnth]
]
| select "first name" "last name" "first name"
| get
| str collect " "
"#
));
assert_eq!(actual.out, "first name last name");
}

View File

@ -0,0 +1,29 @@
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn semicolon_allows_lhs_to_complete() {
Playground::setup("create_test_1", |dirs, _sandbox| {
let actual = nu!(
cwd: dirs.test(),
"touch i_will_be_created_semi.txt; echo done"
);
let path = dirs.test().join("i_will_be_created_semi.txt");
assert!(path.exists());
assert_eq!(actual.out, "done");
})
}
#[test]
fn semicolon_lhs_error_stops_processing() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
where 1 1; echo done
"#
));
assert!(!actual.out.contains("done"));
}

View File

@ -0,0 +1,2 @@
mod until;
mod while_;

View File

@ -0,0 +1,51 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn condition_is_met() {
Playground::setup("skip_until_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"caballeros.txt",
r#"
CHICKEN SUMMARY report date: April 29th, 2020
--------------------------------------------------------------------
Chicken Collection,29/04/2020,30/04/2020,31/04/2020
Yellow Chickens,,,
Andrés,0,0,1
Jonathan,0,0,1
Jason,0,0,1
Yehuda,0,0,1
Blue Chickens,,,
Andrés,0,0,1
Jonathan,0,0,1
Jason,0,0,1
Yehuda,0,0,2
Red Chickens,,,
Andrés,0,0,1
Jonathan,0,0,1
Jason,0,0,1
Yehuda,0,0,3
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open --raw ./caballeros.txt
| lines
| skip 2
| str trim
| str collect (char nl)
| from csv
| skip until "Chicken Collection" == "Red Chickens"
| skip 1
| into int "31/04/2020"
| get "31/04/2020"
| math sum
"#
));
assert_eq!(actual.out, "6");
})
}

View File

@ -0,0 +1,51 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn condition_is_met() {
Playground::setup("skip_while_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"caballeros.txt",
r#"
CHICKEN SUMMARY report date: April 29th, 2020
--------------------------------------------------------------------
Chicken Collection,29/04/2020,30/04/2020,31/04/2020
Yellow Chickens,,,
Andrés,0,0,1
Jonathan,0,0,1
Jason,0,0,1
Yehuda,0,0,1
Blue Chickens,,,
Andrés,0,0,1
Jonathan,0,0,1
Jason,0,0,1
Yehuda,0,0,2
Red Chickens,,,
Andrés,0,0,1
Jonathan,0,0,1
Jason,0,0,1
Yehuda,0,0,3
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open --raw caballeros.txt
| lines
| skip 2
| str trim
| str collect (char nl)
| from csv
| skip while "Chicken Collection" != "Red Chickens"
| skip 1
| into int "31/04/2020"
| get "31/04/2020"
| math sum
"#
));
assert_eq!(actual.out, "6");
})
}

View File

@ -0,0 +1,160 @@
use nu_test_support::{nu, pipeline};
// FIXME: jt: needs more work
#[ignore]
#[test]
fn by_column() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open cargo_sample.toml --raw
| lines
| skip 1
| first 4
| split column "="
| sort-by Column1
| skip 1
| first 1
| get Column1
| str trim
"#
));
assert_eq!(actual.out, "description");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn by_invalid_column() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open cargo_sample.toml --raw
| lines
| skip 1
| first 4
| split column "="
| sort-by ColumnThatDoesNotExist
| skip 1
| first 1
| get Column1
| str trim
"#
));
assert!(actual.err.contains("Can not find column to sort by"));
assert!(actual.err.contains("invalid column"));
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn by_invalid_types() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open cargo_sample.toml --raw
| echo [1 "foo"]
| sort-by
"#
));
assert!(actual.err.contains("Not all values can be compared"));
assert!(actual
.err
.contains("Unable to sort values, as \"integer\" cannot compare against \"string\""));
}
#[test]
fn sort_primitive_values() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open cargo_sample.toml --raw
| lines
| skip 1
| first 6
| sort-by
| first 1
"#
));
assert_eq!(actual.out, "authors = [\"The Nu Project Contributors\"]");
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn ls_sort_by_name_sensitive() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample-ls-output.json
| sort-by name
| select name
| to json --raw
"#
));
let json_output = r#"[{"name":"B.txt"},{"name":"C"},{"name":"a.txt"}]"#;
assert_eq!(actual.out, json_output);
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn ls_sort_by_name_insensitive() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample-ls-output.json
| sort-by -i name
| select name
| to json --raw
"#
));
let json_output = r#"[{"name":"a.txt"},{"name":"B.txt"},{"name":"C"}]"#;
assert_eq!(actual.out, json_output);
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn ls_sort_by_type_name_sensitive() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample-ls-output.json
| sort-by type name
| select name type
| to json --raw
"#
));
let json_output = r#"[{"name":"C","type":"Dir"},{"name":"B.txt","type":"File"},{"name":"a.txt","type":"File"}]"#;
assert_eq!(actual.out, json_output);
}
// FIXME: jt: needs more work
#[ignore]
#[test]
fn ls_sort_by_type_name_insensitive() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample-ls-output.json
| sort-by -i type name
| select name type
| to json --raw
"#
));
let json_output = r#"[{"name":"C","type":"Dir"},{"name":"a.txt","type":"File"},{"name":"B.txt","type":"File"}]"#;
assert_eq!(actual.out, json_output);
}

View File

@ -0,0 +1,153 @@
use nu_test_support::fs::{AbsolutePath, DisplayPath, Stub::FileWithContent};
use nu_test_support::nu;
use nu_test_support::pipeline;
use nu_test_support::playground::Playground;
#[should_panic]
#[test]
fn sources_also_files_under_custom_lib_dirs_path() {
Playground::setup("source_test_1", |dirs, nu| {
let file = AbsolutePath::new(dirs.test().join("config.toml"));
let library_path = AbsolutePath::new(dirs.test().join("lib"));
nu.with_config(&file);
nu.with_files(vec![FileWithContent(
"config.toml",
&format!(
r#"
lib_dirs = ["{}"]
skip_welcome_message = true
"#,
library_path.display_path()
),
)]);
nu.within("lib").with_files(vec![FileWithContent(
"my_library.nu",
r#"
source my_library/main.nu
"#,
)]);
nu.within("lib/my_library").with_files(vec![FileWithContent(
"main.nu",
r#"
def hello [] {
echo "hello nu"
}
"#,
)]);
let actual = nu!(
cwd: ".", pipeline(
r#"
source my_library.nu ;
hello
"#
));
assert_eq!(actual.out, "hello nu");
})
}
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");
});
}
// FIXME: jt: needs more work
#[ignore]
#[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");
}
// FIXME: jt: needs more work
#[ignore]
#[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");
}
// FIXME: jt: needs more work
#[ignore]
#[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");
}
// FIXME: jt: needs more work
#[ignore]
#[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");
}
// FIXME: jt: needs more work
#[ignore]
#[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

@ -0,0 +1,54 @@
use nu_test_support::fs::Stub::{EmptyFile, FileWithContentToBeTrimmed};
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn splits() {
Playground::setup("split_by_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.csv",
r#"
first_name,last_name,rusty_at,type
Andrés,Robalino,10/11/2013,A
Jonathan,Turner,10/12/2013,B
Yehuda,Katz,10/11/2013,A
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_caballeros.csv
| group-by rusty_at
| split-by type
| get A."10/11/2013"
| length
"#
));
assert_eq!(actual.out, "2");
})
}
#[test]
fn errors_if_no_table_given_as_input() {
Playground::setup("split_by_test_2", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("los.txt"),
EmptyFile("tres.txt"),
EmptyFile("amigos.txt"),
EmptyFile("arepas.clu"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| get name
| split-by type
"#
));
assert!(actual.err.contains("requires a table"));
})
}

View File

@ -0,0 +1,28 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn to_column() {
Playground::setup("split_column_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"sample.txt",
r#"
importer,shipper,tariff_item,name,origin
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.txt
| lines
| str trim
| split column ","
| get Column2
"#
));
assert!(actual.out.contains("shipper"));
})
}

View File

@ -0,0 +1,28 @@
use nu_test_support::fs::Stub::FileWithContentToBeTrimmed;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn to_row() {
Playground::setup("split_row_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"sample.txt",
r#"
importer,shipper,tariff_item,name,origin
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.txt
| lines
| str trim
| split row ","
| length
"#
));
assert!(actual.out.contains('5'));
})
}

View File

@ -0,0 +1,53 @@
use nu_test_support::{nu, pipeline};
#[test]
fn test_1() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo 1..5 | into string | str collect
"#
)
);
assert_eq!(actual.out, "12345");
}
#[test]
fn test_2() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [a b c d] | str collect "<sep>"
"#
)
);
assert_eq!(actual.out, "a<sep>b<sep>c<sep>d");
}
#[test]
fn construct_a_path() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo [sample txt] | str collect "."
"#
)
);
assert_eq!(actual.out, "sample.txt");
}
#[test]
fn sum_one_to_four() {
let actual = nu!(
cwd: ".", pipeline(
r#"
1..4 | each { $it } | into string | str collect "+" | math eval
"#
)
);
assert!(actual.out.contains("10"));
}

View File

@ -0,0 +1,158 @@
use nu_test_support::playground::{Dirs, Playground};
use nu_test_support::{nu, pipeline};
#[test]
fn from_range() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo 1..5 | into string | to json
"#
)
);
assert_eq!(actual.out, "[\"1\",\"2\",\"3\",\"4\",\"5\"]");
}
#[test]
fn from_number() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo 5 | into string
"#
)
);
assert_eq!(actual.out, "5");
}
#[test]
fn from_decimal() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo 1.5 | into string
"#
)
);
assert_eq!(actual.out, "1.5");
}
#[test]
fn from_boolean() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo $true | into string
"#
)
);
assert_eq!(actual.out, "true");
}
#[test]
fn from_string() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo "one" | into string
"#
)
);
assert_eq!(actual.out, "one");
}
#[test]
fn from_filename() {
Playground::setup("from_filename", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"sample.toml",
r#"
[dependency]
name = "nu"
"#,
)]);
let actual = nu!(
cwd: dirs.test(),
"ls sample.toml | get name | into string"
);
assert_eq!(actual.out, "sample.toml");
})
}
#[test]
fn from_filesize() {
Playground::setup("from_filesize", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"sample.toml",
r#"
[dependency]
name = "nu"
"#,
)]);
let actual = nu!(
cwd: dirs.test(),
"ls sample.toml | get size | into string"
);
assert_eq!(actual.out, "25 B");
})
}
#[test]
fn from_decimal_correct_trailing_zeros() {
let actual = nu!(
cwd: ".", pipeline(
r#"
= 1.23000 | into string -d 3
"#
));
assert!(actual.out.contains("1.230"));
}
#[test]
fn from_int_decimal_correct_trailing_zeros() {
let actual = nu!(
cwd: ".", pipeline(
r#"
= 1.00000 | into string -d 3
"#
));
assert!(actual.out.contains("1.000"));
}
#[test]
fn from_int_decimal_trim_trailing_zeros() {
let actual = nu!(
cwd: ".", pipeline(
r#"
= 1.00000 | into string | format "{$it} flat"
"#
));
assert!(actual.out.contains("1 flat")); // "1" would match "1.0"
}
#[test]
fn from_table() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo '[{"name": "foo", "weight": 32.377}, {"name": "bar", "weight": 15.2}]'
| from json
| into string weight -d 2
"#
));
assert!(actual.out.contains("32.38"));
assert!(actual.out.contains("15.20"));
}

View File

@ -0,0 +1,356 @@
mod collect;
use nu_test_support::fs::Stub::FileWithContent;
use nu_test_support::playground::Playground;
use nu_test_support::{nu, pipeline};
#[test]
fn trims() {
Playground::setup("str_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[dependency]
name = "nu "
"#,
)]);
let actual = nu!(
cwd: dirs.test(),
"open sample.toml | str trim dependency.name | get dependency.name"
);
assert_eq!(actual.out, "nu");
})
}
#[test]
fn error_trim_multiple_chars() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo "does it work now?!" | str trim -c "?!"
"#
)
);
assert!(actual.err.contains("char"));
}
#[test]
fn capitalizes() {
Playground::setup("str_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[dependency]
name = "nu"
"#,
)]);
let actual = nu!(
cwd: dirs.test(),
"open sample.toml | str capitalize dependency.name | get dependency.name"
);
assert_eq!(actual.out, "Nu");
})
}
#[test]
fn downcases() {
Playground::setup("str_test_3", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[dependency]
name = "LIGHT"
"#,
)]);
let actual = nu!(
cwd: dirs.test(),
"open sample.toml | str downcase dependency.name | get dependency.name"
);
assert_eq!(actual.out, "light");
})
}
#[test]
fn upcases() {
Playground::setup("str_test_4", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[package]
name = "nushell"
"#,
)]);
let actual = nu!(
cwd: dirs.test(),
"open sample.toml | str upcase package.name | get package.name"
);
assert_eq!(actual.out, "NUSHELL");
})
}
#[test]
fn camelcases() {
Playground::setup("str_test_3", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[dependency]
name = "THIS_IS_A_TEST"
"#,
)]);
let actual = nu!(
cwd: dirs.test(),
"open sample.toml | str camel-case dependency.name | get dependency.name"
);
assert_eq!(actual.out, "thisIsATest");
})
}
#[test]
fn converts_to_int() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
echo '{number_as_string: "1"}'
| from json
| into int number_as_string
| rename number
| where number == 1
| get number
"#
));
assert_eq!(actual.out, "1");
}
#[test]
fn converts_to_decimal() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
echo "3.1, 0.0415"
| split row ","
| into decimal
| math sum
"#
));
assert_eq!(actual.out, "3.1415");
}
#[test]
fn find_and_replaces() {
Playground::setup("str_test_6", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[fortune.teller]
phone = "1-800-KATZ"
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| str find-replace KATZ "5289" fortune.teller.phone
| get fortune.teller.phone
"#
));
assert_eq!(actual.out, "1-800-5289");
})
}
#[test]
fn find_and_replaces_without_passing_field() {
Playground::setup("str_test_7", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[fortune.teller]
phone = "1-800-KATZ"
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| get fortune.teller.phone
| str find-replace KATZ "5289"
"#
));
assert_eq!(actual.out, "1-800-5289");
})
}
#[test]
fn substrings_the_input() {
Playground::setup("str_test_8", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[fortune.teller]
phone = "1-800-ROBALINO"
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| str substring 6,14 fortune.teller.phone
| get fortune.teller.phone
"#
));
assert_eq!(actual.out, "ROBALINO");
})
}
#[test]
fn substring_errors_if_start_index_is_greater_than_end_index() {
Playground::setup("str_test_9", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[fortune.teller]
phone = "1-800-ROBALINO"
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| str substring 6,5 fortune.teller.phone
"#
));
assert!(actual
.err
.contains("End must be greater than or equal to Start"))
})
}
#[test]
fn substrings_the_input_and_returns_the_string_if_end_index_exceeds_length() {
Playground::setup("str_test_10", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[package]
name = "nu-arepas"
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| str substring 0,999 package.name
| get package.name
"#
));
assert_eq!(actual.out, "nu-arepas");
})
}
#[test]
fn substrings_the_input_and_returns_blank_if_start_index_exceeds_length() {
Playground::setup("str_test_11", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[package]
name = "nu-arepas"
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| str substring 50,999 package.name
| get package.name
"#
));
assert_eq!(actual.out, "");
})
}
#[test]
fn substrings_the_input_and_treats_start_index_as_zero_if_blank_start_index_given() {
Playground::setup("str_test_12", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[package]
name = "nu-arepas"
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| str substring ,2 package.name
| get package.name
"#
));
assert_eq!(actual.out, "nu");
})
}
#[test]
fn substrings_the_input_and_treats_end_index_as_length_if_blank_end_index_given() {
Playground::setup("str_test_13", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[package]
name = "nu-arepas"
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| str substring 3, package.name
| get package.name
"#
));
assert_eq!(actual.out, "arepas");
})
}
#[test]
fn str_reverse() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo "nushell" | str reverse
"#
));
assert!(actual.out.contains("llehsun"));
}

View File

@ -0,0 +1,31 @@
use nu_test_support::nu;
use nu_test_support::playground::Playground;
#[test]
fn creates_a_file_when_it_doesnt_exist() {
Playground::setup("create_test_1", |dirs, _sandbox| {
nu!(
cwd: dirs.test(),
"touch i_will_be_created.txt"
);
let path = dirs.test().join("i_will_be_created.txt");
assert!(path.exists());
})
}
#[test]
fn creates_two_files() {
Playground::setup("create_test_2", |dirs, _sandbox| {
nu!(
cwd: dirs.test(),
"touch a b"
);
let path = dirs.test().join("a");
assert!(path.exists());
let path2 = dirs.test().join("b");
assert!(path2.exists());
})
}

Some files were not shown because too many files have changed in this diff Show More