2020-03-04 19:58:20 +01:00
|
|
|
use crate::fs;
|
2019-12-15 17:15:06 +01:00
|
|
|
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 {
|
2019-12-31 08:36:08 +01:00
|
|
|
self.fixtures.join("formats")
|
2019-12-15 17:15:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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 {
|
2019-12-31 08:36:08 +01:00
|
|
|
root,
|
2019-12-15 17:15:06 +01:00
|
|
|
tests: topic.to_string(),
|
|
|
|
cwd: nuplay_dir,
|
|
|
|
};
|
|
|
|
|
|
|
|
let playground_root = playground.root.path();
|
|
|
|
|
2020-03-04 19:58:20 +01:00
|
|
|
let fixtures = fs::fixtures();
|
2019-12-31 08:36:08 +01:00
|
|
|
let fixtures = dunce::canonicalize(fixtures.clone()).unwrap_or_else(|e| {
|
|
|
|
panic!(
|
|
|
|
"Couldn't canonicalize fixtures path {}: {:?}",
|
|
|
|
fixtures.display(),
|
|
|
|
e
|
|
|
|
)
|
|
|
|
});
|
|
|
|
|
|
|
|
let test = dunce::canonicalize(playground_root.join(topic)).unwrap_or_else(|e| {
|
|
|
|
panic!(
|
|
|
|
"Couldn't canonicalize test path {}: {:?}",
|
|
|
|
playground_root.join(topic).display(),
|
|
|
|
e
|
|
|
|
)
|
|
|
|
});
|
|
|
|
|
|
|
|
let root = dunce::canonicalize(playground_root).unwrap_or_else(|e| {
|
|
|
|
panic!(
|
|
|
|
"Couldn't canonicalize tests root path {}: {:?}",
|
|
|
|
playground_root.display(),
|
|
|
|
e
|
|
|
|
)
|
|
|
|
});
|
2019-12-15 17:15:06 +01:00
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2020-07-18 03:59:23 +02:00
|
|
|
#[cfg(not(target_arch = "wasm32"))]
|
2020-04-25 08:09:00 +02:00
|
|
|
pub fn symlink(&mut self, from: impl AsRef<Path>, to: impl AsRef<Path>) -> &mut Self {
|
|
|
|
let from = self.cwd.join(from);
|
|
|
|
let to = self.cwd.join(to);
|
|
|
|
|
|
|
|
let create_symlink = {
|
|
|
|
#[cfg(unix)]
|
|
|
|
{
|
|
|
|
std::os::unix::fs::symlink
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(windows)]
|
|
|
|
{
|
|
|
|
if from.is_file() {
|
|
|
|
std::os::windows::fs::symlink_file
|
|
|
|
} else if from.is_dir() {
|
|
|
|
std::os::windows::fs::symlink_dir
|
|
|
|
} else {
|
|
|
|
panic!("symlink from must be a file or dir")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
create_symlink(from, to).expect("can not create symlink");
|
|
|
|
self.back_to_playground();
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2019-12-15 17:15:06 +01:00
|
|
|
pub fn with_files(&mut self, files: Vec<Stub>) -> &mut Self {
|
2020-03-04 19:58:20 +01:00
|
|
|
let endl = fs::line_ending();
|
2019-12-15 17:15:06 +01:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2019-12-31 08:36:08 +01:00
|
|
|
std::fs::write(path, contents.as_bytes()).expect("can not create file");
|
2019-12-15 17:15:06 +01:00
|
|
|
})
|
|
|
|
.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);
|
|
|
|
|
2019-12-31 08:36:08 +01:00
|
|
|
glob.expect("invalid pattern")
|
|
|
|
.map(|path| {
|
|
|
|
if let Ok(path) = path {
|
|
|
|
path
|
|
|
|
} else {
|
|
|
|
unreachable!()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.collect()
|
2019-12-15 17:15:06 +01:00
|
|
|
}
|
|
|
|
}
|