mirror of
https://github.com/nushell/nushell
synced 2024-12-25 12:33:17 +00:00
This commit is the continuing phase of extracting functionality to subcrates. We extract test helpers and begin to change Nu shell's test organization along with it.
This commit is contained in:
parent
4b9ef5a9d0
commit
4034129dba
64 changed files with 2184 additions and 2340 deletions
12
Cargo.lock
generated
12
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
16
crates/test-support/Cargo.toml
Normal file
16
crates/test-support/Cargo.toml
Normal 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"
|
228
crates/test-support/src/fs.rs
Normal file
228
crates/test-support/src/fs.rs
Normal 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()
|
||||
}
|
38
crates/test-support/src/lib.rs
Normal file
38
crates/test-support/src/lib.rs
Normal 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""#
|
||||
);
|
||||
}
|
||||
}
|
159
crates/test-support/src/macros.rs
Normal file
159
crates/test-support/src/macros.rs
Normal 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)
|
||||
}};
|
||||
}
|
152
crates/test-support/src/playground.rs
Normal file
152
crates/test-support/src/playground.rs
Normal 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."),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
116
src/utils.rs
116
src/utils.rs
|
@ -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>),
|
||||
|
|
|
@ -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
17
tests/commands/append.rs
Normal 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");
|
||||
}
|
|
@ -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
52
tests/commands/compact.rs
Normal 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");
|
||||
});
|
||||
}
|
|
@ -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
36
tests/commands/default.rs
Normal 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
16
tests/commands/edit.rs
Normal 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");
|
||||
}
|
|
@ -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
70
tests/commands/first.rs
Normal 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
16
tests/commands/format.rs
Normal 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");
|
||||
}
|
|
@ -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
|
56
tests/commands/group_by.rs
Normal file
56
tests/commands/group_by.rs
Normal 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"));
|
||||
})
|
||||
}
|
32
tests/commands/histogram.rs
Normal file
32
tests/commands/histogram.rs
Normal 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
16
tests/commands/insert.rs
Normal 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
56
tests/commands/last.rs
Normal 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
21
tests/commands/lines.rs
Normal 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");
|
||||
}
|
|
@ -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
|
|
@ -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
30
tests/commands/mod.rs
Normal 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;
|
|
@ -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
39
tests/commands/nth.rs
Normal 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");
|
||||
});
|
||||
}
|
|
@ -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
17
tests/commands/parse.rs
Normal 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
17
tests/commands/prepend.rs
Normal 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
47
tests/commands/range.rs
Normal 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
11
tests/commands/reverse.rs
Normal 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");
|
||||
}
|
|
@ -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
47
tests/commands/save.rs
Normal 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
23
tests/commands/sort_by.rs
Normal 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");
|
||||
}
|
55
tests/commands/split_by.rs
Normal file
55
tests/commands/split_by.rs
Normal 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"));
|
||||
})
|
||||
}
|
20
tests/commands/split_column.rs
Normal file
20
tests/commands/split_column.rs
Normal 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");
|
||||
}
|
|
@ -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
63
tests/commands/wrap.rs
Normal 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");
|
||||
})
|
||||
}
|
|
@ -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"));
|
||||
})
|
||||
}
|
18
tests/converting_formats/bson.rs
Normal file
18
tests/converting_formats/bson.rs
Normal 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");
|
||||
}
|
184
tests/converting_formats/csv.rs
Normal file
184
tests/converting_formats/csv.rs
Normal 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");
|
||||
})
|
||||
}
|
103
tests/converting_formats/json.rs
Normal file
103
tests/converting_formats/json.rs
Normal 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");
|
||||
})
|
||||
}
|
10
tests/converting_formats/mod.rs
Normal file
10
tests/converting_formats/mod.rs
Normal 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;
|
19
tests/converting_formats/sqlite.rs
Normal file
19
tests/converting_formats/sqlite.rs
Normal 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");
|
||||
}
|
98
tests/converting_formats/ssv.rs
Normal file
98
tests/converting_formats/ssv.rs
Normal 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");
|
||||
})
|
||||
}
|
17
tests/converting_formats/toml.rs
Normal file
17
tests/converting_formats/toml.rs
Normal 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");
|
||||
}
|
136
tests/converting_formats/tsv.rs
Normal file
136
tests/converting_formats/tsv.rs
Normal 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");
|
||||
})
|
||||
}
|
17
tests/converting_formats/url.rs
Normal file
17
tests/converting_formats/url.rs
Normal 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é");
|
||||
}
|
17
tests/converting_formats/xlsx.rs
Normal file
17
tests/converting_formats/xlsx.rs
Normal 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");
|
||||
}
|
17
tests/converting_formats/yaml.rs
Normal file
17
tests/converting_formats/yaml.rs
Normal 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");
|
||||
}
|
|
@ -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
43
tests/filters.rs
Normal 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");
|
||||
// }
|
|
@ -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");
|
||||
})
|
||||
}
|
|
@ -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
6
tests/main.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
extern crate test_support;
|
||||
|
||||
mod commands;
|
||||
mod converting_formats;
|
||||
mod plugins;
|
||||
mod shell;
|
|
@ -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() {
|
|
@ -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
2
tests/plugins/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
|||
mod core_inc;
|
||||
mod core_str;
|
32
tests/shell/mod.rs
Normal file
32
tests/shell/mod.rs
Normal 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"));
|
||||
})
|
||||
}
|
||||
}
|
135
tests/tests.rs
135
tests/tests.rs
|
@ -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");
|
||||
}
|
Loading…
Reference in a new issue