From 632107ddff3b567bd613000a26b155ab5f5bf125 Mon Sep 17 00:00:00 2001 From: Cosmic Horror Date: Sat, 18 Nov 2023 17:47:31 -0700 Subject: [PATCH] Drastically simplify test helpers --- src/lib.rs | 6 +- src/{__test_helpers.rs => test_helpers.rs} | 126 ++++++--------------- src/tests.rs | 4 +- 3 files changed, 39 insertions(+), 97 deletions(-) rename src/{__test_helpers.rs => test_helpers.rs} (67%) diff --git a/src/lib.rs b/src/lib.rs index 848d11d..0057063 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -150,11 +150,9 @@ pub use libraryfolders::{parse_library_folders, Library}; pub mod shortcut; pub use shortcut::Shortcut; -/// NOT A PART OF THE PUBLIC API -/// /// These are just some helpers for setting up dummy test environments -#[doc(hidden)] -pub mod __test_helpers; +#[cfg(any(test, doctest))] +pub mod test_helpers; /// An instance of a Steam installation. /// diff --git a/src/__test_helpers.rs b/src/test_helpers.rs similarity index 67% rename from src/__test_helpers.rs rename to src/test_helpers.rs index 8469892..91e6dd8 100644 --- a/src/__test_helpers.rs +++ b/src/test_helpers.rs @@ -1,8 +1,4 @@ -//! NOT PART OF THE PUBLIC API -//! //! Some test helpers for setting up isolated dummy steam installations. -//! -//! Publicly accessible so that we can use them in unit, doc, and integration tests. // TODO: add a test with an env var flag that runs against your real local steam installation? @@ -10,52 +6,31 @@ use std::{ collections::BTreeMap, convert::{TryFrom, TryInto}, fs, iter, - marker::PhantomData, path::{Path, PathBuf}, }; use crate::SteamDir; use serde::Serialize; +use tempfile::TempDir; -// A little bit of a headache. We want to use tempdirs for isolating the dummy steam installations, -// but we can't specify a `cfg` that includes integration tests while also allowing for naming a -// `dev-dependency` here. Instead we abstract the functionality behind a trait and every dependent -// can provide their own concrete implementation. It makes for a bit of a mess unfortunately, but -// it's either this or add a feature that's only used internally for testing which I don't like -// even more. -pub trait TempDir: Sized { - fn new() -> Result; - fn path(&self) -> PathBuf; -} - -#[cfg(test)] -pub struct TestTempDir(tempfile::TempDir); - -#[cfg(test)] -impl TempDir for TestTempDir { - fn new() -> Result { - let mut builder = tempfile::Builder::new(); - builder.prefix("steamlocate-test-"); - let temp_dir = builder.tempdir()?; - Ok(Self(temp_dir)) - } - - fn path(&self) -> PathBuf { - self.0.path().to_owned() - } +fn test_temp_dir() -> Result { + let temp_dir = tempfile::Builder::new() + .prefix("steamlocate-test-") + .tempdir()?; + Ok(temp_dir) } pub type TestError = Box; pub type TestResult = Result<(), TestError>; // TODO(cosmic): Add in functionality for providing shortcuts too -pub struct TempSteamDir { +pub struct TempSteamDir { steam_dir: crate::SteamDir, - _tmps: Vec, + _tmps: Vec, } -impl TryFrom for TempSteamDir { +impl TryFrom for TempSteamDir { type Error = TestError; fn try_from(app: AppFile) -> Result { @@ -63,7 +38,7 @@ impl TryFrom for TempSteamDir { } } -impl TryFrom for TempSteamDir { +impl TryFrom for TempSteamDir { type Error = TestError; fn try_from(sample_app: SampleApp) -> Result { @@ -71,9 +46,9 @@ impl TryFrom for TempSteamDir { } } -impl TempSteamDir { - pub fn builder() -> TempSteamDirBuilder { - TempSteamDirBuilder::new() +impl TempSteamDir { + pub fn builder() -> TempSteamDirBuilder { + TempSteamDirBuilder::default() } pub fn steam_dir(&self) -> &SteamDir { @@ -81,42 +56,27 @@ impl TempSteamDir { } } +#[derive(Default)] #[must_use] -pub struct TempSteamDirBuilder { - libraries: Vec>, +pub struct TempSteamDirBuilder { + libraries: Vec, apps: Vec, } -impl Default for TempSteamDirBuilder { - fn default() -> Self { - Self { - libraries: Vec::default(), - apps: Vec::default(), - } - } -} - -impl TempSteamDirBuilder { - pub fn new() -> Self { - Self::default() - } - +impl TempSteamDirBuilder { pub fn app(mut self, app: AppFile) -> Self { self.apps.push(app); self } - pub fn library(mut self, library: TempLibrary) -> Self { + pub fn library(mut self, library: TempLibrary) -> Self { self.libraries.push(library); self } // Steam dir is also a library, but is laid out slightly differently than a regular library - pub fn finish(self) -> Result, TestError> - where - TmpDir: TempDir, - { - let tmp = TmpDir::new()?; + pub fn finish(self) -> Result { + let tmp = test_temp_dir()?; let root_dir = tmp.path().join("test-steam-dir"); let steam_dir = root_dir.join("Steam"); let apps_dir = steam_dir.join("steamapps"); @@ -155,10 +115,10 @@ fn setup_steamapps_dir(apps_dir: &Path, apps: &[AppFile]) -> Result<(), TestErro Ok(()) } -fn setup_libraryfolders_file( +fn setup_libraryfolders_file( apps_dir: &Path, root_library: LibraryFolder, - aux_libraries: &[TempLibrary], + aux_libraries: &[TempLibrary], ) -> Result<(), TestError> { let library_folders = iter::once(root_library).chain(aux_libraries.iter().map(|temp_library| { @@ -207,14 +167,14 @@ impl LibraryFolder { } } -pub struct TempLibrary { +pub struct TempLibrary { content_id: i32, path: PathBuf, apps: BTreeMap, - _tmp: TmpDir, + _tmp: TempDir, } -impl TryFrom for TempLibrary { +impl TryFrom for TempLibrary { type Error = TestError; fn try_from(app: AppFile) -> Result { @@ -222,7 +182,7 @@ impl TryFrom for TempLibrary { } } -impl TryFrom for TempLibrary { +impl TryFrom for TempLibrary { type Error = TestError; fn try_from(sample_app: SampleApp) -> Result { @@ -230,42 +190,26 @@ impl TryFrom for TempLibrary { } } -impl TempLibrary { - pub fn builder() -> TempLibraryBuilder { - TempLibraryBuilder::new() +impl TempLibrary { + pub fn builder() -> TempLibraryBuilder { + TempLibraryBuilder::default() } } +#[derive(Default)] #[must_use] -pub struct TempLibraryBuilder { +pub struct TempLibraryBuilder { apps: Vec, - temp_dir_type: PhantomData, -} - -impl Default for TempLibraryBuilder { - fn default() -> Self { - Self { - apps: Vec::default(), - temp_dir_type: PhantomData, - } - } } -impl TempLibraryBuilder { - fn new() -> Self { - Self::default() - } - +impl TempLibraryBuilder { fn app(mut self, app: AppFile) -> Self { self.apps.push(app); self } - fn finish(self) -> Result, TestError> - where - TmpDir: TempDir, - { - let tmp = TmpDir::new()?; + fn finish(self) -> Result { + let tmp = test_temp_dir()?; let root_dir = tmp.path().join("test-library"); let apps_dir = root_dir.join("steamapps"); fs::create_dir_all(&apps_dir)?; @@ -343,7 +287,7 @@ impl SampleApp { #[test] fn sanity() -> TestResult { - let tmp_steam_dir = TempSteamDir::::try_from(SampleApp::GarrysMod)?; + let tmp_steam_dir = TempSteamDir::try_from(SampleApp::GarrysMod)?; let steam_dir = tmp_steam_dir.steam_dir(); assert!(steam_dir.app(SampleApp::GarrysMod.id()).unwrap().is_some()); diff --git a/src/tests.rs b/src/tests.rs index e4103d8..a4b49ea 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,8 +1,8 @@ use std::convert::TryInto; use crate::{ + test_helpers::{SampleApp, TempSteamDir, TestError, TestResult}, Error, - __test_helpers::{SampleApp, TempSteamDir, TestError, TestResult, TestTempDir}, }; static GMOD_ID: u32 = SampleApp::GarrysMod.id(); @@ -11,7 +11,7 @@ static GMOD_ID: u32 = SampleApp::GarrysMod.id(); // - Steam must be installed // - At least two library folders must be setup (the steam dir acts as one) // - Garry's Mod along with at least one other steam app must be installed -pub fn legacy_test_env() -> std::result::Result, TestError> { +pub fn legacy_test_env() -> std::result::Result { TempSteamDir::builder() .app(SampleApp::GarrysMod.into()) .library(SampleApp::GraveyardKeeper.try_into()?)