Merge pull request #1081 from andrasio/test-extract

Start test organization facelift.
This commit is contained in:
Andrés N. Robalino 2019-12-15 11:46:58 -05:00 committed by GitHub
commit 6c577e18ca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
64 changed files with 2184 additions and 2340 deletions

12
Cargo.lock generated
View file

@ -2000,6 +2000,7 @@ dependencies = [
"tempfile",
"term",
"termcolor",
"test-support",
"textwrap",
"toml 0.5.5",
"trash",
@ -3408,6 +3409,17 @@ dependencies = [
"wincolor",
]
[[package]]
name = "test-support"
version = "0.1.0"
dependencies = [
"app_dirs",
"dunce",
"getset",
"glob",
"tempfile",
]
[[package]]
name = "textwrap"
version = "0.11.0"

View file

@ -158,6 +158,7 @@ features = ["bundled", "blob"]
[dev-dependencies]
pretty_assertions = "0.6.1"
test-support = { version = "0.1.0", path = "./crates/test-support" }
[build-dependencies]
toml = "0.5.5"

View file

@ -0,0 +1,16 @@
[package]
name = "test-support"
version = "0.1.0"
authors = ["Yehuda Katz <wycats@gmail.com>", "Jonathan Turner <jonathan.d.turner@gmail.com>", "Andrés N. Robalino <andres@androbtech.com>"]
edition = "2018"
description = "A source string characterizer for Nushell"
license = "MIT"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
app_dirs = "1.2.1"
dunce = "1.0.0"
getset = "0.0.9"
glob = "0.3.0"
tempfile = "3.1.0"

View file

@ -0,0 +1,228 @@
use std::io::Read;
use std::ops::Div;
use std::path::{Path, PathBuf};
pub struct AbsoluteFile {
inner: PathBuf,
}
impl AbsoluteFile {
pub fn new(path: impl AsRef<Path>) -> AbsoluteFile {
let path = path.as_ref();
if !path.is_absolute() {
panic!(
"AbsoluteFile::new must take an absolute path :: {}",
path.display()
)
} else if path.is_dir() {
// At the moment, this is not an invariant, but rather a way to catch bugs
// in tests.
panic!(
"AbsoluteFile::new must not take a directory :: {}",
path.display()
)
} else {
AbsoluteFile {
inner: path.to_path_buf(),
}
}
}
pub fn dir(&self) -> AbsolutePath {
AbsolutePath::new(self.inner.parent().unwrap())
}
}
impl From<AbsoluteFile> for PathBuf {
fn from(file: AbsoluteFile) -> Self {
file.inner
}
}
pub struct AbsolutePath {
inner: PathBuf,
}
impl AbsolutePath {
pub fn new(path: impl AsRef<Path>) -> AbsolutePath {
let path = path.as_ref();
if path.is_absolute() {
AbsolutePath {
inner: path.to_path_buf(),
}
} else {
panic!("AbsolutePath::new must take an absolute path")
}
}
}
impl Div<&str> for &AbsolutePath {
type Output = AbsolutePath;
fn div(self, rhs: &str) -> Self::Output {
let parts = rhs.split('/');
let mut result = self.inner.clone();
for part in parts {
result = result.join(part);
}
AbsolutePath::new(result)
}
}
impl AsRef<Path> for AbsolutePath {
fn as_ref(&self) -> &Path {
self.inner.as_path()
}
}
pub struct RelativePath {
inner: PathBuf,
}
impl RelativePath {
pub fn new(path: impl Into<PathBuf>) -> RelativePath {
let path = path.into();
if path.is_relative() {
RelativePath { inner: path }
} else {
panic!("RelativePath::new must take a relative path")
}
}
}
impl<T: AsRef<str>> Div<T> for &RelativePath {
type Output = RelativePath;
fn div(self, rhs: T) -> Self::Output {
let parts = rhs.as_ref().split('/');
let mut result = self.inner.clone();
for part in parts {
result = result.join(part);
}
RelativePath::new(result)
}
}
pub trait DisplayPath {
fn display_path(&self) -> String;
}
impl DisplayPath for AbsolutePath {
fn display_path(&self) -> String {
self.inner.display().to_string()
}
}
impl DisplayPath for PathBuf {
fn display_path(&self) -> String {
self.display().to_string()
}
}
impl DisplayPath for str {
fn display_path(&self) -> String {
self.to_string()
}
}
impl DisplayPath for &str {
fn display_path(&self) -> String {
self.to_string()
}
}
impl DisplayPath for String {
fn display_path(&self) -> String {
self.clone()
}
}
impl DisplayPath for &String {
fn display_path(&self) -> String {
self.to_string()
}
}
pub enum Stub<'a> {
FileWithContent(&'a str, &'a str),
FileWithContentToBeTrimmed(&'a str, &'a str),
EmptyFile(&'a str),
}
pub fn file_contents(full_path: impl AsRef<Path>) -> String {
let mut file = std::fs::File::open(full_path.as_ref()).expect("can not open file");
let mut contents = String::new();
file.read_to_string(&mut contents)
.expect("can not read file");
contents
}
pub fn file_contents_binary(full_path: impl AsRef<Path>) -> Vec<u8> {
let mut file = std::fs::File::open(full_path.as_ref()).expect("can not open file");
let mut contents = Vec::new();
file.read_to_end(&mut contents).expect("can not read file");
contents
}
pub fn line_ending() -> String {
#[cfg(windows)]
{
String::from("\r\n")
}
#[cfg(not(windows))]
{
String::from("\n")
}
}
pub fn delete_file_at(full_path: impl AsRef<Path>) {
let full_path = full_path.as_ref();
if full_path.exists() {
std::fs::remove_file(full_path).expect("can not delete file");
}
}
pub fn create_file_at(full_path: impl AsRef<Path>) -> Result<(), std::io::Error> {
let full_path = full_path.as_ref();
if let Some(parent) = full_path.parent() {
panic!(format!("{:?} exists", parent.display()));
}
std::fs::write(full_path, "fake data".as_bytes())
}
pub fn copy_file_to(source: &str, destination: &str) {
std::fs::copy(source, destination).expect("can not copy file");
}
pub fn files_exist_at(files: Vec<impl AsRef<Path>>, path: impl AsRef<Path>) -> bool {
files.iter().all(|f| {
let mut loc = PathBuf::from(path.as_ref());
loc.push(f);
loc.exists()
})
}
pub fn delete_directory_at(full_path: &str) {
std::fs::remove_dir_all(PathBuf::from(full_path)).expect("can not remove directory");
}
pub fn executable_path() -> PathBuf {
let mut buf = PathBuf::new();
buf.push("target");
buf.push("debug");
buf.push("nu");
buf
}
pub fn in_directory(str: impl AsRef<Path>) -> String {
str.as_ref().display().to_string()
}

View file

@ -0,0 +1,38 @@
pub mod fs;
pub mod macros;
pub mod playground;
pub fn pipeline(commands: &str) -> String {
commands
.lines()
.skip(1)
.map(|line| line.trim())
.collect::<Vec<&str>>()
.join(" ")
.trim_end()
.to_string()
}
#[cfg(tests)]
mod tests {
use super::pipeline;
#[test]
fn constructs_a_pipeline() {
let actual = pipeline(
r#"
open los_tres_amigos.txt
| from-csv
| get rusty_luck
| str --to-int
| sum
| echo "$it"
"#,
);
assert_eq!(
actual,
r#"open los_tres_amigos.txt | from-csv | get rusty_luck | str --to-int | sum | echo "$it""#
);
}
}

View file

@ -0,0 +1,159 @@
#[macro_export]
macro_rules! nu {
(cwd: $cwd:expr, $path:expr, $($part:expr),*) => {{
use $crate::fs::DisplayPath;
let path = format!($path, $(
$part.display_path()
),*);
nu!($cwd, &path)
}};
(cwd: $cwd:expr, $path:expr) => {{
nu!($cwd, $path)
}};
($cwd:expr, $path:expr) => {{
pub use std::error::Error;
pub use std::io::prelude::*;
pub use std::process::{Command, Stdio};
let commands = &*format!(
"
cd {}
{}
exit",
$crate::fs::in_directory($cwd),
$crate::fs::DisplayPath::display_path(&$path)
);
let mut process = match Command::new($crate::fs::executable_path())
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
{
Ok(child) => child,
Err(why) => panic!("Can't run test {}", why.description()),
};
let stdin = process.stdin.as_mut().expect("couldn't open stdin");
stdin
.write_all(commands.as_bytes())
.expect("couldn't write to stdin");
let output = process
.wait_with_output()
.expect("couldn't read from stdout");
let out = String::from_utf8_lossy(&output.stdout);
let out = out.replace("\r\n", "");
let out = out.replace("\n", "");
out
}};
}
#[macro_export]
macro_rules! nu_error {
(cwd: $cwd:expr, $path:expr, $($part:expr),*) => {{
use $crate::fs::DisplayPath;
let path = format!($path, $(
$part.display_path()
),*);
nu_error!($cwd, &path)
}};
(cwd: $cwd:expr, $path:expr) => {{
nu_error!($cwd, $path)
}};
($cwd:expr, $path:expr) => {{
pub use std::error::Error;
pub use std::io::prelude::*;
pub use std::process::{Command, Stdio};
let commands = &*format!(
"
cd {}
{}
exit",
$crate::fs::in_directory($cwd),
$crate::fs::DisplayPath::display_path(&$path)
);
let mut process = Command::new($crate::fs::executable_path())
.stdin(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("couldn't run test");
let stdin = process.stdin.as_mut().expect("couldn't open stdin");
stdin
.write_all(commands.as_bytes())
.expect("couldn't write to stdin");
let output = process
.wait_with_output()
.expect("couldn't read from stderr");
let out = String::from_utf8_lossy(&output.stderr);
out.into_owned()
}};
}
#[macro_export]
macro_rules! nu_combined {
(cwd: $cwd:expr, $path:expr, $($part:expr),*) => {{
use $crate::fs::DisplayPath;
let path = format!($path, $(
$part.display_path()
),*);
nu_combined!($cwd, &path)
}};
(cwd: $cwd:expr, $path:expr) => {{
nu_combined!($cwd, $path)
}};
($cwd:expr, $path:expr) => {{
pub use std::error::Error;
pub use std::io::prelude::*;
pub use std::process::{Command, Stdio};
let commands = &*format!(
"
cd {}
{}
exit",
$crate::fs::in_directory($cwd),
$crate::fs::DisplayPath::display_path(&$path)
);
let mut process = Command::new($crate::fs::executable_path())
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("couldn't run test");
let stdin = process.stdin.as_mut().expect("couldn't open stdin");
stdin
.write_all(commands.as_bytes())
.expect("couldn't write to stdin");
let output = process
.wait_with_output()
.expect("couldn't read from stdout/stderr");
let err = String::from_utf8_lossy(&output.stderr).into_owned();
let out = String::from_utf8_lossy(&output.stdout).into_owned();
let out = out.replace("\r\n", "");
let out = out.replace("\n", "");
(out, err)
}};
}

View file

@ -0,0 +1,152 @@
use crate::fs::line_ending;
use crate::fs::Stub;
use getset::Getters;
use glob::glob;
use std::path::{Path, PathBuf};
use tempfile::{tempdir, TempDir};
pub struct Playground {
root: TempDir,
tests: String,
cwd: PathBuf,
}
#[derive(Getters)]
#[get = "pub"]
pub struct Dirs {
pub root: PathBuf,
pub test: PathBuf,
pub fixtures: PathBuf,
}
impl Dirs {
pub fn formats(&self) -> PathBuf {
PathBuf::from(self.fixtures.join("formats"))
}
}
impl Playground {
pub fn root(&self) -> &Path {
self.root.path()
}
pub fn back_to_playground(&mut self) -> &mut Self {
self.cwd = PathBuf::from(self.root()).join(self.tests.clone());
self
}
pub fn setup(topic: &str, block: impl FnOnce(Dirs, &mut Playground)) {
let root = tempdir().expect("Couldn't create a tempdir");
let nuplay_dir = root.path().join(topic);
if PathBuf::from(&nuplay_dir).exists() {
std::fs::remove_dir_all(PathBuf::from(&nuplay_dir)).expect("can not remove directory");
}
std::fs::create_dir(PathBuf::from(&nuplay_dir)).expect("can not create directory");
let mut playground = Playground {
root: root,
tests: topic.to_string(),
cwd: nuplay_dir,
};
let project_root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let playground_root = playground.root.path();
let fixtures = project_root;
let fixtures = fixtures
.parent()
.expect("Couldn't find the fixtures directory")
.parent()
.expect("Couldn't find the fixtures directory")
.join("tests/fixtures");
let fixtures = dunce::canonicalize(fixtures.clone()).expect(&format!(
"Couldn't canonicalize fixtures path {}",
fixtures.display()
));
let test =
dunce::canonicalize(PathBuf::from(playground_root.join(topic))).expect(&format!(
"Couldn't canonicalize test path {}",
playground_root.join(topic).display()
));
let root = dunce::canonicalize(playground_root).expect(&format!(
"Couldn't canonicalize tests root path {}",
playground_root.display()
));
let dirs = Dirs {
root,
test,
fixtures,
};
block(dirs, &mut playground);
}
pub fn mkdir(&mut self, directory: &str) -> &mut Self {
self.cwd.push(directory);
std::fs::create_dir_all(&self.cwd).expect("can not create directory");
self.back_to_playground();
self
}
pub fn with_files(&mut self, files: Vec<Stub>) -> &mut Self {
let endl = line_ending();
files
.iter()
.map(|f| {
let mut path = PathBuf::from(&self.cwd);
let (file_name, contents) = match *f {
Stub::EmptyFile(name) => (name, "fake data".to_string()),
Stub::FileWithContent(name, content) => (name, content.to_string()),
Stub::FileWithContentToBeTrimmed(name, content) => (
name,
content
.lines()
.skip(1)
.map(|line| line.trim())
.collect::<Vec<&str>>()
.join(&endl),
),
};
path.push(file_name);
std::fs::write(PathBuf::from(path), contents.as_bytes())
.expect("can not create file");
})
.for_each(drop);
self.back_to_playground();
self
}
pub fn within(&mut self, directory: &str) -> &mut Self {
self.cwd.push(directory);
std::fs::create_dir(&self.cwd).expect("can not create directory");
self
}
pub fn glob_vec(pattern: &str) -> Vec<PathBuf> {
let glob = glob(pattern);
match glob {
Ok(paths) => paths
.map(|path| {
if let Ok(path) = path {
path
} else {
unreachable!()
}
})
.collect(),
Err(_) => panic!("Invalid pattern."),
}
}
}

View file

@ -26,7 +26,6 @@ pub use crate::data::dict::TaggedListBuilder;
pub use crate::data::primitive;
pub use crate::data::value;
pub use crate::env::host::BasicHost;
pub use crate::utils::{AbsoluteFile, AbsolutePath, RelativePath};
pub use nu_parser::TokenTreeBuilder;
pub use nu_value_ext::ValueExt;
pub use num_traits::cast::ToPrimitive;

View file

@ -1,123 +1,7 @@
use nu_errors::ShellError;
use nu_protocol::{UntaggedValue, Value};
use nu_source::{b, DebugDocBuilder, PrettyDebug};
use std::ops::Div;
use std::path::{Component, Path, PathBuf};
pub struct AbsoluteFile {
inner: PathBuf,
}
impl AbsoluteFile {
pub fn new(path: impl AsRef<Path>) -> AbsoluteFile {
let path = path.as_ref();
if !path.is_absolute() {
panic!(
"AbsoluteFile::new must take an absolute path :: {}",
path.display()
)
} else if path.is_dir() {
// At the moment, this is not an invariant, but rather a way to catch bugs
// in tests.
panic!(
"AbsoluteFile::new must not take a directory :: {}",
path.display()
)
} else {
AbsoluteFile {
inner: path.to_path_buf(),
}
}
}
pub fn dir(&self) -> AbsolutePath {
AbsolutePath::new(self.inner.parent().unwrap())
}
}
impl From<AbsoluteFile> for PathBuf {
fn from(file: AbsoluteFile) -> Self {
file.inner
}
}
pub struct AbsolutePath {
inner: PathBuf,
}
impl PrettyDebug for AbsolutePath {
fn pretty(&self) -> DebugDocBuilder {
b::primitive(self.inner.display())
}
}
impl AbsolutePath {
pub fn new(path: impl AsRef<Path>) -> AbsolutePath {
let path = path.as_ref();
if path.is_absolute() {
AbsolutePath {
inner: path.to_path_buf(),
}
} else {
panic!("AbsolutePath::new must take an absolute path")
}
}
}
impl Div<&str> for &AbsolutePath {
type Output = AbsolutePath;
fn div(self, rhs: &str) -> Self::Output {
let parts = rhs.split('/');
let mut result = self.inner.clone();
for part in parts {
result = result.join(part);
}
AbsolutePath::new(result)
}
}
impl AsRef<Path> for AbsolutePath {
fn as_ref(&self) -> &Path {
self.inner.as_path()
}
}
pub struct RelativePath {
inner: PathBuf,
}
impl RelativePath {
pub fn new(path: impl Into<PathBuf>) -> RelativePath {
let path = path.into();
if path.is_relative() {
RelativePath { inner: path }
} else {
panic!("RelativePath::new must take a relative path")
}
}
}
impl<T: AsRef<str>> Div<T> for &RelativePath {
type Output = RelativePath;
fn div(self, rhs: T) -> Self::Output {
let parts = rhs.as_ref().split('/');
let mut result = self.inner.clone();
for part in parts {
result = result.join(part);
}
RelativePath::new(result)
}
}
pub enum TaggedValueIter<'a> {
Empty,
List(indexmap::map::Iter<'a, String, Value>),

View file

@ -1,115 +0,0 @@
mod helpers;
use helpers as h;
use helpers::{Playground, Stub::*};
use std::path::PathBuf;
#[test]
fn has_default_configuration_file() {
let expected = "config.toml";
Playground::setup("config_test_1", |dirs, _| {
nu!(cwd: dirs.root(), "config");
assert_eq!(
dirs.config_path().join(expected),
nu::config_path().unwrap().join(expected)
);
})
}
#[test]
fn shows_path_of_configuration_file() {
let expected = "config.toml";
Playground::setup("config_test_2", |dirs, _| {
let actual = nu!(
cwd: dirs.test(),
"config --path | echo $it"
);
assert_eq!(PathBuf::from(actual), dirs.config_path().join(expected));
});
}
#[test]
fn use_different_configuration() {
Playground::setup("config_test_3", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"test_3.toml",
r#"
caballero_1 = "Andrés N. Robalino"
caballero_2 = "Jonathan Turner"
caballero_3 = "Yehuda katz"
"#,
)]);
let actual = nu!(
cwd: dirs.root(),
"config --get caballero_1 --load {}/test_3.toml | echo $it",
dirs.test()
);
assert_eq!(actual, "Andrés N. Robalino");
});
h::delete_file_at(nu::config_path().unwrap().join("test_3.toml"));
}
#[test]
fn sets_configuration_value() {
Playground::setup("config_test_4", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"test_4.toml",
r#"
caballero_1 = "Andrés N. Robalino"
caballero_2 = "Jonathan Turner"
caballero_3 = "Yehuda katz"
"#,
)]);
nu!(
cwd: dirs.test(),
"config --load test_4.toml --set [caballero_4 jonas]"
);
let actual = nu!(
cwd: dirs.root(),
r#"open "{}/test_4.toml" | get caballero_4 | echo $it"#,
dirs.config_path()
);
assert_eq!(actual, "jonas");
});
h::delete_file_at(nu::config_path().unwrap().join("test_4.toml"));
}
// #[test]
// fn removes_configuration_value() {
// Playground::setup("config_test_5", |dirs, sandbox| {
// sandbox.with_files(vec![FileWithContent(
// "test_5.toml",
// r#"
// caballeros = [1, 1, 1]
// podershell = [1, 1, 1]
// "#,
// )]);
// nu!(
// cwd: dirs.test(),
// "config --load test_5.toml --remove podershell"
// );
// let actual = nu_error!(
// cwd: dirs.root(),
// r#"open "{}/test_5.toml" | get podershell | echo $it"#,
// dirs.config_path()
// );
// assert!(actual.contains("Unknown column"));
// });
// h::delete_file_at(nu::config_path().unwrap().join("test_5.toml"));
// }

17
tests/commands/append.rs Normal file
View file

@ -0,0 +1,17 @@
use test_support::{nu, pipeline};
#[test]
fn adds_a_row_to_the_end() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open fileA.txt
| lines
| append "testme"
| nth 3
| echo $it
"#
));
assert_eq!(actual, "testme");
}

View file

@ -1,7 +1,7 @@
mod helpers;
use helpers::{Playground, Stub::*};
use std::path::PathBuf;
use test_support::fs::{Stub::EmptyFile, Stub::FileWithContent};
use test_support::playground::Playground;
use test_support::{nu, nu_error};
#[test]
fn filesystem_change_from_current_directory_using_relative_path() {

52
tests/commands/compact.rs Normal file
View file

@ -0,0 +1,52 @@
use test_support::fs::Stub::FileWithContentToBeTrimmed;
use test_support::playground::Playground;
use 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
| count
| echo $it
"#
));
assert_eq!(actual, "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
| count
| echo $it
"#
));
assert_eq!(actual, "4");
});
}

View file

@ -1,9 +1,7 @@
mod helpers;
use nu::AbsoluteFile;
use helpers::{files_exist_at, Playground, Stub::*};
use std::path::Path;
use test_support::fs::{files_exist_at, AbsoluteFile, Stub::EmptyFile};
use test_support::playground::Playground;
use test_support::{nu, nu_error};
#[test]
fn copies_a_file() {

36
tests/commands/default.rs Normal file
View file

@ -0,0 +1,36 @@
use test_support::fs::Stub::FileWithContentToBeTrimmed;
use test_support::playground::Playground;
use 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
| count
| echo $it
"#
));
assert_eq!(actual, "2");
});
}

16
tests/commands/edit.rs Normal file
View file

@ -0,0 +1,16 @@
use test_support::{nu, pipeline};
#[test]
fn creates_a_new_table_with_the_new_row_given() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open cargo_sample.toml
| edit dev-dependencies.pretty_assertions "7"
| get dev-dependencies.pretty_assertions
| echo $it
"#
));
assert_eq!(actual, "7");
}

View file

@ -1,9 +1,7 @@
mod helpers;
use helpers as h;
use helpers::{Playground, Stub::*};
use std::path::Path;
use test_support::fs::{files_exist_at, Stub::EmptyFile};
use test_support::playground::Playground;
use test_support::{nu, nu_error};
#[test]
fn knows_the_filesystems_entered() {
@ -53,7 +51,7 @@ fn knows_the_filesystems_entered() {
);
assert!(!red_pill_dir.exists());
assert!(h::files_exist_at(
assert!(files_exist_at(
vec![
Path::new("andres.nu"),
Path::new("jonathan.nu"),
@ -63,7 +61,7 @@ fn knows_the_filesystems_entered() {
));
assert!(!blue_pill_dir.exists());
assert!(h::files_exist_at(
assert!(files_exist_at(
vec![
Path::new("bash.nxt"),
Path::new("korn.nxt"),

70
tests/commands/first.rs Normal file
View file

@ -0,0 +1,70 @@
use test_support::fs::Stub::EmptyFile;
use test_support::playground::Playground;
use 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
| count
| echo $it
"#
));
assert_eq!(actual, "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
| count
| echo $it
"#
));
assert_eq!(actual, "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
| count
| echo $it
"#
));
assert_eq!(actual, "1");
})
}

16
tests/commands/format.rs Normal file
View file

@ -0,0 +1,16 @@
use 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}"
| echo $it
"#
));
assert_eq!(actual, "nu has license ISC");
}

View file

@ -1,10 +1,9 @@
mod helpers;
use helpers as h;
use helpers::{Playground, Stub::*};
use test_support::fs::Stub::FileWithContent;
use test_support::playground::Playground;
use test_support::{nu, nu_error, pipeline};
#[test]
fn get() {
fn fetches_a_row() {
Playground::setup("get_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
@ -14,7 +13,7 @@ fn get() {
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| get nu_party_venue
@ -41,7 +40,7 @@ fn fetches_by_index() {
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| get package.authors.2
@ -64,7 +63,7 @@ fn fetches_by_column_path() {
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| get package.name
@ -89,7 +88,7 @@ fn column_paths_are_either_double_quoted_or_regular_unquoted_words_separated_by_
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| get package."9999"
@ -123,7 +122,7 @@ fn fetches_more_than_one_column_path() {
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| get fortune_tellers.2.name fortune_tellers.0.name fortune_tellers.1.name
@ -148,7 +147,7 @@ fn errors_fetching_by_column_not_present() {
)]);
let actual = nu_error!(
cwd: dirs.test(), h::pipeline(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| get taco
@ -173,7 +172,7 @@ fn errors_fetching_by_column_using_a_number() {
)]);
let actual = nu_error!(
cwd: dirs.test(), h::pipeline(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| get spanish_lesson.9
@ -196,7 +195,7 @@ fn errors_fetching_by_index_out_of_bounds() {
)]);
let actual = nu_error!(
cwd: dirs.test(), h::pipeline(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| get spanish_lesson.sentence_words.3

View file

@ -0,0 +1,56 @@
use test_support::fs::Stub::FileWithContentToBeTrimmed;
use test_support::playground::Playground;
use test_support::{nu, nu_error, 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"
| count
| echo $it
"#
));
assert_eq!(actual, "2");
})
}
#[test]
fn errors_if_given_unknown_column_name_is_missing() {
Playground::setup("group_by_test_2", |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_error!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_caballeros.csv
| group-by ttype
"#
));
assert!(actual.contains("Unknown column"));
})
}

View file

@ -0,0 +1,32 @@
use test_support::fs::Stub::FileWithContentToBeTrimmed;
use test_support::playground::Playground;
use test_support::{nu, pipeline};
#[test]
fn summarizes() {
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
| echo $it
"#
));
assert_eq!(actual, "**************************************************");
// 50%
})
}

16
tests/commands/insert.rs Normal file
View file

@ -0,0 +1,16 @@
use test_support::{nu, pipeline};
#[test]
fn insert_plugin() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open cargo_sample.toml
| insert dev-dependencies.newdep "1"
| get dev-dependencies.newdep
| echo $it
"#
));
assert_eq!(actual, "1");
}

56
tests/commands/last.rs Normal file
View file

@ -0,0 +1,56 @@
use test_support::fs::Stub::EmptyFile;
use test_support::playground::Playground;
use 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 | trim | echo $it"
);
assert_eq!(actual, "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
| count
| echo $it
"#
));
assert_eq!(actual, "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
| count
| echo $it
"#
));
assert_eq!(actual, "1");
})
}

21
tests/commands/lines.rs Normal file
View file

@ -0,0 +1,21 @@
use test_support::{nu, pipeline};
#[test]
fn lines() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open cargo_sample.toml --raw
| lines
| skip-while $it != "[dependencies]"
| skip 1
| first 1
| split-column "="
| get Column1
| trim
| echo $it
"#
));
assert_eq!(actual, "rustyline");
}

View file

@ -1,10 +1,9 @@
mod helpers;
use helpers as h;
use helpers::{Playground, Stub::*};
use test_support::fs::Stub::EmptyFile;
use test_support::playground::Playground;
use test_support::{nu, pipeline};
#[test]
fn ls_lists_regular_files() {
fn lists_regular_files() {
Playground::setup("ls_test_1", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("yehuda.txt"),
@ -13,7 +12,7 @@ fn ls_lists_regular_files() {
]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
cwd: dirs.test(), pipeline(
r#"
ls
| count
@ -26,7 +25,7 @@ fn ls_lists_regular_files() {
}
#[test]
fn ls_lists_regular_files_using_asterisk_wildcard() {
fn lists_regular_files_using_asterisk_wildcard() {
Playground::setup("ls_test_2", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("los.txt"),
@ -36,7 +35,7 @@ fn ls_lists_regular_files_using_asterisk_wildcard() {
]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
cwd: dirs.test(), pipeline(
r#"
ls *.txt
| count
@ -49,7 +48,7 @@ fn ls_lists_regular_files_using_asterisk_wildcard() {
}
#[test]
fn ls_lists_regular_files_using_question_mark_wildcard() {
fn lists_regular_files_using_question_mark_wildcard() {
Playground::setup("ls_test_3", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("yehuda.10.txt"),
@ -59,7 +58,7 @@ fn ls_lists_regular_files_using_question_mark_wildcard() {
]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
cwd: dirs.test(), pipeline(
r#"
ls *.??.txt
| count

View file

@ -1,9 +1,7 @@
mod helpers;
use helpers as h;
use helpers::Playground;
use std::path::Path;
use test_support::fs::files_exist_at;
use test_support::nu;
use test_support::playground::Playground;
#[test]
fn creates_directory() {
@ -27,7 +25,7 @@ fn accepts_and_creates_directories() {
"mkdir dir_1 dir_2 dir_3"
);
assert!(h::files_exist_at(
assert!(files_exist_at(
vec![Path::new("dir_1"), Path::new("dir_2"), Path::new("dir_3")],
dirs.test()
));

30
tests/commands/mod.rs Normal file
View file

@ -0,0 +1,30 @@
mod append;
mod cd;
mod compact;
mod cp;
mod default;
mod edit;
mod enter;
mod first;
mod format;
mod get;
mod group_by;
mod histogram;
mod insert;
mod last;
mod lines;
mod ls;
mod mkdir;
mod mv;
mod open;
mod parse;
mod prepend;
mod range;
mod reverse;
mod rm;
mod save;
mod sort_by;
mod split_by;
mod split_column;
mod where_;
mod wrap;

View file

@ -1,7 +1,6 @@
mod helpers;
use helpers as h;
use helpers::{Playground, Stub::*};
use test_support::fs::{files_exist_at, Stub::EmptyFile};
use test_support::nu;
use test_support::playground::Playground;
#[test]
fn moves_a_file() {
@ -148,7 +147,7 @@ fn moves_using_path_with_wildcard() {
nu!(cwd: work_dir, "mv ../originals/*.ini ../expected");
assert!(h::files_exist_at(
assert!(files_exist_at(
vec!["yehuda.ini", "jonathan.ini", "sample.ini", "andres.ini",],
expected
));
@ -175,7 +174,7 @@ fn moves_using_a_glob() {
nu!(cwd: work_dir, "mv ../meals/* ../expected");
assert!(meal_dir.exists());
assert!(h::files_exist_at(
assert!(files_exist_at(
vec!["arepa.txt", "empanada.txt", "taquiza.txt",],
expected
));

39
tests/commands/nth.rs Normal file
View file

@ -0,0 +1,39 @@
#[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
| echo $it
"#
));
assert_eq!(actual, "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
| count
| echo $it
"#
));
assert_eq!(actual, "2");
});
}

View file

@ -1,10 +1,9 @@
mod helpers;
use helpers as h;
use helpers::{Playground, Stub::*};
use test_support::fs::Stub::FileWithContentToBeTrimmed;
use test_support::playground::Playground;
use test_support::{nu, nu_error, pipeline};
#[test]
fn recognizes_csv() {
fn parses_csv() {
Playground::setup("open_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"nu.zion.csv",
@ -17,7 +16,7 @@ fn recognizes_csv() {
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
cwd: dirs.test(), pipeline(
r#"
open nu.zion.csv
| where author == "Andres N. Robalino"
@ -56,7 +55,7 @@ fn recognizes_csv() {
//
#[test]
fn open_can_parse_bson_1() {
fn parses_bson() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"open sample.bson | get root | nth 0 | get b | echo $it"
@ -66,9 +65,9 @@ fn open_can_parse_bson_1() {
}
#[test]
fn open_can_parse_bson_2() {
fn parses_more_bson_complexity() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample.bson
| get root
@ -132,9 +131,9 @@ fn open_can_parse_bson_2() {
// ━━━┷━━━━━━
#[test]
fn open_can_parse_sqlite() {
fn parses_sqlite() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample.db
| get table_values
@ -147,7 +146,7 @@ fn open_can_parse_sqlite() {
}
#[test]
fn open_can_parse_toml() {
fn parses_toml() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"open cargo_sample.toml | get package.edition | echo $it"
@ -157,9 +156,9 @@ fn open_can_parse_toml() {
}
#[test]
fn open_can_parse_tsv() {
fn parses_tsv() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
cwd: "tests/fixtures/formats", pipeline(
r#"
open caco3_plastics.tsv
| first 1
@ -172,9 +171,9 @@ fn open_can_parse_tsv() {
}
#[test]
fn open_can_parse_json() {
fn parses_json() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sgml_description.json
| get glossary.GlossDiv.GlossList.GlossEntry.GlossSee
@ -186,7 +185,7 @@ fn open_can_parse_json() {
}
#[test]
fn open_can_parse_xml() {
fn parses_xml() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"open jonathan.xml | get rss.channel | get item | get link | echo $it"
@ -199,7 +198,7 @@ fn open_can_parse_xml() {
}
#[test]
fn open_can_parse_ini() {
fn parses_ini() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"open sample.ini | get SectionOne.integer | echo $it"
@ -209,7 +208,7 @@ fn open_can_parse_ini() {
}
#[test]
fn open_can_parse_utf16_ini() {
fn parses_utf16_ini() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"open utf16.ini | get '.ShellClassInfo' | get IconIndex | echo $it"

17
tests/commands/parse.rs Normal file
View file

@ -0,0 +1,17 @@
use test_support::{nu, pipeline};
#[test]
fn extracts_fields_from_the_given_the_pattern() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open fileA.txt
| parse "{Name}={Value}"
| nth 1
| get Value
| echo $it
"#
));
assert_eq!(actual, "StupidLongName");
}

17
tests/commands/prepend.rs Normal file
View file

@ -0,0 +1,17 @@
use test_support::{nu, pipeline};
#[test]
fn adds_a_row_to_the_beginning() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open fileA.txt
| lines
| prepend "testme"
| nth 0
| echo $it
"#
));
assert_eq!(actual, "testme");
}

47
tests/commands/range.rs Normal file
View file

@ -0,0 +1,47 @@
use test_support::fs::Stub::EmptyFile;
use test_support::playground::Playground;
use 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
| echo $it
"#
));
assert_eq!(actual, "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
| count
| echo $it
"#
));
assert_eq!(actual, "2");
});
}

11
tests/commands/reverse.rs Normal file
View file

@ -0,0 +1,11 @@
use 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 | trim | echo $it"
);
assert_eq!(actual, "utf16.ini");
}

View file

@ -1,10 +1,9 @@
mod helpers;
use helpers as h;
use helpers::{Playground, Stub::*};
use test_support::fs::{files_exist_at, Stub::EmptyFile};
use test_support::playground::Playground;
use test_support::{nu, nu_error};
#[test]
fn rm_removes_a_file() {
fn removes_a_file() {
Playground::setup("rm_test_1", |dirs, sandbox| {
sandbox.with_files(vec![EmptyFile("i_will_be_deleted.txt")]);
@ -20,7 +19,7 @@ fn rm_removes_a_file() {
}
#[test]
fn rm_removes_files_with_wildcard() {
fn removes_files_with_wildcard() {
Playground::setup("rm_test_2", |dirs, sandbox| {
sandbox
.within("src")
@ -44,7 +43,7 @@ fn rm_removes_files_with_wildcard() {
r#"rm "src/*/*/*.rs""#
);
assert!(!h::files_exist_at(
assert!(!files_exist_at(
vec![
"src/parser/parse/token_tree.rs",
"src/parser/hir/baseline_parse.rs",
@ -61,7 +60,7 @@ fn rm_removes_files_with_wildcard() {
}
#[test]
fn rm_removes_deeply_nested_directories_with_wildcard_and_recursive_flag() {
fn removes_deeply_nested_directories_with_wildcard_and_recursive_flag() {
Playground::setup("rm_test_3", |dirs, sandbox| {
sandbox
.within("src")
@ -85,7 +84,7 @@ fn rm_removes_deeply_nested_directories_with_wildcard_and_recursive_flag() {
"rm src/* --recursive"
);
assert!(!h::files_exist_at(
assert!(!files_exist_at(
vec!["src/parser/parse", "src/parser/hir"],
dirs.test()
));
@ -93,7 +92,7 @@ fn rm_removes_deeply_nested_directories_with_wildcard_and_recursive_flag() {
}
#[test]
fn rm_removes_directory_contents_without_recursive_flag_if_empty() {
fn removes_directory_contents_without_recursive_flag_if_empty() {
Playground::setup("rm_test_4", |dirs, _| {
nu!(
cwd: dirs.root(),
@ -105,7 +104,7 @@ fn rm_removes_directory_contents_without_recursive_flag_if_empty() {
}
#[test]
fn rm_removes_directory_contents_with_recursive_flag() {
fn removes_directory_contents_with_recursive_flag() {
Playground::setup("rm_test_5", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("yehuda.txt"),
@ -123,7 +122,7 @@ fn rm_removes_directory_contents_with_recursive_flag() {
}
#[test]
fn rm_errors_if_attempting_to_delete_a_directory_with_content_without_recursive_flag() {
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")]);
@ -138,7 +137,7 @@ fn rm_errors_if_attempting_to_delete_a_directory_with_content_without_recursive_
}
#[test]
fn rm_errors_if_attempting_to_delete_single_dot_as_argument() {
fn errors_if_attempting_to_delete_single_dot_as_argument() {
Playground::setup("rm_test_7", |dirs, _| {
let actual = nu_error!(
cwd: dirs.root(),
@ -150,7 +149,7 @@ fn rm_errors_if_attempting_to_delete_single_dot_as_argument() {
}
#[test]
fn rm_errors_if_attempting_to_delete_two_dot_as_argument() {
fn errors_if_attempting_to_delete_two_dot_as_argument() {
Playground::setup("rm_test_8", |dirs, _| {
let actual = nu_error!(
cwd: dirs.root(),

47
tests/commands/save.rs Normal file
View file

@ -0,0 +1,47 @@
use test_support::fs::{file_contents, Stub::FileWithContent};
use test_support::nu;
use 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, _| {
let expected_file = dirs.test().join("cargo_sample.csv");
nu!(
cwd: dirs.root(),
"open {}/cargo_sample.toml | get package | save save_test_2/cargo_sample.csv",
dirs.formats()
);
let actual = file_contents(expected_file);
assert!(actual.contains("[Table],A shell for the GitHub era,2018,ISC,nu,0.1.1"));
})
}

23
tests/commands/sort_by.rs Normal file
View file

@ -0,0 +1,23 @@
use test_support::{nu, pipeline};
#[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
| trim
| echo $it
"#
));
assert_eq!(actual, "description");
}

View file

@ -0,0 +1,55 @@
use test_support::fs::Stub::{EmptyFile, FileWithContentToBeTrimmed};
use test_support::playground::Playground;
use test_support::{nu, nu_error, 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"
| count
| echo $it
"#
));
assert_eq!(actual, "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_error!(
cwd: dirs.test(), pipeline(
r#"
ls
| get name
| split-by type
"#
));
assert!(actual.contains("Expected table from pipeline"));
})
}

View file

@ -0,0 +1,20 @@
use test_support::{nu, pipeline};
#[test]
fn by_column() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open cargo_sample.toml --raw
| lines
| skip 1
| first 1
| split-column "="
| get Column1
| trim
| echo $it
"#
));
assert_eq!(actual, "name");
}

View file

@ -1,11 +1,19 @@
mod helpers;
use helpers as h;
use test_support::{nu, pipeline};
#[test]
fn test_compare() {
fn filters_by_unit_size_comparison() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
cwd: "tests/fixtures/formats",
"ls | where size > 1kb | sort-by size | get name | first 1 | trim | echo $it"
);
assert_eq!(actual, "cargo_sample.toml");
}
#[test]
fn binary_operator_comparisons() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample.db
| where table_name == ints
@ -20,7 +28,7 @@ fn test_compare() {
assert_eq!(actual, "4253");
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample.db
| where table_name == ints
@ -35,7 +43,7 @@ fn test_compare() {
assert_eq!(actual, "4253");
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample.db
| where table_name == ints
@ -50,7 +58,7 @@ fn test_compare() {
assert_eq!(actual, "1");
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample.db
| where table_name == ints
@ -65,7 +73,7 @@ fn test_compare() {
assert_eq!(actual, "1");
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample.db
| where table_name == ints
@ -81,9 +89,9 @@ fn test_compare() {
}
#[test]
fn test_contains() {
fn contains_operator() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample.db
| where table_name == strings
@ -97,7 +105,7 @@ fn test_contains() {
assert_eq!(actual, "4");
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample.db
| where table_name == strings

63
tests/commands/wrap.rs Normal file
View file

@ -0,0 +1,63 @@
use test_support::fs::Stub::FileWithContentToBeTrimmed;
use test_support::playground::Playground;
use test_support::{nu, pipeline};
#[test]
fn wrap_rows_into_a_row() {
Playground::setup("embed_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.txt",
r#"
first_name,last_name
Andrés,Robalino
Jonathan,Turner
Yehuda,Katz
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_caballeros.txt
| from-csv
| wrap caballeros
| get caballeros
| nth 0
| get last_name
| echo $it
"#
));
assert_eq!(actual, "Robalino");
})
}
#[test]
fn wrap_rows_into_a_table() {
Playground::setup("embed_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.txt",
r#"
first_name,last_name
Andrés,Robalino
Jonathan,Turner
Yehuda,Katz
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_caballeros.txt
| from-csv
| get last_name
| wrap caballero
| nth 2
| get caballero
| echo $it
"#
));
assert_eq!(actual, "Katz");
})
}

View file

@ -1,564 +0,0 @@
mod helpers;
use helpers as h;
use helpers::{Playground, Stub::*};
#[test]
fn nth_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(), h::pipeline(
r#"
ls
| sort-by name
| nth 0
| get name
| echo $it
"#
));
assert_eq!(actual, "arepas.txt");
});
}
#[test]
fn nth_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(), h::pipeline(
r#"
ls
| get name
| nth 1 0
| count
| echo $it
"#
));
assert_eq!(actual, "2");
});
}
#[test]
fn default_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(), h::pipeline(
r#"
open los_tres_amigos.json
| get amigos
| default rusty_luck 1
| where rusty_luck == 1
| count
| echo $it
"#
));
assert_eq!(actual, "2");
});
}
#[test]
fn compact_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(), h::pipeline(
r#"
open los_tres_amigos.json
| get amigos
| compact rusty_luck
| count
| echo $it
"#
));
assert_eq!(actual, "3");
});
}
#[test]
fn compact_empty_rows_by_default() {
Playground::setup("compact_test_2", |dirs, _| {
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
echo "[1,2,3,14,null]"
| from-json
| compact
| count
| echo $it
"#
));
assert_eq!(actual, "4");
});
}
#[test]
fn group_by() {
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(), h::pipeline(
r#"
open los_tres_caballeros.csv
| group-by rusty_at
| get "10/11/2013"
| count
| echo $it
"#
));
assert_eq!(actual, "2");
})
}
#[test]
fn histogram() {
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(), h::pipeline(
r#"
open los_tres_caballeros.csv
| histogram rusty_at countries
| where rusty_at == "Ecuador"
| get countries
| echo $it
"#
));
assert_eq!(actual, "**************************************************");
// 50%
})
}
#[test]
fn group_by_errors_if_unknown_column_name() {
Playground::setup("group_by_test_2", |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_error!(
cwd: dirs.test(), h::pipeline(
r#"
open los_tres_caballeros.csv
| group-by ttype
"#
));
assert!(actual.contains("Unknown column"));
})
}
#[test]
fn range_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(), h::pipeline(
r#"
ls
| sort-by name
| range 0..0
| get name
| echo $it
"#
));
assert_eq!(actual, "notes.txt");
});
}
#[test]
fn range_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(), h::pipeline(
r#"
ls
| get name
| range 1..2
| count
| echo $it
"#
));
assert_eq!(actual, "2");
});
}
#[test]
fn split_by() {
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(), h::pipeline(
r#"
open los_tres_caballeros.csv
| group-by rusty_at
| split-by type
| get A."10/11/2013"
| count
| echo $it
"#
));
assert_eq!(actual, "2");
})
}
#[test]
fn split_by_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_error!(
cwd: dirs.test(), h::pipeline(
r#"
ls
| get name
| split-by type
"#
));
assert!(actual.contains("Expected table from pipeline"));
})
}
#[test]
fn first_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(), h::pipeline(
r#"
ls
| first 3
| count
| echo $it
"#
));
assert_eq!(actual, "3");
})
}
#[test]
fn first_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(), h::pipeline(
r#"
ls
| first 99
| count
| echo $it
"#
));
assert_eq!(actual, "4");
})
}
#[test]
fn first_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(), h::pipeline(
r#"
ls
| first
| count
| echo $it
"#
));
assert_eq!(actual, "1");
})
}
#[test]
fn last_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(), h::pipeline(
r#"
ls
| last 3
| count
| echo $it
"#
));
assert_eq!(actual, "3");
})
}
#[test]
fn last_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(), h::pipeline(
r#"
ls
| last
| count
| echo $it
"#
));
assert_eq!(actual, "1");
})
}
#[test]
fn get() {
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(), h::pipeline(
r#"
open sample.toml
| get nu_party_venue
| echo $it
"#
));
assert_eq!(actual, "zion");
})
}
#[test]
fn get_more_than_one_member() {
Playground::setup("get_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContent(
"sample.toml",
r#"
[[fortune_tellers]]
name = "Andrés N. Robalino"
arepas = 1
broken_builds = 0
[[fortune_tellers]]
name = "Jonathan Turner"
arepas = 1
broken_builds = 1
[[fortune_tellers]]
name = "Yehuda Katz"
arepas = 1
broken_builds = 1
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open sample.toml
| get fortune_tellers
| get arepas broken_builds
| where $it == 1
| count
| echo $it
"#
));
assert_eq!(actual, "5");
})
}
#[test]
fn lines() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
r#"
open cargo_sample.toml --raw
| lines
| skip-while $it != "[dependencies]"
| skip 1
| first 1
| split-column "="
| get Column1
| trim
| echo $it
"#
));
assert_eq!(actual, "rustyline");
}
#[test]
fn save_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 = h::file_contents(&subject_file);
assert!(actual.contains("0.1.1"));
})
}
#[test]
fn it_arg_works_with_many_inputs_to_external_command() {
Playground::setup("it_arg_works_with_many_inputs", |dirs, sandbox| {
sandbox.with_files(vec![
FileWithContent("file1", "text"),
FileWithContent("file2", " and more text"),
]);
let (stdout, stderr) = nu_combined!(
cwd: dirs.test(), h::pipeline(
r#"
echo hello world
| split-row " "
| ^echo $it
"#
));
#[cfg(windows)]
assert_eq!("hello world", stdout);
#[cfg(not(windows))]
assert_eq!("helloworld", stdout);
assert!(!stderr.contains("No such file or directory"));
})
}
#[test]
fn save_can_write_out_csv() {
Playground::setup("save_test_2", |dirs, _| {
let expected_file = dirs.test().join("cargo_sample.csv");
nu!(
cwd: dirs.root(),
"open {}/cargo_sample.toml | get package | save save_test_2/cargo_sample.csv",
dirs.formats()
);
let actual = h::file_contents(expected_file);
assert!(actual.contains("[Table],A shell for the GitHub era,2018,ISC,nu,0.1.1"));
})
}

View file

@ -0,0 +1,18 @@
use test_support::{nu, pipeline};
#[test]
fn table_to_bson_and_back_into_table() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample.bson
| to-bson
| from-bson
| get root
| get 1.b
| echo $it
"#
));
assert_eq!(actual, "whel");
}

View file

@ -0,0 +1,184 @@
use test_support::fs::Stub::FileWithContentToBeTrimmed;
use test_support::playground::Playground;
use test_support::{nu, pipeline};
#[test]
fn table_to_csv_text_and_from_csv_text_back_into_table() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"open caco3_plastics.csv | to-csv | from-csv | first 1 | get origin | echo $it"
);
assert_eq!(actual, "SPAIN");
}
#[test]
fn table_to_csv_text() {
Playground::setup("filter_to_csv_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"csv_text_sample.txt",
r#"
importer,shipper,tariff_item,name,origin
Plasticos Rival,Reverte,2509000000,Calcium carbonate,Spain
Tigre Ecuador,OMYA Andina,3824909999,Calcium carbonate,Colombia
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open csv_text_sample.txt
| lines
| trim
| split-column "," a b c d origin
| last 1
| to-csv
| lines
| nth 1
| echo $it
"#
));
assert!(actual.contains("Tigre Ecuador,OMYA Andina,3824909999,Calcium carbonate,Colombia"));
})
}
#[test]
fn table_to_csv_text_skipping_headers_after_conversion() {
Playground::setup("filter_to_csv_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"csv_text_sample.txt",
r#"
importer,shipper,tariff_item,name,origin
Plasticos Rival,Reverte,2509000000,Calcium carbonate,Spain
Tigre Ecuador,OMYA Andina,3824909999,Calcium carbonate,Colombia
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open csv_text_sample.txt
| lines
| trim
| split-column "," a b c d origin
| last 1
| to-csv --headerless
| echo $it
"#
));
assert!(actual.contains("Tigre Ecuador,OMYA Andina,3824909999,Calcium carbonate,Colombia"));
})
}
#[test]
fn from_csv_text_to_table() {
Playground::setup("filter_from_csv_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.txt",
r#"
first_name,last_name,rusty_luck
Andrés,Robalino,1
Jonathan,Turner,1
Yehuda,Katz,1
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_caballeros.txt
| from-csv
| get rusty_luck
| count
| echo $it
"#
));
assert_eq!(actual, "3");
})
}
#[test]
fn from_csv_text_with_separator_to_table() {
Playground::setup("filter_from_csv_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.txt",
r#"
first_name;last_name;rusty_luck
Andrés;Robalino;1
Jonathan;Turner;1
Yehuda;Katz;1
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_caballeros.txt
| from-csv --separator ';'
| get rusty_luck
| count
| echo $it
"#
));
assert_eq!(actual, "3");
})
}
#[test]
fn from_csv_text_with_tab_separator_to_table() {
Playground::setup("filter_from_csv_test_3", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.txt",
r#"
first_name last_name rusty_luck
Andrés Robalino 1
Jonathan Turner 1
Yehuda Katz 1
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_caballeros.txt
| from-csv --separator '\t'
| get rusty_luck
| count
| echo $it
"#
));
assert_eq!(actual, "3");
})
}
#[test]
fn from_csv_text_skipping_headers_to_table() {
Playground::setup("filter_from_csv_test_4", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_amigos.txt",
r#"
Andrés,Robalino,1
Jonathan,Turner,1
Yehuda,Katz,1
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_amigos.txt
| from-csv --headerless
| get Column3
| count
| echo $it
"#
));
assert_eq!(actual, "3");
})
}

View file

@ -0,0 +1,103 @@
use test_support::fs::Stub::FileWithContentToBeTrimmed;
use test_support::playground::Playground;
use test_support::{nu, pipeline};
#[test]
fn table_to_json_text_and_from_json_text_back_into_table() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sgml_description.json
| to-json
| from-json
| get glossary.GlossDiv.GlossList.GlossEntry.GlossSee
| echo $it
"#
));
assert_eq!(actual, "markup");
}
#[test]
fn from_json_text_to_table() {
Playground::setup("filter_from_json_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"katz.txt",
r#"
{
"katz": [
{"name": "Yehuda", "rusty_luck": 1},
{"name": "Jonathan", "rusty_luck": 1},
{"name": "Andres", "rusty_luck": 1},
{"name":"GorbyPuff", "rusty_luck": 1}
]
}
"#,
)]);
let actual = nu!(
cwd: dirs.test(),
"open katz.txt | from-json | get katz | get rusty_luck | count | echo $it"
);
assert_eq!(actual, "4");
})
}
#[test]
fn from_json_text_recognizing_objects_independently_to_table() {
Playground::setup("filter_from_json_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"katz.txt",
r#"
{"name": "Yehuda", "rusty_luck": 1}
{"name": "Jonathan", "rusty_luck": 1}
{"name": "Andres", "rusty_luck": 1}
{"name":"GorbyPuff", "rusty_luck": 3}
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open katz.txt
| from-json --objects
| where name == "GorbyPuff"
| get rusty_luck
| echo $it
"#
));
assert_eq!(actual, "3");
})
}
#[test]
fn table_to_json_text() {
Playground::setup("filter_to_json_test", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"sample.txt",
r#"
JonAndrehudaTZ,3
GorbyPuff,100
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open sample.txt
| lines
| split-column "," name luck
| pick name
| to-json
| from-json
| nth 0
| get name
| echo $it
"#
));
assert_eq!(actual, "JonAndrehudaTZ");
})
}

View file

@ -0,0 +1,10 @@
mod bson;
mod csv;
mod json;
mod sqlite;
mod ssv;
mod toml;
mod tsv;
mod url;
mod xlsx;
mod yaml;

View file

@ -0,0 +1,19 @@
use test_support::{nu, pipeline};
#[test]
fn table_to_sqlite_and_back_into_table() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample.db
| to-sqlite
| from-sqlite
| get table_values
| nth 2
| get x
| echo $it
"#
));
assert_eq!(actual, "hello");
}

View file

@ -0,0 +1,98 @@
use test_support::fs::Stub::FileWithContentToBeTrimmed;
use test_support::playground::Playground;
use test_support::{nu, pipeline};
#[test]
fn from_ssv_text_to_table() {
Playground::setup("filter_from_ssv_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"oc_get_svc.txt",
r#"
NAME LABELS SELECTOR IP PORT(S)
docker-registry docker-registry=default docker-registry=default 172.30.78.158 5000/TCP
kubernetes component=apiserver,provider=kubernetes <none> 172.30.0.2 443/TCP
kubernetes-ro component=apiserver,provider=kubernetes <none> 172.30.0.1 80/TCP
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open oc_get_svc.txt
| from-ssv
| nth 0
| get IP
| echo $it
"#
));
assert_eq!(actual, "172.30.78.158");
})
}
#[test]
fn from_ssv_text_to_table_with_separator_specified() {
Playground::setup("filter_from_ssv_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"oc_get_svc.txt",
r#"
NAME LABELS SELECTOR IP PORT(S)
docker-registry docker-registry=default docker-registry=default 172.30.78.158 5000/TCP
kubernetes component=apiserver,provider=kubernetes <none> 172.30.0.2 443/TCP
kubernetes-ro component=apiserver,provider=kubernetes <none> 172.30.0.1 80/TCP
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open oc_get_svc.txt
| from-ssv --minimum-spaces 3
| nth 0
| get IP
| echo $it
"#
));
assert_eq!(actual, "172.30.78.158");
})
}
#[test]
fn from_ssv_text_treating_first_line_as_data_with_flag() {
Playground::setup("filter_from_ssv_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"oc_get_svc.txt",
r#"
docker-registry docker-registry=default docker-registry=default 172.30.78.158 5000/TCP
kubernetes component=apiserver,provider=kubernetes <none> 172.30.0.2 443/TCP
kubernetes-ro component=apiserver,provider=kubernetes <none> 172.30.0.1 80/TCP
"#,
)]);
let aligned_columns = nu!(
cwd: dirs.test(), pipeline(
r#"
open oc_get_svc.txt
| from-ssv --headerless --aligned-columns
| first
| get Column1
| echo $it
"#
));
let separator_based = nu!(
cwd: dirs.test(), pipeline(
r#"
open oc_get_svc.txt
| from-ssv --headerless
| first
| get Column1
| echo $it
"#
));
assert_eq!(aligned_columns, separator_based);
assert_eq!(separator_based, "docker-registry");
})
}

View file

@ -0,0 +1,17 @@
use test_support::{nu, pipeline};
#[test]
fn table_to_toml_text_and_from_toml_text_back_into_table() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open cargo_sample.toml
| to-toml
| from-toml
| get package.name
| echo $it
"#
));
assert_eq!(actual, "nu");
}

View file

@ -0,0 +1,136 @@
use test_support::fs::Stub::FileWithContentToBeTrimmed;
use test_support::playground::Playground;
use test_support::{nu, pipeline};
#[test]
fn table_to_tsv_text_and_from_tsv_text_back_into_table() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"open caco3_plastics.tsv | to-tsv | from-tsv | first 1 | get origin | echo $it"
);
assert_eq!(actual, "SPAIN");
}
#[test]
fn table_to_tsv_text_and_from_tsv_text_back_into_table_using_csv_separator() {
let actual = nu!(
cwd: "tests/fixtures/formats",
r"open caco3_plastics.tsv | to-tsv | from-csv --separator '\t' | first 1 | get origin | echo $it"
);
assert_eq!(actual, "SPAIN");
}
#[test]
fn table_to_tsv_text() {
Playground::setup("filter_to_tsv_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"tsv_text_sample.txt",
r#"
importer shipper tariff_item name origin
Plasticos Rival Reverte 2509000000 Calcium carbonate Spain
Tigre Ecuador OMYA Andina 3824909999 Calcium carbonate Colombia
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open tsv_text_sample.txt
| lines
| split-column "\t" a b c d origin
| last 1
| to-tsv
| lines
| nth 1
| echo $it
"#
));
assert!(actual.contains("Colombia"));
})
}
#[test]
fn table_to_tsv_text_skipping_headers_after_conversion() {
Playground::setup("filter_to_tsv_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"tsv_text_sample.txt",
r#"
importer shipper tariff_item name origin
Plasticos Rival Reverte 2509000000 Calcium carbonate Spain
Tigre Ecuador OMYA Andina 3824909999 Calcium carbonate Colombia
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open tsv_text_sample.txt
| lines
| split-column "\t" a b c d origin
| last 1
| to-tsv --headerless
| echo $it
"#
));
assert!(actual.contains("Colombia"));
})
}
#[test]
fn from_tsv_text_to_table() {
Playground::setup("filter_from_tsv_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_amigos.txt",
r#"
first Name Last Name rusty_luck
Andrés Robalino 1
Jonathan Turner 1
Yehuda Katz 1
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_amigos.txt
| from-tsv
| get rusty_luck
| count
| echo $it
"#
));
assert_eq!(actual, "3");
})
}
#[test]
fn from_tsv_text_skipping_headers_to_table() {
Playground::setup("filter_from_tsv_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_amigos.txt",
r#"
Andrés Robalino 1
Jonathan Turner 1
Yehuda Katz 1
"#,
)]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
open los_tres_amigos.txt
| from-tsv --headerless
| get Column3
| count
| echo $it
"#
));
assert_eq!(actual, "3");
})
}

View file

@ -0,0 +1,17 @@
use test_support::{nu, pipeline};
#[test]
fn can_encode_and_decode_urlencoding() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample.url
| to-url
| from-url
| get cheese
| echo $it
"#
));
assert_eq!(actual, "comté");
}

View file

@ -0,0 +1,17 @@
use test_support::{nu, pipeline};
#[test]
fn from_excel_file_to_table() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open sample_data.xlsx
| get SalesOrders
| nth 4
| get Column2
| echo $it
"#
));
assert_eq!(actual, "Gill");
}

View file

@ -0,0 +1,17 @@
use test_support::{nu, pipeline};
#[test]
fn table_to_yaml_text_and_from_yaml_text_back_into_table() {
let actual = nu!(
cwd: "tests/fixtures/formats", pipeline(
r#"
open appveyor.yml
| to-yaml
| from-yaml
| get environment.global.PROJECT_NAME
| echo $it
"#
));
assert_eq!(actual, "nushell");
}

View file

@ -1,42 +0,0 @@
mod helpers;
use helpers::Playground;
#[test]
fn external_command() {
let actual = nu!(
cwd: "tests/fixtures",
"echo 1"
);
assert!(actual.contains("1"));
}
#[test]
fn spawn_external_process_with_home_in_arguments() {
Playground::setup("echo_tilde", |dirs, _| {
let actual = nu!(
cwd: dirs.test(),
r#"
sh -c "echo ~"
"#
);
assert!(
!actual.contains("~"),
format!("'{}' should not contain ~", actual)
);
})
}
#[test]
fn spawn_external_process_with_tilde_in_arguments() {
let actual = nu!(
cwd: "tests/fixtures",
r#"
sh -c "echo 1~1"
"#
);
assert_eq!(actual, "1~1");
}

43
tests/filters.rs Normal file
View file

@ -0,0 +1,43 @@
// use test_support::{nu, pipeline};
// use test_support::playground::Playground;
// use test_support::fs::Stub::FileWithContentToBeTrimmed;
// #[test]
// fn can_sum() {
// let actual = nu!(
// cwd: "tests/fixtures/formats", h::pipeline(
// r#"
// open sgml_description.json
// | get glossary.GlossDiv.GlossList.GlossEntry.Sections
// | sum
// | echo $it
// "#
// ));
// assert_eq!(actual, "203")
// }
// #[test]
// fn can_average_numbers() {
// let actual = nu!(
// cwd: "tests/fixtures/formats", h::pipeline(
// r#"
// open sgml_description.json
// | get glossary.GlossDiv.GlossList.GlossEntry.Sections
// | average
// | echo $it
// "#
// ));
// assert_eq!(actual, "101.5000000000000")
// }
// #[test]
// fn can_average_bytes() {
// let actual = nu!(
// cwd: "tests/fixtures/formats",
// "ls | sort-by name | skip 1 | first 2 | get size | average | echo $it"
// );
// assert_eq!(actual, "1600.000000000000");
// }

View file

@ -1,811 +0,0 @@
mod helpers;
use helpers as h;
use helpers::{Playground, Stub::*};
#[test]
fn can_convert_table_to_csv_text_and_from_csv_text_back_into_table() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"open caco3_plastics.csv | to-csv | from-csv | first 1 | get origin | echo $it"
);
assert_eq!(actual, "SPAIN");
}
#[test]
fn converts_structured_table_to_csv_text() {
Playground::setup("filter_to_csv_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"csv_text_sample.txt",
r#"
importer,shipper,tariff_item,name,origin
Plasticos Rival,Reverte,2509000000,Calcium carbonate,Spain
Tigre Ecuador,OMYA Andina,3824909999,Calcium carbonate,Colombia
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open csv_text_sample.txt
| lines
| trim
| split-column "," a b c d origin
| last 1
| to-csv
| lines
| nth 1
| echo $it
"#
));
assert!(actual.contains("Tigre Ecuador,OMYA Andina,3824909999,Calcium carbonate,Colombia"));
})
}
#[test]
fn converts_structured_table_to_csv_text_skipping_headers_after_conversion() {
Playground::setup("filter_to_csv_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"csv_text_sample.txt",
r#"
importer,shipper,tariff_item,name,origin
Plasticos Rival,Reverte,2509000000,Calcium carbonate,Spain
Tigre Ecuador,OMYA Andina,3824909999,Calcium carbonate,Colombia
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open csv_text_sample.txt
| lines
| trim
| split-column "," a b c d origin
| last 1
| to-csv --headerless
| echo $it
"#
));
assert!(actual.contains("Tigre Ecuador,OMYA Andina,3824909999,Calcium carbonate,Colombia"));
})
}
#[test]
fn converts_from_csv_text_to_structured_table() {
Playground::setup("filter_from_csv_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.txt",
r#"
first_name,last_name,rusty_luck
Andrés,Robalino,1
Jonathan,Turner,1
Yehuda,Katz,1
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open los_tres_caballeros.txt
| from-csv
| get rusty_luck
| count
| echo $it
"#
));
assert_eq!(actual, "3");
})
}
#[test]
fn converts_from_csv_text_with_separator_to_structured_table() {
Playground::setup("filter_from_csv_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.txt",
r#"
first_name;last_name;rusty_luck
Andrés;Robalino;1
Jonathan;Turner;1
Yehuda;Katz;1
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open los_tres_caballeros.txt
| from-csv --separator ';'
| get rusty_luck
| count
| echo $it
"#
));
assert_eq!(actual, "3");
})
}
#[test]
fn converts_from_csv_text_with_tab_separator_to_structured_table() {
Playground::setup("filter_from_csv_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.txt",
r#"
first_name last_name rusty_luck
Andrés Robalino 1
Jonathan Turner 1
Yehuda Katz 1
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open los_tres_caballeros.txt
| from-csv --separator '\t'
| get rusty_luck
| count
| echo $it
"#
));
assert_eq!(actual, "3");
})
}
#[test]
fn converts_from_csv_text_skipping_headers_to_structured_table() {
Playground::setup("filter_from_csv_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_amigos.txt",
r#"
Andrés,Robalino,1
Jonathan,Turner,1
Yehuda,Katz,1
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open los_tres_amigos.txt
| from-csv --headerless
| get Column3
| count
| echo $it
"#
));
assert_eq!(actual, "3");
})
}
#[test]
fn can_convert_table_to_json_text_and_from_json_text_back_into_table() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
r#"
open sgml_description.json
| to-json
| from-json
| get glossary.GlossDiv.GlossList.GlossEntry.GlossSee
| echo $it
"#
));
assert_eq!(actual, "markup");
}
#[test]
fn converts_from_json_text_to_structured_table() {
Playground::setup("filter_from_json_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"katz.txt",
r#"
{
"katz": [
{"name": "Yehuda", "rusty_luck": 1},
{"name": "Jonathan", "rusty_luck": 1},
{"name": "Andres", "rusty_luck": 1},
{"name":"GorbyPuff", "rusty_luck": 1}
]
}
"#,
)]);
let actual = nu!(
cwd: dirs.test(),
"open katz.txt | from-json | get katz | get rusty_luck | count | echo $it"
);
assert_eq!(actual, "4");
})
}
#[test]
fn converts_from_json_text_recognizing_objects_independendtly_to_structured_table() {
Playground::setup("filter_from_json_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"katz.txt",
r#"
{"name": "Yehuda", "rusty_luck": 1}
{"name": "Jonathan", "rusty_luck": 1}
{"name": "Andres", "rusty_luck": 1}
{"name":"GorbyPuff", "rusty_luck": 3}
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open katz.txt
| from-json --objects
| where name == "GorbyPuff"
| get rusty_luck
| echo $it
"#
));
assert_eq!(actual, "3");
})
}
#[test]
fn converts_structured_table_to_json_text() {
Playground::setup("filter_to_json_test", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"sample.txt",
r#"
JonAndrehudaTZ,3
GorbyPuff,100
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open sample.txt
| lines
| split-column "," name luck
| pick name
| to-json
| from-json
| nth 0
| get name
| echo $it
"#
));
assert_eq!(actual, "JonAndrehudaTZ");
})
}
#[test]
fn can_convert_table_to_tsv_text_and_from_tsv_text_back_into_table() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"open caco3_plastics.tsv | to-tsv | from-tsv | first 1 | get origin | echo $it"
);
assert_eq!(actual, "SPAIN");
}
#[test]
fn can_convert_table_to_tsv_text_and_from_tsv_text_back_into_table_using_csv_separator() {
let actual = nu!(
cwd: "tests/fixtures/formats",
r"open caco3_plastics.tsv | to-tsv | from-csv --separator '\t' | first 1 | get origin | echo $it"
);
assert_eq!(actual, "SPAIN");
}
#[test]
fn converts_structured_table_to_tsv_text() {
Playground::setup("filter_to_tsv_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"tsv_text_sample.txt",
r#"
importer shipper tariff_item name origin
Plasticos Rival Reverte 2509000000 Calcium carbonate Spain
Tigre Ecuador OMYA Andina 3824909999 Calcium carbonate Colombia
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open tsv_text_sample.txt
| lines
| split-column "\t" a b c d origin
| last 1
| to-tsv
| lines
| nth 1
| echo $it
"#
));
assert!(actual.contains("Colombia"));
})
}
#[test]
fn converts_structured_table_to_tsv_text_skipping_headers_after_conversion() {
Playground::setup("filter_to_tsv_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"tsv_text_sample.txt",
r#"
importer shipper tariff_item name origin
Plasticos Rival Reverte 2509000000 Calcium carbonate Spain
Tigre Ecuador OMYA Andina 3824909999 Calcium carbonate Colombia
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open tsv_text_sample.txt
| lines
| split-column "\t" a b c d origin
| last 1
| to-tsv --headerless
| echo $it
"#
));
assert!(actual.contains("Colombia"));
})
}
#[test]
fn converts_from_tsv_text_to_structured_table() {
Playground::setup("filter_from_tsv_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_amigos.txt",
r#"
first Name Last Name rusty_luck
Andrés Robalino 1
Jonathan Turner 1
Yehuda Katz 1
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open los_tres_amigos.txt
| from-tsv
| get rusty_luck
| count
| echo $it
"#
));
assert_eq!(actual, "3");
})
}
#[test]
fn converts_from_tsv_text_skipping_headers_to_structured_table() {
Playground::setup("filter_from_tsv_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_amigos.txt",
r#"
Andrés Robalino 1
Jonathan Turner 1
Yehuda Katz 1
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open los_tres_amigos.txt
| from-tsv --headerless
| get Column3
| count
| echo $it
"#
));
assert_eq!(actual, "3");
})
}
#[test]
fn converts_from_ssv_text_to_structured_table() {
Playground::setup("filter_from_ssv_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"oc_get_svc.txt",
r#"
NAME LABELS SELECTOR IP PORT(S)
docker-registry docker-registry=default docker-registry=default 172.30.78.158 5000/TCP
kubernetes component=apiserver,provider=kubernetes <none> 172.30.0.2 443/TCP
kubernetes-ro component=apiserver,provider=kubernetes <none> 172.30.0.1 80/TCP
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open oc_get_svc.txt
| from-ssv
| nth 0
| get IP
| echo $it
"#
));
assert_eq!(actual, "172.30.78.158");
})
}
#[test]
fn converts_from_ssv_text_to_structured_table_with_separator_specified() {
Playground::setup("filter_from_ssv_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"oc_get_svc.txt",
r#"
NAME LABELS SELECTOR IP PORT(S)
docker-registry docker-registry=default docker-registry=default 172.30.78.158 5000/TCP
kubernetes component=apiserver,provider=kubernetes <none> 172.30.0.2 443/TCP
kubernetes-ro component=apiserver,provider=kubernetes <none> 172.30.0.1 80/TCP
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open oc_get_svc.txt
| from-ssv --minimum-spaces 3
| nth 0
| get IP
| echo $it
"#
));
assert_eq!(actual, "172.30.78.158");
})
}
#[test]
fn converts_from_ssv_text_treating_first_line_as_data_with_flag() {
Playground::setup("filter_from_ssv_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"oc_get_svc.txt",
r#"
docker-registry docker-registry=default docker-registry=default 172.30.78.158 5000/TCP
kubernetes component=apiserver,provider=kubernetes <none> 172.30.0.2 443/TCP
kubernetes-ro component=apiserver,provider=kubernetes <none> 172.30.0.1 80/TCP
"#,
)]);
let aligned_columns = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open oc_get_svc.txt
| from-ssv --headerless --aligned-columns
| first
| get Column1
| echo $it
"#
));
let separator_based = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open oc_get_svc.txt
| from-ssv --headerless
| first
| get Column1
| echo $it
"#
));
assert_eq!(aligned_columns, separator_based);
assert_eq!(separator_based, "docker-registry");
})
}
#[test]
fn can_convert_table_to_bson_and_back_into_table() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
r#"
open sample.bson
| to-bson
| from-bson
| get root
| get 1.b
| echo $it
"#
));
assert_eq!(actual, "whel");
}
#[test]
fn can_read_excel_file() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
r#"
open sample_data.xlsx
| get SalesOrders
| nth 4
| get Column2
| echo $it
"#
));
assert_eq!(actual, "Gill");
}
#[test]
fn can_convert_table_to_sqlite_and_back_into_table() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
r#"
open sample.db
| to-sqlite
| from-sqlite
| get table_values
| nth 2
| get x
| echo $it
"#
));
assert_eq!(actual, "hello");
}
#[test]
fn can_convert_table_to_toml_text_and_from_toml_text_back_into_table() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
r#"
open cargo_sample.toml
| to-toml
| from-toml
| get package.name
| echo $it
"#
));
assert_eq!(actual, "nu");
}
#[test]
fn can_convert_table_to_yaml_text_and_from_yaml_text_back_into_table() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
r#"
open appveyor.yml
| to-yaml
| from-yaml
| get environment.global.PROJECT_NAME
| echo $it
"#
));
assert_eq!(actual, "nushell");
}
#[test]
fn can_encode_and_decode_urlencoding() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
r#"
open sample.url
| to-url
| from-url
| get cheese
| echo $it
"#
));
assert_eq!(actual, "comté");
}
#[test]
fn can_sort_by_column() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
r#"
open cargo_sample.toml --raw
| lines
| skip 1
| first 4
| split-column "="
| sort-by Column1
| skip 1
| first 1
| get Column1
| trim
| echo $it
"#
));
assert_eq!(actual, "description");
}
#[test]
fn can_split_by_column() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
r#"
open cargo_sample.toml --raw
| lines
| skip 1
| first 1
| split-column "="
| get Column1
| trim
| echo $it
"#
));
assert_eq!(actual, "name");
}
// #[test]
// fn can_sum() {
// let actual = nu!(
// cwd: "tests/fixtures/formats", h::pipeline(
// r#"
// open sgml_description.json
// | get glossary.GlossDiv.GlossList.GlossEntry.Sections
// | sum
// | echo $it
// "#
// ));
// assert_eq!(actual, "203")
// }
// #[test]
// fn can_average_numbers() {
// let actual = nu!(
// cwd: "tests/fixtures/formats", h::pipeline(
// r#"
// open sgml_description.json
// | get glossary.GlossDiv.GlossList.GlossEntry.Sections
// | average
// | echo $it
// "#
// ));
// assert_eq!(actual, "101.5000000000000")
// }
// #[test]
// fn can_average_bytes() {
// let actual = nu!(
// cwd: "tests/fixtures/formats",
// "ls | sort-by name | skip 1 | first 2 | get size | average | echo $it"
// );
// assert_eq!(actual, "1600.000000000000");
// }
#[test]
fn can_filter_by_unit_size_comparison() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"ls | where size > 1kb | sort-by size | get name | first 1 | trim | echo $it"
);
assert_eq!(actual, "cargo_sample.toml");
}
#[test]
fn can_get_last() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"ls | sort-by name | last 1 | get name | trim | echo $it"
);
assert_eq!(actual, "utf16.ini");
}
#[test]
fn can_get_reverse_first() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"ls | sort-by name | reverse | first 1 | get name | trim | echo $it"
);
assert_eq!(actual, "utf16.ini");
}
#[test]
fn wrap_rows_into_a_row() {
Playground::setup("embed_test_1", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.txt",
r#"
first_name,last_name
Andrés,Robalino
Jonathan,Turner
Yehuda,Katz
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open los_tres_caballeros.txt
| from-csv
| wrap caballeros
| get caballeros
| nth 0
| get last_name
| echo $it
"#
));
assert_eq!(actual, "Robalino");
})
}
#[test]
fn wrap_rows_into_a_table() {
Playground::setup("embed_test_2", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.txt",
r#"
first_name,last_name
Andrés,Robalino
Jonathan,Turner
Yehuda,Katz
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open los_tres_caballeros.txt
| from-csv
| get last_name
| wrap caballero
| nth 2
| get caballero
| echo $it
"#
));
assert_eq!(actual, "Katz");
})
}
#[test]
fn get() {
Playground::setup("get_test", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.txt",
r#"
first_name,last_name
Andrés,Robalino
Jonathan,Turner
Yehuda,Katz
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open los_tres_caballeros.txt
| from-csv
| nth 1
| get last_name
| echo $it
"#
));
assert_eq!(actual, "Turner");
})
}

View file

@ -1,450 +0,0 @@
#![allow(dead_code)]
use glob::glob;
pub use std::path::Path;
pub use std::path::PathBuf;
use app_dirs::{get_app_root, AppDataType};
use getset::Getters;
use nu_source::PrettyDebug;
use std::io::Read;
use tempfile::{tempdir, TempDir};
pub trait DisplayPath {
fn display_path(&self) -> String;
}
impl DisplayPath for PathBuf {
fn display_path(&self) -> String {
self.display().to_string()
}
}
impl DisplayPath for str {
fn display_path(&self) -> String {
self.to_string()
}
}
impl DisplayPath for &str {
fn display_path(&self) -> String {
self.to_string()
}
}
impl DisplayPath for String {
fn display_path(&self) -> String {
self.clone()
}
}
impl DisplayPath for &String {
fn display_path(&self) -> String {
self.to_string()
}
}
impl DisplayPath for nu::AbsolutePath {
fn display_path(&self) -> String {
self.display()
}
}
#[macro_export]
macro_rules! nu {
(cwd: $cwd:expr, $path:expr, $($part:expr),*) => {{
use $crate::helpers::DisplayPath;
let path = format!($path, $(
$part.display_path()
),*);
nu!($cwd, &path)
}};
(cwd: $cwd:expr, $path:expr) => {{
nu!($cwd, $path)
}};
($cwd:expr, $path:expr) => {{
pub use std::error::Error;
pub use std::io::prelude::*;
pub use std::process::{Command, Stdio};
let commands = &*format!(
"
cd {}
{}
exit",
$crate::helpers::in_directory($cwd),
$crate::helpers::DisplayPath::display_path(&$path)
);
let mut process = match Command::new(helpers::executable_path())
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
{
Ok(child) => child,
Err(why) => panic!("Can't run test {}", why.description()),
};
let stdin = process.stdin.as_mut().expect("couldn't open stdin");
stdin
.write_all(commands.as_bytes())
.expect("couldn't write to stdin");
let output = process
.wait_with_output()
.expect("couldn't read from stdout");
let out = String::from_utf8_lossy(&output.stdout);
let out = out.replace("\r\n", "");
let out = out.replace("\n", "");
out
}};
}
#[macro_export]
macro_rules! nu_error {
(cwd: $cwd:expr, $path:expr, $($part:expr),*) => {{
use $crate::helpers::DisplayPath;
let path = format!($path, $(
$part.display_path()
),*);
nu_error!($cwd, &path)
}};
(cwd: $cwd:expr, $path:expr) => {{
nu_error!($cwd, $path)
}};
($cwd:expr, $path:expr) => {{
pub use std::error::Error;
pub use std::io::prelude::*;
pub use std::process::{Command, Stdio};
let commands = &*format!(
"
cd {}
{}
exit",
$crate::helpers::in_directory($cwd),
$crate::helpers::DisplayPath::display_path(&$path)
);
let mut process = Command::new(helpers::executable_path())
.stdin(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("couldn't run test");
let stdin = process.stdin.as_mut().expect("couldn't open stdin");
stdin
.write_all(commands.as_bytes())
.expect("couldn't write to stdin");
let output = process
.wait_with_output()
.expect("couldn't read from stderr");
let out = String::from_utf8_lossy(&output.stderr);
out.into_owned()
}};
}
#[macro_export]
macro_rules! nu_combined {
(cwd: $cwd:expr, $path:expr, $($part:expr),*) => {{
use $crate::helpers::DisplayPath;
let path = format!($path, $(
$part.display_path()
),*);
nu_combined!($cwd, &path)
}};
(cwd: $cwd:expr, $path:expr) => {{
nu_combined!($cwd, $path)
}};
($cwd:expr, $path:expr) => {{
pub use std::error::Error;
pub use std::io::prelude::*;
pub use std::process::{Command, Stdio};
let commands = &*format!(
"
cd {}
{}
exit",
$crate::helpers::in_directory($cwd),
$crate::helpers::DisplayPath::display_path(&$path)
);
let mut process = Command::new(helpers::executable_path())
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("couldn't run test");
let stdin = process.stdin.as_mut().expect("couldn't open stdin");
stdin
.write_all(commands.as_bytes())
.expect("couldn't write to stdin");
let output = process
.wait_with_output()
.expect("couldn't read from stdout/stderr");
let err = String::from_utf8_lossy(&output.stderr).into_owned();
let out = String::from_utf8_lossy(&output.stdout).into_owned();
let out = out.replace("\r\n", "");
let out = out.replace("\n", "");
(out, err)
}};
}
pub enum Stub<'a> {
FileWithContent(&'a str, &'a str),
FileWithContentToBeTrimmed(&'a str, &'a str),
EmptyFile(&'a str),
}
pub struct Playground {
root: TempDir,
tests: String,
cwd: PathBuf,
}
#[derive(Getters)]
#[get = "pub"]
pub struct Dirs {
pub root: PathBuf,
pub test: PathBuf,
pub fixtures: PathBuf,
}
impl Dirs {
pub fn formats(&self) -> PathBuf {
PathBuf::from(self.fixtures.join("formats"))
}
pub fn config_path(&self) -> PathBuf {
get_app_root(AppDataType::UserConfig, &nu::APP_INFO).unwrap()
}
}
impl Playground {
pub fn root(&self) -> &Path {
self.root.path()
}
pub fn back_to_playground(&mut self) -> &mut Self {
self.cwd = PathBuf::from(self.root()).join(self.tests.clone());
self
}
pub fn setup(topic: &str, block: impl FnOnce(Dirs, &mut Playground)) {
let root = tempdir().expect("Couldn't create a tempdir");
let nuplay_dir = root.path().join(topic);
if PathBuf::from(&nuplay_dir).exists() {
std::fs::remove_dir_all(PathBuf::from(&nuplay_dir)).expect("can not remove directory");
}
std::fs::create_dir(PathBuf::from(&nuplay_dir)).expect("can not create directory");
let mut playground = Playground {
root: root,
tests: topic.to_string(),
cwd: nuplay_dir,
};
let project_root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let playground_root = playground.root.path();
let fixtures = project_root.join(file!());
let fixtures = fixtures
.parent()
.expect("Couldn't find the fixtures directory")
.parent()
.expect("Couldn't find the fixtures directory")
.join("fixtures");
let fixtures = dunce::canonicalize(fixtures.clone()).expect(&format!(
"Couldn't canonicalize fixtures path {}",
fixtures.display()
));
let test =
dunce::canonicalize(PathBuf::from(playground_root.join(topic))).expect(&format!(
"Couldn't canonicalize test path {}",
playground_root.join(topic).display()
));
let root = dunce::canonicalize(playground_root).expect(&format!(
"Couldn't canonicalize tests root path {}",
playground_root.display()
));
let dirs = Dirs {
root,
test,
fixtures,
};
block(dirs, &mut playground);
}
pub fn mkdir(&mut self, directory: &str) -> &mut Self {
self.cwd.push(directory);
std::fs::create_dir_all(&self.cwd).expect("can not create directory");
self.back_to_playground();
self
}
pub fn with_files(&mut self, files: Vec<Stub>) -> &mut Self {
let endl = line_ending();
files
.iter()
.map(|f| {
let mut path = PathBuf::from(&self.cwd);
let (file_name, contents) = match *f {
Stub::EmptyFile(name) => (name, "fake data".to_string()),
Stub::FileWithContent(name, content) => (name, content.to_string()),
Stub::FileWithContentToBeTrimmed(name, content) => (
name,
content
.lines()
.skip(1)
.map(|line| line.trim())
.collect::<Vec<&str>>()
.join(&endl),
),
};
path.push(file_name);
std::fs::write(PathBuf::from(path), contents.as_bytes())
.expect("can not create file");
})
.for_each(drop);
self.back_to_playground();
self
}
pub fn within(&mut self, directory: &str) -> &mut Self {
self.cwd.push(directory);
std::fs::create_dir(&self.cwd).expect("can not create directory");
self
}
pub fn glob_vec(pattern: &str) -> Vec<PathBuf> {
let glob = glob(pattern);
match glob {
Ok(paths) => paths
.map(|path| {
if let Ok(path) = path {
path
} else {
unreachable!()
}
})
.collect(),
Err(_) => panic!("Invalid pattern."),
}
}
}
pub fn file_contents(full_path: impl AsRef<Path>) -> String {
let mut file = std::fs::File::open(full_path.as_ref()).expect("can not open file");
let mut contents = String::new();
file.read_to_string(&mut contents)
.expect("can not read file");
contents
}
pub fn file_contents_binary(full_path: impl AsRef<Path>) -> Vec<u8> {
let mut file = std::fs::File::open(full_path.as_ref()).expect("can not open file");
let mut contents = Vec::new();
file.read_to_end(&mut contents).expect("can not read file");
contents
}
pub fn line_ending() -> String {
#[cfg(windows)]
{
String::from("\r\n")
}
#[cfg(not(windows))]
{
String::from("\n")
}
}
pub fn delete_file_at(full_path: impl AsRef<Path>) {
let full_path = full_path.as_ref();
if full_path.exists() {
std::fs::remove_file(full_path).expect("can not delete file");
}
}
pub fn create_file_at(full_path: impl AsRef<Path>) -> Result<(), std::io::Error> {
let full_path = full_path.as_ref();
if let Some(parent) = full_path.parent() {
panic!(format!("{:?} exists", parent.display()));
}
std::fs::write(full_path, "fake data".as_bytes())
}
pub fn copy_file_to(source: &str, destination: &str) {
std::fs::copy(source, destination).expect("can not copy file");
}
pub fn files_exist_at(files: Vec<impl AsRef<Path>>, path: impl AsRef<Path>) -> bool {
files.iter().all(|f| {
let mut loc = PathBuf::from(path.as_ref());
loc.push(f);
loc.exists()
})
}
pub fn delete_directory_at(full_path: &str) {
std::fs::remove_dir_all(PathBuf::from(full_path)).expect("can not remove directory");
}
pub fn executable_path() -> PathBuf {
let mut buf = PathBuf::new();
buf.push("target");
buf.push("debug");
buf.push("nu");
buf
}
pub fn in_directory(str: impl AsRef<Path>) -> String {
str.as_ref().display().to_string()
}
pub fn pipeline(commands: &str) -> String {
commands
.lines()
.skip(1)
.map(|line| line.trim())
.collect::<Vec<&str>>()
.join(" ")
.trim_end()
.to_string()
}

6
tests/main.rs Normal file
View file

@ -0,0 +1,6 @@
extern crate test_support;
mod commands;
mod converting_formats;
mod plugins;
mod shell;

View file

@ -1,6 +1,6 @@
mod helpers;
use helpers::{Playground, Stub::*};
use test_support::fs::Stub::FileWithContent;
use test_support::playground::Playground;
use test_support::{nu, nu_error};
#[test]
fn can_only_apply_one() {

View file

@ -1,7 +1,6 @@
mod helpers;
use h::{Playground, Stub::*};
use helpers as h;
use test_support::fs::Stub::FileWithContent;
use test_support::playground::Playground;
use test_support::{nu, nu_error, pipeline};
#[test]
fn can_only_apply_one() {
@ -77,7 +76,7 @@ fn upcases() {
#[test]
fn converts_to_int() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
cwd: "tests/fixtures/formats", pipeline(
r#"
open caco3_plastics.csv
| first 1
@ -103,7 +102,7 @@ fn replaces() {
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| str package.name --replace wykittenshell
@ -128,7 +127,7 @@ fn find_and_replaces() {
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| str fortune.teller.phone --find-replace [KATZ "5289"]
@ -153,7 +152,7 @@ fn find_and_replaces_without_passing_field() {
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
cwd: dirs.test(), pipeline(
r#"
open sample.toml
| get fortune.teller.phone

2
tests/plugins/mod.rs Normal file
View file

@ -0,0 +1,2 @@
mod core_inc;
mod core_str;

32
tests/shell/mod.rs Normal file
View file

@ -0,0 +1,32 @@
mod pipeline {
use test_support::fs::Stub::FileWithContent;
use test_support::playground::Playground;
use test_support::{nu_combined, pipeline};
#[test]
fn it_arg_works_with_many_inputs_to_external_command() {
Playground::setup("it_arg_works_with_many_inputs", |dirs, sandbox| {
sandbox.with_files(vec![
FileWithContent("file1", "text"),
FileWithContent("file2", " and more text"),
]);
let (stdout, stderr) = nu_combined!(
cwd: dirs.test(), pipeline(
r#"
echo hello world
| split-row " "
| ^echo $it
"#
));
#[cfg(windows)]
assert_eq!("hello world", stdout);
#[cfg(not(windows))]
assert_eq!("helloworld", stdout);
assert!(!stderr.contains("No such file or directory"));
})
}
}

View file

@ -1,135 +0,0 @@
mod helpers;
use helpers as h;
#[test]
fn pipeline_helper() {
let actual = h::pipeline(
r#"
open los_tres_amigos.txt
| from-csv
| get rusty_luck
| str --to-int
| sum
| echo "$it"
"#,
);
assert_eq!(
actual,
r#"open los_tres_amigos.txt | from-csv | get rusty_luck | str --to-int | sum | echo "$it""#
);
}
#[test]
fn external_num() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"open sgml_description.json | get glossary.GlossDiv.GlossList.GlossEntry.Height | echo $it"
);
assert_eq!(actual, "10");
}
#[test]
fn external_has_correct_quotes() {
let actual = nu!(
cwd: ".",
r#"echo "hello world""#
);
assert_eq!(actual, r#"hello world"#);
}
#[test]
fn insert_plugin() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
r#"
open cargo_sample.toml
| insert dev-dependencies.newdep "1"
| get dev-dependencies.newdep
| echo $it
"#
));
assert_eq!(actual, "1");
}
#[test]
fn parse_plugin() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
r#"
open fileA.txt
| parse "{Name}={Value}"
| nth 1
| get Value
| echo $it
"#
));
assert_eq!(actual, "StupidLongName");
}
#[test]
fn format_plugin() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
r#"
open cargo_sample.toml
| get package
| format "{name} has license {license}"
| echo $it
"#
));
assert_eq!(actual, "nu has license ISC");
}
#[test]
fn prepend_plugin() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
r#"
open fileA.txt
| lines
| prepend "testme"
| nth 0
| echo $it
"#
));
assert_eq!(actual, "testme");
}
#[test]
fn append_plugin() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
r#"
open fileA.txt
| lines
| append "testme"
| nth 3
| echo $it
"#
));
assert_eq!(actual, "testme");
}
#[test]
fn edit_plugin() {
let actual = nu!(
cwd: "tests/fixtures/formats", h::pipeline(
r#"
open cargo_sample.toml
| edit dev-dependencies.pretty_assertions "7"
| get dev-dependencies.pretty_assertions
| echo $it
"#
));
assert_eq!(actual, "7");
}