#![cfg(feature = "sequential-tests")]
use i3nator::{
configfiles::ConfigFile,
projects::{self, Project},
types::*,
};
use lazy_static::lazy_static;
use std::{
env,
ffi::OsString,
fs::{self, File},
io::prelude::*,
panic::{self, UnwindSafe},
path::{Path, PathBuf},
};
use tempdir::TempDir;
use tempfile::NamedTempFile;
lazy_static! {
static ref TMP_DIR: TempDir = TempDir::new("i3nator-tests").unwrap();
static ref PROJECTS_DIR: PathBuf = TMP_DIR.path().join("i3nator/projects");
}
fn with_projects_dir<F: FnOnce(&Path) -> ()>(body: F)
where
F: UnwindSafe,
{
if !PROJECTS_DIR.exists() {
fs::create_dir_all(&*PROJECTS_DIR).expect("couldn't create temporary directories");
}
env::set_var("XDG_CONFIG_HOME", TMP_DIR.path());
let panic_result = panic::catch_unwind(|| body(PROJECTS_DIR.as_ref()));
fs::remove_dir_all(&*TMP_DIR).expect("couldn't delete temporary directories");
if let Err(err) = panic_result {
panic::resume_unwind(err);
}
}
#[test]
fn empty_list() {
with_projects_dir(|_| {
assert!(projects::list().is_empty());
})
}
#[test]
fn create() {
with_projects_dir(|projects_dir| {
let project = Project::create("project-one").unwrap();
assert_eq!(project.name, "project-one");
assert_eq!(project.path, projects_dir.join("project-one.toml"));
assert!(project.verify().is_err());
assert!(projects::list().is_empty());
})
}
#[test]
#[should_panic(expected = "ConfigExists")]
fn create_exists() {
with_projects_dir(|projects_dir| {
let project = Project::create("project-one").unwrap();
assert_eq!(project.name, "project-one");
assert_eq!(project.path, projects_dir.join("project-one.toml"));
assert!(project.verify().is_err());
File::create(&project.path).expect("couldn't create project file");
assert_eq!(projects::list(), vec![OsString::from("project-one")]);
Project::create("project-one").unwrap();
})
}
#[test]
fn create_from_template() {
with_projects_dir(|projects_dir| {
let template = "this is my template";
let project =
Project::create_from_template("project-template", template.as_bytes()).unwrap();
assert_eq!(project.name, "project-template");
assert_eq!(project.path, projects_dir.join("project-template.toml"));
assert!(project.path.exists());
assert!(project.verify().is_err());
let mut file = File::open(project.path).unwrap();
let mut contents = String::new();
file.read_to_string(&mut contents).unwrap();
assert_eq!(contents, template);
})
}
#[test]
fn from_path() {
let tempfile = NamedTempFile::new().expect("couldn't create temporary file");
let project = Project::from_path(tempfile.path()).unwrap();
assert_eq!(project.name, "local");
assert_eq!(project.path, tempfile.path());
assert!(project.verify().is_err());
}
#[test]
#[should_panic(expected = "PathDoesntExist")]
fn from_path_not_exists() {
Project::from_path("/this/path/does/not/exist").unwrap();
}
#[test]
fn open() {
with_projects_dir(|projects_dir| {
let project = Project::create("project-open").unwrap();
assert_eq!(project.name, "project-open");
assert_eq!(project.path, projects_dir.join("project-open.toml"));
assert!(project.verify().is_err());
File::create(&project.path).expect("couldn't create project file");
let project_open = Project::open("project-open").unwrap();
assert_eq!(project_open, project);
})
}
#[test]
#[should_panic(expected = "UnknownConfig")]
fn open_unknown_project() {
with_projects_dir(|_| {
Project::open("unknown-project").unwrap();
})
}
#[test]
fn config() {
with_projects_dir(|projects_dir| {
let template = r#"[general]
layout = "{ ... }"
[[applications]]
command = "mycommand""#;
let mut project =
Project::create_from_template("project-template", template.as_bytes()).unwrap();
assert_eq!(project.name, "project-template");
assert_eq!(project.path, projects_dir.join("project-template.toml"));
assert!(project.path.exists());
assert!(project.verify().is_ok());
let expected = Config {
general: General {
working_directory: None,
workspace: None,
layout: Layout::Contents("{ ... }".to_owned()),
},
applications: vec![Application {
command: ApplicationCommand {
program: "mycommand".to_owned(),
args: vec![],
},
working_directory: None,
exec: None,
}],
};
assert_eq!(project.config().unwrap(), &expected);
})
}
#[test]
fn config_invalid() {
with_projects_dir(|projects_dir| {
let template = r#"invalid template"#;
let mut project =
Project::create_from_template("project-template", template.as_bytes()).unwrap();
assert_eq!(project.name, "project-template");
assert_eq!(project.path, projects_dir.join("project-template.toml"));
assert!(project.path.exists());
assert!(project.verify().is_err());
assert!(project.config().is_err());
})
}
#[test]
fn copy() {
with_projects_dir(|projects_dir| {
let project = Project::create("project-existing").unwrap();
assert_eq!(project.name, "project-existing");
assert_eq!(project.path, projects_dir.join("project-existing.toml"));
assert!(project.verify().is_err());
File::create(&project.path).expect("couldn't create project file");
let project_new = project.copy("project-new").unwrap();
assert_eq!(project_new.name, "project-new");
assert_eq!(project_new.path, projects_dir.join("project-new.toml"));
assert!(project.verify().is_err());
})
}
#[test]
#[should_panic(expected = "No such file or directory")]
fn copy_without_file() {
with_projects_dir(|projects_dir| {
let project = Project::create("project-existing").unwrap();
assert_eq!(project.name, "project-existing");
assert_eq!(project.path, projects_dir.join("project-existing.toml"));
assert!(project.verify().is_err());
project.copy("project-new").unwrap();
})
}
#[test]
fn delete() {
with_projects_dir(|projects_dir| {
let project = Project::create("project-delete").unwrap();
assert_eq!(project.name, "project-delete");
assert_eq!(project.path, projects_dir.join("project-delete.toml"));
assert!(project.verify().is_err());
File::create(&project.path).expect("couldn't create project file");
assert!(project.delete().is_ok());
assert!(!project.path.exists())
})
}
#[test]
#[should_panic(expected = "No such file or directory")]
fn delete_without_file() {
with_projects_dir(|projects_dir| {
let project = Project::create("project-delete").unwrap();
assert_eq!(project.name, "project-delete");
assert_eq!(project.path, projects_dir.join("project-delete.toml"));
assert!(project.verify().is_err());
project.delete().unwrap();
})
}
#[test]
fn rename() {
with_projects_dir(|projects_dir| {
let project = Project::create("project-rename-old").unwrap();
assert_eq!(project.name, "project-rename-old");
assert_eq!(project.path, projects_dir.join("project-rename-old.toml"));
assert!(project.verify().is_err());
File::create(&project.path).expect("couldn't create project file");
let project_new = project.rename("project-rename-new").unwrap();
assert_eq!(project_new.name, "project-rename-new");
assert_eq!(
project_new.path,
projects_dir.join("project-rename-new.toml")
);
assert!(project_new.verify().is_err());
assert!(!project.path.exists());
assert!(project_new.path.exists());
})
}