#![cfg_attr(docsrs, feature(doc_cfg))]
#![warn(missing_docs)]
#![warn(rust_2018_idioms)]
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
pub struct TempProject {
_dir: tempfile::TempDir,
files: Vec<(PathBuf, Vec<u8>)>,
}
impl TempProject {
pub fn new() -> TempProjectBuilder {
TempProjectBuilder::default()
}
pub fn path(&self) -> &Path {
self._dir.path()
}
pub fn declared_files(&self) -> impl Iterator<Item = (&Path, &[u8])> {
self.files.iter().map(|(p, b)| (p.as_path(), b.as_slice()))
}
}
#[derive(Default)]
pub struct TempProjectBuilder {
files: Vec<(PathBuf, Vec<u8>)>,
}
impl TempProjectBuilder {
pub fn with_file(mut self, relative_path: impl Into<PathBuf>, contents: impl Into<String>) -> Self {
self.files
.push((relative_path.into(), contents.into().into_bytes()));
self
}
pub fn with_bytes(
mut self,
relative_path: impl Into<PathBuf>,
contents: impl Into<Vec<u8>>,
) -> Self {
self.files.push((relative_path.into(), contents.into()));
self
}
pub fn build(self) -> io::Result<TempProject> {
let dir = tempfile::tempdir()?;
for (rel, bytes) in &self.files {
let target = dir.path().join(rel);
if let Some(parent) = target.parent() {
fs::create_dir_all(parent)?;
}
fs::write(&target, bytes)?;
}
Ok(TempProject {
_dir: dir,
files: self.files,
})
}
}
pub trait Fixture {
type Output;
fn set_up(&mut self) -> io::Result<Self::Output>;
fn tear_down(&mut self) -> io::Result<()>;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn temp_project_builds_and_writes_files() {
let project = TempProject::new()
.with_file("a.txt", "hello")
.with_file("nested/b.txt", "world")
.build()
.unwrap();
let a = project.path().join("a.txt");
let b = project.path().join("nested").join("b.txt");
assert!(a.exists());
assert!(b.exists());
assert_eq!(std::fs::read_to_string(&a).unwrap(), "hello");
assert_eq!(std::fs::read_to_string(&b).unwrap(), "world");
}
#[test]
fn temp_project_cleans_up_on_drop() {
let path = {
let project = TempProject::new()
.with_file("x.txt", "ephemeral")
.build()
.unwrap();
project.path().to_path_buf()
};
assert!(!path.exists());
}
}