// Copyright Pit Kleyersburg // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified or distributed // except according to those terms. #![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 ()>(body: F) where F: UnwindSafe, { // Create the temporary directories if they do not exist if !PROJECTS_DIR.exists() { fs::create_dir_all(&*PROJECTS_DIR).expect("couldn't create temporary directories"); } // Set up temporary XDG config directory env::set_var("XDG_CONFIG_HOME", TMP_DIR.path()); // Run body let panic_result = panic::catch_unwind(|| body(PROJECTS_DIR.as_ref())); // Remove the temporary directories 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()); // File does not get created by default, list should still be empty 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()); // Create project file File::create(&project.path).expect("couldn't create project file"); // File created, list should contain it assert_eq!(projects::list(), vec![OsString::from("project-one")]); // Create project with same name, this should fail 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()); // Create project file File::create(&project.path).expect("couldn't create project file"); // Open project 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()); // Create project file 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()); // Create project file 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()); // Create project file 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()); }) }