mirror of
https://github.com/nushell/nushell
synced 2024-12-25 12:33:17 +00:00
Merge pull request #1081 from andrasio/test-extract
Start test organization facelift.
This commit is contained in:
commit
6c577e18ca
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