use std::env;
use std::fs;
use std::io::Write;
use std::path::PathBuf;
use std::process::{Command, Stdio};
const MKTOOL: &str = env!("CARGO_BIN_EXE_mktool");
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
#[test]
fn test_symlink_simple() -> Result<()> {
let tmpdir = PathBuf::from(env!("CARGO_TARGET_TMPDIR"));
let mut cmd = Command::new(MKTOOL)
.arg("symlinks")
.current_dir(&tmpdir)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?;
let mut stdin = cmd.stdin.take().ok_or("failed to open stdin")?;
std::thread::spawn(move || {
let _ = stdin.write_all("dst1 -> src1\n".as_bytes());
});
let out = cmd.wait_with_output()?;
assert_eq!(out.status.code(), Some(0));
assert_eq!(out.stdout, "".as_bytes());
assert_eq!(out.stderr, "".as_bytes());
assert!(tmpdir.clone().join("dst1").is_symlink());
assert!(!tmpdir.clone().join("dst1").exists());
assert!(!tmpdir.clone().join("src1").exists());
Ok(())
}
#[test]
fn test_symlink_overwrite() -> Result<()> {
let tmpdir = PathBuf::from(env!("CARGO_TARGET_TMPDIR"));
let mut cmd = Command::new(MKTOOL)
.arg("symlinks")
.current_dir(&tmpdir)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?;
let mut stdin = cmd.stdin.take().ok_or("failed to open stdin")?;
std::thread::spawn(move || {
let _ = stdin.write_all("dst2 -> src2\ndst2 -> src2a\n".as_bytes());
});
let out = cmd.wait_with_output()?;
assert_eq!(out.status.code(), Some(0));
assert_eq!(out.stdout, "".as_bytes());
assert_eq!(out.stderr, "".as_bytes());
assert!(tmpdir.clone().join("dst2").is_symlink());
assert!(!tmpdir.clone().join("dst2").exists());
assert!(!tmpdir.clone().join("src2").exists());
assert!(!tmpdir.clone().join("src2a").exists());
Ok(())
}
#[test]
fn test_symlink_subdir() -> Result<()> {
let tmpdir = PathBuf::from(env!("CARGO_TARGET_TMPDIR"));
let mut cmd = Command::new(MKTOOL)
.arg("symlinks")
.current_dir(&tmpdir)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?;
let mut stdin = cmd.stdin.take().ok_or("failed to open stdin")?;
std::thread::spawn(move || {
let _ = stdin.write_all(" dst3/a/b/c/f -> src3 \n".as_bytes());
});
let out = cmd.wait_with_output()?;
assert_eq!(out.status.code(), Some(0));
assert_eq!(out.stdout, "".as_bytes());
assert_eq!(out.stderr, "".as_bytes());
assert!(tmpdir.clone().join("dst3").is_dir());
assert!(tmpdir.clone().join("dst3/a").is_dir());
assert!(tmpdir.clone().join("dst3/a/b").is_dir());
assert!(tmpdir.clone().join("dst3/a/b/c").is_dir());
assert!(tmpdir.clone().join("dst3/a/b/c/f").is_symlink());
assert!(!tmpdir.clone().join("dst3/a/b/c/f").exists());
Ok(())
}
#[test]
fn test_symlink_invalid() -> Result<()> {
let mut tmpdir = PathBuf::from(env!("CARGO_TARGET_TMPDIR"));
tmpdir.push("invalid");
fs::create_dir(&tmpdir)?;
let mut cmd = Command::new(MKTOOL)
.arg("symlinks")
.current_dir(&tmpdir)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?;
let mut stdin = cmd.stdin.take().ok_or("failed to open stdin")?;
std::thread::spawn(move || {
let _ = stdin.write_all(
format!(
"{}\n{}\n{}\n\n",
"one/two -> three -> four", "one", "one two"
)
.as_bytes(),
);
});
let out = cmd.wait_with_output()?;
assert_eq!(out.status.code(), Some(0));
assert_eq!(out.stdout, "".as_bytes());
assert_eq!(out.stderr, "".as_bytes());
fs::remove_dir(&tmpdir)?;
Ok(())
}