From be78597331380aded1f750bc11c5267ec492943f Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Fri, 14 Jun 2024 09:05:11 +0100 Subject: [PATCH] tests: make TestRepository from git crate available to other crates --- crates/git/Cargo.toml | 2 +- crates/git/src/repository/mod.rs | 20 +++++------ crates/git/src/repository/open/mod.rs | 25 ++++++------- crates/git/src/repository/open/otest.rs | 48 ++++++++++++++++--------- 4 files changed, 51 insertions(+), 44 deletions(-) diff --git a/crates/git/Cargo.toml b/crates/git/Cargo.toml index 48a794c..59345cb 100644 --- a/crates/git/Cargo.toml +++ b/crates/git/Cargo.toml @@ -50,7 +50,7 @@ thiserror = { workspace = true } actix = { workspace = true } # actix-rt = { workspace = true } # tokio = { workspace = true } -# + [dev-dependencies] # Testing assert2 = { workspace = true } diff --git a/crates/git/src/repository/mod.rs b/crates/git/src/repository/mod.rs index 2c77f30..14e1b1a 100644 --- a/crates/git/src/repository/mod.rs +++ b/crates/git/src/repository/mod.rs @@ -1,9 +1,13 @@ // #[cfg(test)] mod mock; +#[cfg(test)] +pub use mock::MockRepository; +#[cfg(test)] +pub use open::MockOpenRepository; + mod open; mod real; -#[cfg(test)] mod test; #[cfg(test)] @@ -12,21 +16,15 @@ mod tests; use git_next_config as config; use git_next_config::GitDir; -#[cfg(test)] -pub use mock::MockRepository; -#[cfg(test)] pub use open::otest::OnFetch; -#[cfg(test)] pub use open::otest::OnPush; -#[cfg(test)] -pub use open::MockOpenRepository; + pub use open::OpenRepository; pub use open::OpenRepositoryLike; pub use open::RealOpenRepository; pub use real::RealRepository; use tracing::info; -#[cfg(test)] use crate::repository::test::TestRepository; use crate::validation::repo::validate_repo; @@ -39,7 +37,6 @@ pub enum Repository { Real, #[cfg(test)] Mock(MockRepository), - #[cfg(test)] Test(TestRepository), } @@ -52,7 +49,6 @@ pub fn mock() -> MockRepository { MockRepository::new() } -#[cfg(test)] pub const fn test(fs: kxio::fs::FileSystem) -> TestRepository { TestRepository::new(false, fs, vec![], vec![]) } @@ -92,10 +88,10 @@ impl std::ops::Deref for Repository { fn deref(&self) -> &Self::Target { match self { Self::Real => &real::RealRepository, + Self::Test(test_repository) => test_repository, + #[cfg(test)] Self::Mock(mock_repository) => mock_repository, - #[cfg(test)] - Self::Test(test_repository) => test_repository, } } } diff --git a/crates/git/src/repository/open/mod.rs b/crates/git/src/repository/open/mod.rs index a3f080c..0082fe0 100644 --- a/crates/git/src/repository/open/mod.rs +++ b/crates/git/src/repository/open/mod.rs @@ -5,7 +5,6 @@ mod tests; pub mod oreal; -#[cfg(test)] pub mod otest; #[cfg(test)] @@ -22,7 +21,6 @@ use git_next_config as config; #[cfg(test)] pub use omock::MockOpenRepository; pub use oreal::RealOpenRepository; -#[cfg(test)] pub use otest::TestOpenRepository; #[derive(Clone, Debug)] @@ -31,6 +29,15 @@ pub enum OpenRepository { /// /// This variant is the normal implementation for use in production code. Real(RealOpenRepository), + + /// A real git repository, but with preprogrammed responses to network access. + /// + /// This variant is for use only in testing. Requests to methods + /// that would require network access, such as to the git remote + /// server will result in an error, unless a predefined change + /// has been scheduled for that request. + Test(TestOpenRepository), + /// A fake git repository. /// /// This variant has no on-disk presense, and only fakes some of @@ -39,14 +46,6 @@ pub enum OpenRepository { /// that instead. #[cfg(test)] Mock(git::repository::MockOpenRepository), // TODO: (#38) contain a mock model of a repo - /// A real git repository, but with preprogrammed responses to network access. - /// - /// This variant is for use only in testing. Requests to methods - /// that would require network access, such as to the git remote - /// server will result in an error, unless a predefined change - /// has been scheduled for that request. - #[cfg(test)] - Test(TestOpenRepository), } pub fn real(gix_repo: gix::Repository) -> OpenRepository { @@ -56,7 +55,6 @@ pub fn real(gix_repo: gix::Repository) -> OpenRepository { } #[cfg(not(tarpaulin_include))] // don't test mocks -#[cfg(test)] pub fn test( gitdir: &config::GitDir, fs: kxio::fs::FileSystem, @@ -67,7 +65,6 @@ pub fn test( } #[cfg(not(tarpaulin_include))] // don't test mocks -#[cfg(test)] pub fn test_bare( gitdir: &config::GitDir, fs: kxio::fs::FileSystem, @@ -111,10 +108,10 @@ impl std::ops::Deref for OpenRepository { fn deref(&self) -> &Self::Target { match self { Self::Real(real) => real, + Self::Test(test) => test, + #[cfg(test)] Self::Mock(mock) => mock, - #[cfg(test)] - Self::Test(test) => test, } } } diff --git a/crates/git/src/repository/open/otest.rs b/crates/git/src/repository/open/otest.rs index dc7b466..7720011 100644 --- a/crates/git/src/repository/open/otest.rs +++ b/crates/git/src/repository/open/otest.rs @@ -1,16 +1,13 @@ // use crate as git; -use derive_more::Constructor; +use derive_more::{Constructor, Deref}; use git_next_config as config; use std::{ - cell::Cell, path::Path, - sync::{Arc, Mutex}, + sync::{Arc, Mutex, RwLock}, }; -use assert2::let_assert; - pub type OnFetchFn = fn(&config::RepoBranches, &config::GitDir, &kxio::fs::FileSystem) -> git::fetch::Result<()>; #[derive(Clone, Debug, Constructor)] @@ -65,9 +62,9 @@ impl OnPush { #[derive(Clone, Debug)] pub struct TestOpenRepository { on_fetch: Vec, - fetch_counter: Cell, + fetch_counter: Arc>, on_push: Vec, - push_counter: Cell, + push_counter: Arc>, real: git::repository::RealOpenRepository, } impl git::repository::OpenRepositoryLike for TestOpenRepository { @@ -80,9 +77,16 @@ impl git::repository::OpenRepositoryLike for TestOpenRepository { } fn fetch(&self) -> Result<(), git::fetch::Error> { - let i = self.fetch_counter.get(); + let i: usize = *self + .fetch_counter + .read() + .map_err(|_| git::fetch::Error::Lock)? + .deref(); eprintln!("Fetch: {i}"); - self.fetch_counter.set(i + 1); + self.fetch_counter + .write() + .map_err(|_| git::fetch::Error::Lock) + .map(|mut c| *c += 1)?; self.on_fetch.get(i).map(|f| f.invoke()).unwrap_or_else(|| { unimplemented!("Unexpected fetch"); }) @@ -95,8 +99,16 @@ impl git::repository::OpenRepositoryLike for TestOpenRepository { to_commit: &git::GitRef, force: &git::push::Force, ) -> git::push::Result<()> { - let i = self.push_counter.get(); - self.push_counter.set(i + 1); + let i: usize = *self + .push_counter + .read() + .map_err(|_| git::fetch::Error::Lock)? + .deref(); + eprintln!("Push: {i}"); + self.push_counter + .write() + .map_err(|_| git::fetch::Error::Lock) + .map(|mut c| *c += 1)?; self.on_push .get(i) .map(|f| f.invoke(repo_details, branch_name, to_commit, force)) @@ -129,13 +141,14 @@ impl TestOpenRepository { on_push: Vec, ) -> Self { let pathbuf = fs.base().join(gitdir.to_path_buf()); - let_assert!(Ok(gix) = gix::init(pathbuf), "git init"); + #[allow(clippy::expect_used)] + let gix = gix::init(pathbuf).expect("git init"); Self::write_origin(gitdir, &fs); Self { on_fetch, - fetch_counter: Cell::new(0), + fetch_counter: Arc::new(RwLock::new(0)), on_push, - push_counter: Cell::new(0), + push_counter: Arc::new(RwLock::new(0)), real: git::repository::RealOpenRepository::new(Arc::new(Mutex::new(gix))), } } @@ -146,13 +159,14 @@ impl TestOpenRepository { on_push: Vec, ) -> Self { let pathbuf = fs.base().join(gitdir.to_path_buf()); - let_assert!(Ok(gix) = gix::init_bare(pathbuf), "git init bare"); + #[allow(clippy::expect_used)] + let gix = gix::init_bare(pathbuf).expect("git init bare"); Self::write_origin(gitdir, &fs); Self { on_fetch, - fetch_counter: Cell::new(0), + fetch_counter: Arc::new(RwLock::new(0)), on_push, - push_counter: Cell::new(0), + push_counter: Arc::new(RwLock::new(0)), real: git::repository::RealOpenRepository::new(Arc::new(Mutex::new(gix))), } }