use super::{dd_pipe_err, Success};
use opts::Opts;
use std::{
fs,
io::{Read, Write},
path::Path,
};
use tempfile::{tempdir, TempDir};
const IN_PATH: &str = "in_file.txt";
const OUT_PATH: &str = "out_file.txt";
const BLOCK_SIZE: usize = 1024;
const TOTAL_BLOCKS: usize = 1024;
const TOTAL_BYTES: usize = BLOCK_SIZE * TOTAL_BLOCKS;
#[test]
fn base_case() {
let dir = tempdir().unwrap();
let in_path = string_path(&dir, IN_PATH);
let out_path = string_path(&dir, OUT_PATH);
write_file(&in_path, &mut [b'a'; TOTAL_BYTES]);
let args = vec!["dd".to_string(), keyval("if", &in_path), keyval("of", &out_path)];
let opts = Opts::new(args).unwrap();
if let Ok(Success::Bytes { bytes, .. }) = dd_pipe_err(&opts, vec![]) {
assert_eq!(bytes, TOTAL_BYTES)
} else {
panic!("expected Ok(Success::Bytes)")
}
let output = read_file(out_path);
assert_eq!(output, vec![b'a'; TOTAL_BYTES]);
}
#[test]
fn conversion_to_uppercase() {
let dir = tempdir().unwrap();
let (in_path, out_path) = (string_path(&dir, IN_PATH), string_path(&dir, OUT_PATH));
write_file(&in_path, &mut [b'a'; 1024 * 1024]);
let args = vec![
"dd".to_string(),
keyval("if", &in_path),
keyval("of", &out_path),
keyval("conv", "ucase"),
];
let opts = Opts::new(args).unwrap();
if let Ok(Success::Bytes { bytes, .. }) = dd_pipe_err(&opts, vec![]) {
assert_eq!(bytes, 1024 * 1024)
} else {
panic!("expected Ok(Success::Bytes)")
}
let output = read_file(out_path);
assert_eq!(output, vec![b'A'; 1024 * 1024]);
}
#[test]
fn seek_input_and_block_size() {
let dir = tempdir().unwrap();
let (in_path, out_path) = (string_path(&dir, IN_PATH), string_path(&dir, OUT_PATH));
write_file(&in_path, &mut [b'a'; 1024 * 1024]);
let args = vec![
"dd".to_string(),
keyval("if", &in_path),
keyval("of", &out_path),
keyval("ibs", "1024"),
keyval("iseek", "1"), ];
let opts = Opts::new(args).unwrap();
if let Ok(Success::Bytes { bytes, .. }) = dd_pipe_err(&opts, vec![]) {
assert_eq!(bytes, 1023 * 1024)
} else {
panic!("expected Ok(Success::Bytes)")
}
let got = read_file(out_path);
assert_eq!(got, vec![b'a'; 1023 * 1024]);
}
#[test]
fn block() {
let dir = tempdir().unwrap();
let (in_path, out_path) = (string_path(&dir, IN_PATH), string_path(&dir, OUT_PATH));
let mut input: Vec<u8> = "aaaaa\n\n\n\nbbbb\nccc\ndddddd".bytes().collect();
write_file(&in_path, &mut input);
let args = vec![
"dd".to_string(),
keyval("if", &in_path),
keyval("of", &out_path),
keyval("cbs", "5"), keyval("conv", "block"),
];
if let Ok(Success::Block {
lines,
truncated,
padded,
block_size,
..
}) = dd_pipe_err(&Opts::new(args).unwrap(), vec![])
{
assert_eq!((lines, truncated, padded, block_size), (4, 1, 2, 5));
} else {
panic!("expected Ok(Success::Bytes)")
}
let got = read_file(out_path);
let want: Vec<u8> = concat!("aaaaa", "bbbb ", "ccc ", "ddddd").bytes().collect();
assert_eq!(want, got)
}
fn string_path(dir: &TempDir, file: &str) -> String { dir.path().join(file).to_str().unwrap().to_string() }
fn keyval<S: AsRef<str>>(key: S, val: S) -> String { format!("{}={}", key.as_ref(), val.as_ref()) }
fn write_file<P: AsRef<Path>>(path: P, data: &mut [u8]) {
let mut f = fs::File::create(path.as_ref()).unwrap();
f.write_all(data).unwrap();
}
fn read_file<P: AsRef<Path>>(path: P) -> Vec<u8> {
let mut f = fs::File::open(path).unwrap();
let mut buf = Vec::new();
f.read_to_end(&mut buf).unwrap();
buf
}