From 3acf2ffea109e39a07a86ba7b4f9b96fc938d525 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 4 Oct 2018 20:01:25 +0100 Subject: [PATCH] Refactor game-specific code and add tests for it --- src/function/eval.rs | 14 +--- src/lib.rs | 157 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 157 insertions(+), 14 deletions(-) diff --git a/src/function/eval.rs b/src/function/eval.rs index 20c41f8..e65f5e7 100644 --- a/src/function/eval.rs +++ b/src/function/eval.rs @@ -11,18 +11,6 @@ use super::Function; use Error; use State; -fn has_plugin_file_extension(path: &Path, state: &State) -> bool { - match path.extension().and_then(OsStr::to_str) { - Some("esp") | Some("esm") => true, - Some("esl") if state.game_type.supports_light_plugins() => true, - Some("ghost") => path - .file_stem() - .map(|s| has_plugin_file_extension(Path::new(s), state)) - .unwrap_or(false), - _ => false, - } -} - fn add_extension(path: &Path, extension: &str) -> PathBuf { match path.extension() { Some(e) => { @@ -44,7 +32,7 @@ fn resolve_path(state: &State, path: &Path) -> PathBuf { } else { let path = state.data_path.join(path); - if !path.exists() && has_plugin_file_extension(&path, state) { + if !path.exists() && state.game_type.is_plugin_filename(&path) { add_extension(&path, "ghost") } else { path diff --git a/src/lib.rs b/src/lib.rs index 42172bc..9137ed3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,8 +7,9 @@ extern crate regex; extern crate tempfile; use std::collections::{HashMap, HashSet}; +use std::ffi::OsStr; use std::io; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::str; use std::sync::RwLock; @@ -59,6 +60,18 @@ impl GameType { _ => false, } } + + fn is_plugin_filename(&self, path: &Path) -> bool { + match path.extension().and_then(OsStr::to_str) { + Some("esp") | Some("esm") => true, + Some("esl") if self.supports_light_plugins() => true, + Some("ghost") => path + .file_stem() + .map(|s| self.is_plugin_filename(Path::new(s))) + .unwrap_or(false), + _ => false, + } + } } pub struct State { @@ -172,6 +185,148 @@ mod tests { } } + #[test] + fn game_type_supports_light_plugins_should_be_true_for_tes5se_tes5vr_fo4_and_fo4vr() { + assert!(GameType::Tes5se.supports_light_plugins()); + assert!(GameType::Tes5vr.supports_light_plugins()); + assert!(GameType::Fo4.supports_light_plugins()); + assert!(GameType::Fo4vr.supports_light_plugins()); + } + + #[test] + fn game_type_supports_light_master_should_be_false_for_tes4_tes5_fo3_and_fonv() { + assert!(!GameType::Tes4.supports_light_plugins()); + assert!(!GameType::Tes5.supports_light_plugins()); + assert!(!GameType::Fo3.supports_light_plugins()); + assert!(!GameType::Fonv.supports_light_plugins()); + } + + #[test] + fn game_type_is_plugin_filename_should_be_true_for_esp_for_all_game_types() { + let filename = Path::new("Blank.esp"); + + assert!(GameType::Tes4.is_plugin_filename(filename)); + assert!(GameType::Tes5.is_plugin_filename(filename)); + assert!(GameType::Tes5se.is_plugin_filename(filename)); + assert!(GameType::Tes5vr.is_plugin_filename(filename)); + assert!(GameType::Fo3.is_plugin_filename(filename)); + assert!(GameType::Fonv.is_plugin_filename(filename)); + assert!(GameType::Fo4.is_plugin_filename(filename)); + assert!(GameType::Fo4vr.is_plugin_filename(filename)); + } + + #[test] + fn game_type_is_plugin_filename_should_be_true_for_esm_for_all_game_types() { + let filename = Path::new("Blank.esm"); + + assert!(GameType::Tes4.is_plugin_filename(filename)); + assert!(GameType::Tes5.is_plugin_filename(filename)); + assert!(GameType::Tes5se.is_plugin_filename(filename)); + assert!(GameType::Tes5vr.is_plugin_filename(filename)); + assert!(GameType::Fo3.is_plugin_filename(filename)); + assert!(GameType::Fonv.is_plugin_filename(filename)); + assert!(GameType::Fo4.is_plugin_filename(filename)); + assert!(GameType::Fo4vr.is_plugin_filename(filename)); + } + + #[test] + fn game_type_is_plugin_filename_should_be_true_for_esl_for_tes5se_tes5vr_fo4_and_fo4vr() { + let filename = Path::new("Blank.esl"); + + assert!(GameType::Tes5se.is_plugin_filename(filename)); + assert!(GameType::Tes5vr.is_plugin_filename(filename)); + assert!(GameType::Fo4.is_plugin_filename(filename)); + assert!(GameType::Fo4vr.is_plugin_filename(filename)); + } + + #[test] + fn game_type_is_plugin_filename_should_be_false_for_esl_for_tes4_tes5_fo3_and_fonv() { + let filename = Path::new("Blank.esl"); + + assert!(!GameType::Tes4.is_plugin_filename(filename)); + assert!(!GameType::Tes5.is_plugin_filename(filename)); + assert!(!GameType::Fo3.is_plugin_filename(filename)); + assert!(!GameType::Fonv.is_plugin_filename(filename)); + } + + #[test] + fn game_type_is_plugin_filename_should_be_true_for_esp_dot_ghost_for_all_game_types() { + let filename = Path::new("Blank.esp.ghost"); + + assert!(GameType::Tes4.is_plugin_filename(filename)); + assert!(GameType::Tes5.is_plugin_filename(filename)); + assert!(GameType::Tes5se.is_plugin_filename(filename)); + assert!(GameType::Tes5vr.is_plugin_filename(filename)); + assert!(GameType::Fo3.is_plugin_filename(filename)); + assert!(GameType::Fonv.is_plugin_filename(filename)); + assert!(GameType::Fo4.is_plugin_filename(filename)); + assert!(GameType::Fo4vr.is_plugin_filename(filename)); + } + + #[test] + fn game_type_is_plugin_filename_should_be_true_for_esm_dot_ghost_for_all_game_types() { + let filename = Path::new("Blank.esm.ghost"); + + assert!(GameType::Tes4.is_plugin_filename(filename)); + assert!(GameType::Tes5.is_plugin_filename(filename)); + assert!(GameType::Tes5se.is_plugin_filename(filename)); + assert!(GameType::Tes5vr.is_plugin_filename(filename)); + assert!(GameType::Fo3.is_plugin_filename(filename)); + assert!(GameType::Fonv.is_plugin_filename(filename)); + assert!(GameType::Fo4.is_plugin_filename(filename)); + assert!(GameType::Fo4vr.is_plugin_filename(filename)); + } + + #[test] + fn game_type_is_plugin_filename_should_be_true_for_esl_dot_ghost_for_tes5se_tes5vr_fo4_and_fo4vr( +) { + let filename = Path::new("Blank.esl.ghost"); + + assert!(GameType::Tes5se.is_plugin_filename(filename)); + assert!(GameType::Tes5vr.is_plugin_filename(filename)); + assert!(GameType::Fo4.is_plugin_filename(filename)); + assert!(GameType::Fo4vr.is_plugin_filename(filename)); + } + + #[test] + fn game_type_is_plugin_filename_should_be_false_for_esl_dot_ghost_for_tes4_tes5_fo3_and_fonv() { + let filename = Path::new("Blank.esl.ghost"); + + assert!(!GameType::Tes4.is_plugin_filename(filename)); + assert!(!GameType::Tes5.is_plugin_filename(filename)); + assert!(!GameType::Fo3.is_plugin_filename(filename)); + assert!(!GameType::Fonv.is_plugin_filename(filename)); + } + + #[test] + fn game_type_is_plugin_filename_should_be_false_for_non_esp_esm_esl_for_all_game_types() { + let filename = Path::new("Blank.txt"); + + assert!(!GameType::Tes4.is_plugin_filename(filename)); + assert!(!GameType::Tes5.is_plugin_filename(filename)); + assert!(!GameType::Tes5se.is_plugin_filename(filename)); + assert!(!GameType::Tes5vr.is_plugin_filename(filename)); + assert!(!GameType::Fo3.is_plugin_filename(filename)); + assert!(!GameType::Fonv.is_plugin_filename(filename)); + assert!(!GameType::Fo4.is_plugin_filename(filename)); + assert!(!GameType::Fo4vr.is_plugin_filename(filename)); + } + + #[test] + fn game_type_is_plugin_filename_should_be_false_for_non_esp_esm_esl_dot_ghost_for_all_game_types( +) { + let filename = Path::new("Blank.txt.ghost"); + + assert!(!GameType::Tes4.is_plugin_filename(filename)); + assert!(!GameType::Tes5.is_plugin_filename(filename)); + assert!(!GameType::Tes5se.is_plugin_filename(filename)); + assert!(!GameType::Tes5vr.is_plugin_filename(filename)); + assert!(!GameType::Fo3.is_plugin_filename(filename)); + assert!(!GameType::Fonv.is_plugin_filename(filename)); + assert!(!GameType::Fo4.is_plugin_filename(filename)); + assert!(!GameType::Fo4vr.is_plugin_filename(filename)); + } + #[test] fn expression_parse_should_handle_a_single_compound_condition() { let result = Expression::parse("file(\"Cargo.toml\")").unwrap().1;