diff --git a/crates/config/src/branch_name.rs b/crates/config/src/branch_name.rs index 70df7c6..5086151 100644 --- a/crates/config/src/branch_name.rs +++ b/crates/config/src/branch_name.rs @@ -5,4 +5,7 @@ impl BranchName { pub fn new(str: impl Into) -> Self { Self(str.into()) } + pub fn into_string(self) -> String { + self.0 + } } diff --git a/crates/config/src/git_dir.rs b/crates/config/src/git_dir.rs index f27596d..57c0cc4 100644 --- a/crates/config/src/git_dir.rs +++ b/crates/config/src/git_dir.rs @@ -20,6 +20,10 @@ impl GitDir { pub const fn pathbuf(&self) -> &PathBuf { &self.0 } + + pub fn into_string(self) -> String { + self.to_string() + } } impl std::fmt::Display for GitDir { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { diff --git a/crates/forge-forgejo/src/tests.rs b/crates/forge-forgejo/src/tests.rs index 881e0bf..6ad6f7f 100644 --- a/crates/forge-forgejo/src/tests.rs +++ b/crates/forge-forgejo/src/tests.rs @@ -6,18 +6,14 @@ mod forgejo { use super::*; use assert2::let_assert; - use std::collections::BTreeMap; use crate::ForgeJo; - use config::{ - webhook::message::Body, ForgeAlias, ForgeConfig, ForgeType, GitDir, RepoAlias, - RepoBranches, ServerRepoConfig, WebhookAuth, WebhookMessage, - }; use git::ForgeLike as _; #[test] fn should_return_name() { - let forge = given::a_forgejo_forge(&given::repo_details(), given::a_network()); + let fs = given::a_filesystem(); + let forge = given::a_forgejo_forge(&given::repo_details(&fs), given::a_network()); assert_eq!(forge.name(), "forgejo"); } @@ -27,35 +23,40 @@ mod forgejo { #[test] fn should_return_true_with_valid_header() { - let forge = given::a_forgejo_forge(&given::repo_details(), given::a_network()); + let fs = given::a_filesystem(); + let forge = given::a_forgejo_forge(&given::repo_details(&fs), given::a_network()); let auth = given::a_webhook_auth(); let message = given::a_webhook_message(given::Header::Valid(auth.clone())); assert!(forge.is_message_authorised(&message, &auth)); } #[test] fn should_return_false_with_missing_header() { - let forge = given::a_forgejo_forge(&given::repo_details(), given::a_network()); + let fs = given::a_filesystem(); + let forge = given::a_forgejo_forge(&given::repo_details(&fs), given::a_network()); let auth = given::a_webhook_auth(); let message = given::a_webhook_message(given::Header::Missing); assert!(!forge.is_message_authorised(&message, &auth)); } #[test] fn should_return_false_with_non_basic_prefix() { - let forge = given::a_forgejo_forge(&given::repo_details(), given::a_network()); + let fs = given::a_filesystem(); + let forge = given::a_forgejo_forge(&given::repo_details(&fs), given::a_network()); let auth = given::a_webhook_auth(); let message = given::a_webhook_message(given::Header::NonBasic); assert!(!forge.is_message_authorised(&message, &auth)); } #[test] fn should_return_false_with_non_ulid_value() { - let forge = given::a_forgejo_forge(&given::repo_details(), given::a_network()); + let fs = given::a_filesystem(); + let forge = given::a_forgejo_forge(&given::repo_details(&fs), given::a_network()); let auth = given::a_webhook_auth(); let message = given::a_webhook_message(given::Header::NonUlid); assert!(!forge.is_message_authorised(&message, &auth)); } #[test] fn should_return_false_with_wrong_ulid_value() { - let forge = given::a_forgejo_forge(&given::repo_details(), given::a_network()); + let fs = given::a_filesystem(); + let forge = given::a_forgejo_forge(&given::repo_details(&fs), given::a_network()); let auth = given::a_webhook_auth(); let message = given::a_webhook_message(given::Header::WrongUlid); assert!(!forge.is_message_authorised(&message, &auth)); @@ -70,12 +71,13 @@ mod forgejo { #[test] fn should_parse_valid_body() { - let forge = given::a_forgejo_forge(&given::repo_details(), given::a_network()); + let fs = given::a_filesystem(); + let forge = given::a_forgejo_forge(&given::repo_details(&fs), given::a_network()); let repo_branches = given::repo_branches(); let next = repo_branches.next(); let sha = given::a_name(); let message = given::a_name(); - let body = Body::new( + let body = config::webhook::message::Body::new( json!({"ref":format!("refs/heads/{next}"),"after":sha,"head_commit":{"message":message}}) .to_string(), ); @@ -90,8 +92,9 @@ mod forgejo { #[test] fn should_error_invalid_body() { - let forge = given::a_forgejo_forge(&given::repo_details(), given::a_network()); - let body = Body::new(r#"{"type":"invalid"}"#.to_string()); + let fs = given::a_filesystem(); + let forge = given::a_forgejo_forge(&given::repo_details(&fs), given::a_network()); + let body = config::webhook::message::Body::new(r#"{"type":"invalid"}"#.to_string()); let_assert!(Err(_) = forge.parse_webhook_body(&body)); } } @@ -104,7 +107,8 @@ mod forgejo { #[tokio::test] async fn should_return_pass_for_success() { - let repo_details = given::repo_details(); + let fs = given::a_filesystem(); + let repo_details = given::repo_details(&fs); let commit = given::a_commit(); let mut net = given::a_network(); given::a_commit_state("success", &mut net, &repo_details, &commit); @@ -113,7 +117,8 @@ mod forgejo { } #[tokio::test] async fn should_return_pending_for_pending() { - let repo_details = given::repo_details(); + let fs = given::a_filesystem(); + let repo_details = given::repo_details(&fs); let commit = given::a_commit(); let mut net = given::a_network(); given::a_commit_state("pending", &mut net, &repo_details, &commit); @@ -122,7 +127,8 @@ mod forgejo { } #[tokio::test] async fn should_return_fail_for_failure() { - let repo_details = given::repo_details(); + let fs = given::a_filesystem(); + let repo_details = given::repo_details(&fs); let commit = given::a_commit(); let mut net = given::a_network(); given::a_commit_state("failure", &mut net, &repo_details, &commit); @@ -131,7 +137,8 @@ mod forgejo { } #[tokio::test] async fn should_return_fail_for_error() { - let repo_details = given::repo_details(); + let fs = given::a_filesystem(); + let repo_details = given::repo_details(&fs); let commit = given::a_commit(); let mut net = given::a_network(); given::a_commit_state("error", &mut net, &repo_details, &commit); @@ -140,7 +147,8 @@ mod forgejo { } #[tokio::test] async fn should_return_pending_for_blank() { - let repo_details = given::repo_details(); + let fs = given::a_filesystem(); + let repo_details = given::repo_details(&fs); let commit = given::a_commit(); let mut net = given::a_network(); given::a_commit_state("", &mut net, &repo_details, &commit); @@ -149,7 +157,8 @@ mod forgejo { } #[tokio::test] async fn should_return_pending_for_no_statuses() { - let repo_details = given::repo_details(); + let fs = given::a_filesystem(); + let repo_details = given::repo_details(&fs); let commit = given::a_commit(); let mut net = given::a_network(); net.add_get_response( @@ -162,14 +171,15 @@ mod forgejo { } #[tokio::test] async fn should_return_pending_for_network_error() { - let repo_details = given::repo_details(); + let fs = given::a_filesystem(); + let repo_details = given::repo_details(&fs); let commit = given::a_commit(); let mut net = given::a_network(); net.add_get_error( &given::a_commit_status_url(&repo_details, &commit), "boom today", ); - let forge = given::a_forgejo_forge(&given::repo_details(), net); + let forge = given::a_forgejo_forge(&repo_details, net); assert_eq!(forge.commit_status(&commit).await, Status::Pending); } } @@ -184,7 +194,8 @@ mod forgejo { #[tokio::test] async fn should_return_a_list_of_matching_webhooks() { - let repo_details = given::repo_details(); + let fs = given::a_filesystem(); + let repo_details = given::repo_details(&fs); let webhook_url = given::any_webhook_url(); let hostname = repo_details.forge.hostname(); let repo_path = &repo_details.repo_path; @@ -228,7 +239,8 @@ mod forgejo { #[tokio::test] async fn should_return_any_network_error() { - let repo_details = given::repo_details(); + let fs = given::a_filesystem(); + let repo_details = given::repo_details(&fs); let webhook_url = given::a_webhook_url(&given::a_forge_alias(), &given::a_repo_alias()); let hostname = repo_details.forge.hostname(); let repo_path = &repo_details.repo_path; @@ -255,7 +267,8 @@ mod forgejo { #[tokio::test] async fn should_delete_webhook() { - let repo_details = given::repo_details(); + let fs = given::a_filesystem(); + let repo_details = given::repo_details(&fs); let hostname = repo_details.forge.hostname(); let repo_path = &repo_details.repo_path; use secrecy::ExposeSecret; @@ -279,7 +292,8 @@ mod forgejo { #[tokio::test] async fn should_return_error_on_network_error() { - let repo_details = given::repo_details(); + let fs = given::a_filesystem(); + let repo_details = given::repo_details(&fs); let hostname = repo_details.forge.hostname(); let repo_path = &repo_details.repo_path; use secrecy::ExposeSecret; @@ -316,7 +330,8 @@ mod forgejo { #[tokio::test] async fn should_register_a_new_webhook() { - let repo_details = given::repo_details(); + let fs = given::a_filesystem(); + let repo_details = given::repo_details(&fs); assert!( repo_details.repo_config.is_some(), "repo_details needs to have repo_config for this test" @@ -357,7 +372,8 @@ mod forgejo { #[tokio::test] async fn should_abort_if_repo_config_missing() { - let mut repo_details = given::repo_details(); + let fs = given::a_filesystem(); + let mut repo_details = given::repo_details(&fs); repo_details.repo_config.take(); assert!( repo_details.repo_config.is_none(), @@ -376,7 +392,8 @@ mod forgejo { #[tokio::test] async fn should_unregister_existing_webhooks_before_registering() { - let repo_details = given::repo_details(); + let fs = given::a_filesystem(); + let repo_details = given::repo_details(&fs); assert!( repo_details.repo_config.is_some(), "repo_details needs to have repo_config for this test" @@ -428,7 +445,8 @@ mod forgejo { #[tokio::test] async fn should_return_error_if_empty_network_response() { - let repo_details = given::repo_details(); + let fs = given::a_filesystem(); + let repo_details = given::repo_details(&fs); assert!( repo_details.repo_config.is_some(), "repo_details needs to have repo_config for this test" @@ -468,7 +486,8 @@ mod forgejo { #[tokio::test] async fn should_return_error_on_network_error() { - let repo_details = given::repo_details(); + let fs = given::a_filesystem(); + let repo_details = given::repo_details(&fs); assert!( repo_details.repo_config.is_some(), "repo_details needs to have repo_config for this test" @@ -568,11 +587,11 @@ mod forgejo { } } mod given { + #![allow(dead_code)] + use std::collections::HashMap; - use git_next_config::{server::Webhook, WebhookId}; use kxio::network::{MockNetwork, StatusCode}; - use rand::RngCore; use serde_json::json; use super::*; @@ -604,25 +623,23 @@ mod forgejo { ) } - pub fn a_webhook_auth() -> WebhookAuth { - WebhookAuth::generate() - } - pub enum Header { - Valid(WebhookAuth), + Valid(config::WebhookAuth), Missing, NonBasic, NonUlid, WrongUlid, } - pub fn a_webhook_message(header: Header) -> WebhookMessage { - WebhookMessage::new( + + pub fn a_webhook_message(header: Header) -> config::WebhookMessage { + config::WebhookMessage::new( given::a_forge_alias(), given::a_repo_alias(), given::webhook_headers(header), given::a_webhook_message_body(), ) } + pub fn webhook_headers(header: Header) -> HashMap { let mut headers = HashMap::new(); match header { @@ -639,25 +656,12 @@ mod forgejo { Header::WrongUlid => { headers.insert( "authorization".to_string(), - format!("Basic {}", WebhookAuth::generate()), + format!("Basic {}", config::WebhookAuth::generate()), ); } } headers } - pub fn a_webhook_message_body() -> Body { - Body::new(a_name()) - } - pub fn a_commit() -> git::Commit { - git::Commit::new( - git::commit::Sha::new(a_name()), - git::commit::Message::new(a_name()), - ) - } - - pub fn repo_branches() -> RepoBranches { - RepoBranches::new(a_name(), a_name(), a_name()) - } pub fn a_forgejo_forge( repo_details: &git::RepoDetails, @@ -665,49 +669,45 @@ mod forgejo { ) -> ForgeJo { ForgeJo::new(repo_details.clone(), net.into()) } - pub fn repo_details() -> git::RepoDetails { - git::RepoDetails::new( - git::Generation::new(), - &a_repo_alias(), - &ServerRepoConfig::new( - format!("{}/{}", a_name(), a_name()), // repo path: owner/repo - a_name(), - None, - Some(a_name()), - Some(a_name()), - Some(a_name()), - ), - &a_forge_alias(), - &ForgeConfig::new( - ForgeType::ForgeJo, - a_name(), - a_name(), - a_name(), - BTreeMap::default(), - ), - GitDir::default(), - ) + + pub fn a_forgejo_webhook_id() -> i64 { + use rand::RngCore as _; + rand::thread_rng().next_u32().into() } - pub fn a_forge_alias() -> ForgeAlias { - ForgeAlias::new(a_name()) + pub fn a_webhook_auth() -> config::WebhookAuth { + config::WebhookAuth::generate() } - pub fn a_repo_alias() -> RepoAlias { - RepoAlias::new(a_name()) + pub fn a_webhook_message_body() -> config::webhook::message::Body { + config::webhook::message::Body::new(a_name()) } + + pub fn repo_branches() -> config::RepoBranches { + config::RepoBranches::new(a_name(), a_name(), a_name()) + } + + pub fn a_forge_alias() -> config::ForgeAlias { + config::ForgeAlias::new(a_name()) + } + + pub fn a_repo_alias() -> config::RepoAlias { + config::RepoAlias::new(a_name()) + } + pub fn a_network() -> kxio::network::MockNetwork { kxio::network::MockNetwork::new() } pub fn a_webhook_url( - forge_alias: &ForgeAlias, - repo_alias: &RepoAlias, + forge_alias: &config::ForgeAlias, + repo_alias: &config::RepoAlias, ) -> git_next_config::server::WebhookUrl { - Webhook::new(a_name()).url(forge_alias, repo_alias) + config::server::Webhook::new(a_name()).url(forge_alias, repo_alias) } + pub fn any_webhook_url() -> git_next_config::server::WebhookUrl { - given::a_webhook_url(&given::a_forge_alias(), &given::a_repo_alias()) + a_webhook_url(&a_forge_alias(), &a_repo_alias()) } pub fn a_name() -> String { @@ -723,12 +723,103 @@ mod forgejo { generate(5) } - pub fn a_webhook_id() -> WebhookId { - WebhookId::new(given::a_name()) + pub fn a_webhook_id() -> config::WebhookId { + config::WebhookId::new(a_name()) } - pub fn a_forgejo_webhook_id() -> i64 { + pub fn a_github_webhook_id() -> i64 { + use rand::RngCore as _; rand::thread_rng().next_u32().into() } + + pub fn a_branch_name() -> config::BranchName { + config::BranchName::new(a_name()) + } + + pub fn a_git_dir(fs: &kxio::fs::FileSystem) -> config::GitDir { + let dir_name = a_name(); + let dir = fs.base().join(dir_name); + config::GitDir::new(&dir) + } + + pub fn a_forge_config() -> config::ForgeConfig { + config::ForgeConfig::new( + config::ForgeType::MockForge, + a_name(), + a_name(), + a_name(), + Default::default(), // no repos + ) + } + + pub fn a_server_repo_config() -> config::ServerRepoConfig { + let main = a_branch_name().into_string(); + let next = a_branch_name().into_string(); + let dev = a_branch_name().into_string(); + config::ServerRepoConfig::new( + format!("{}/{}", a_name(), a_name()), + main.clone(), + None, + Some(main), + Some(next), + Some(dev), + ) + } + + pub fn a_commit() -> git::Commit { + git::Commit::new(a_commit_sha(), a_commit_message()) + } + + pub fn a_commit_with_message(message: &git::commit::Message) -> git::Commit { + git::Commit::new(a_commit_sha(), message.to_owned()) + } + + pub fn a_commit_with_sha(sha: &git::commit::Sha) -> git::Commit { + git::Commit::new(sha.to_owned(), a_commit_message()) + } + + pub fn a_commit_with( + sha: &git::commit::Sha, + message: &git::commit::Message, + ) -> git::Commit { + git::Commit::new(sha.to_owned(), message.to_owned()) + } + + pub fn a_commit_message() -> git::commit::Message { + git::commit::Message::new(a_name()) + } + + pub fn a_commit_sha() -> git::commit::Sha { + git::commit::Sha::new(a_name()) + } + + pub fn a_webhook_push( + sha: &git::commit::Sha, + message: &git::commit::Message, + ) -> config::webhook::Push { + let branch = a_branch_name(); + config::webhook::Push::new(branch, sha.to_string(), message.to_string()) + } + + pub fn a_filesystem() -> kxio::fs::FileSystem { + kxio::fs::temp().unwrap_or_else(|e| panic!("{}", e)) + } + + pub fn repo_details(fs: &kxio::fs::FileSystem) -> git::RepoDetails { + let generation = git::Generation::new(); + let repo_alias = a_repo_alias(); + let server_repo_config = a_server_repo_config(); + let forge_alias = a_forge_alias(); + let forge_config = a_forge_config(); + let gitdir = a_git_dir(fs); + git::RepoDetails::new( + generation, + &repo_alias, + &server_repo_config, + &forge_alias, + &forge_config, + gitdir, + ) + } } } diff --git a/crates/git/Cargo.toml b/crates/git/Cargo.toml index c34de0b..21df2be 100644 --- a/crates/git/Cargo.toml +++ b/crates/git/Cargo.toml @@ -54,6 +54,7 @@ actix = { workspace = true } [dev-dependencies] # Testing assert2 = { workspace = true } +rand = { workspace = true } [lints.clippy] nursery = { level = "warn", priority = -1 } diff --git a/crates/git/src/commit.rs b/crates/git/src/commit.rs index 8948d7f..fcbb3f4 100644 --- a/crates/git/src/commit.rs +++ b/crates/git/src/commit.rs @@ -52,6 +52,7 @@ pub mod log { } impl From for Error { + #[cfg(not(tarpaulin_include))] fn from(e: String) -> Self { Self::Gix(e) } diff --git a/crates/git/src/file.rs b/crates/git/src/file.rs index c545d7e..34be9d0 100644 --- a/crates/git/src/file.rs +++ b/crates/git/src/file.rs @@ -52,26 +52,30 @@ pub enum Error { TryId, } -impl From for Error { - fn from(value: gix::reference::find::existing::Error) -> Self { - Self::FindReference(value.to_string()) +mod gix_errors { + #![cfg(not(tarpaulin_include))] // third-party library errors + use super::Error; + impl From for Error { + fn from(value: gix::reference::find::existing::Error) -> Self { + Self::FindReference(value.to_string()) + } } -} -impl From for Error { - fn from(value: gix::object::commit::Error) -> Self { - Self::NoTreeInCommit(value.to_string()) + impl From for Error { + fn from(value: gix::object::commit::Error) -> Self { + Self::NoTreeInCommit(value.to_string()) + } } -} -impl From for Error { - fn from(value: gix::object::find::existing::Error) -> Self { - Self::FindObject(value.to_string()) + impl From for Error { + fn from(value: gix::object::find::existing::Error) -> Self { + Self::FindObject(value.to_string()) + } } -} -impl From for Error { - fn from(value: std::string::FromUtf8Error) -> Self { - Self::NonUtf8Blob(value.to_string()) + impl From for Error { + fn from(value: std::string::FromUtf8Error) -> Self { + Self::NonUtf8Blob(value.to_string()) + } } } diff --git a/crates/git/src/tests.rs b/crates/git/src/tests.rs index 12674f7..89321ec 100644 --- a/crates/git/src/tests.rs +++ b/crates/git/src/tests.rs @@ -1,22 +1,36 @@ +use crate as git; + mod commit { - use crate::{commit, Commit}; + use super::*; #[test] fn should_return_sha() { - let sha = commit::Sha::new("sha".to_string()); - let message = commit::Message::new("message".to_string()); - let commit = Commit::new(sha.clone(), message); + let sha = given::a_commit_sha(); + let commit = given::a_commit_with_sha(&sha); assert_eq!(commit.sha(), &sha); } #[test] fn should_return_message() { - let sha = commit::Sha::new("sha".to_string()); - let message = commit::Message::new("message".to_string()); - let commit = Commit::new(sha, message.clone()); + let message = given::a_commit_message(); + let commit = given::a_commit_with_message(&message); assert_eq!(commit.message(), &message); } + #[test] + fn should_convert_from_push() { + let sha = given::a_commit_sha(); + let message = given::a_commit_message(); + let push = given::a_webhook_push(&sha, &message); + let commit = git::Commit::from(push); + + let expected = git::Commit::new( + git::commit::Sha::new(sha.to_string()), + git::commit::Message::new(message.to_string()), + ); + + assert_eq!(commit, expected); + } } mod generation { use crate::Generation; @@ -160,3 +174,186 @@ mod repo_details { ); } } +// mod branch { +// use super::*; +// use assert2::let_assert; +// #[test] +// fn reset_should_fetch_then_push() { +// // let repository = given::a_mock_open_repository(); +// let fs = given::a_filesystem(); +// let repo_detauls = given::repo_details(&fs); +// let repository = given::a_mock_open_repository(); +// let_assert!( +// Ok(result) = git::branch::reset( +// repository, +// &repo_details, +// &repo_details.branch, +// git_ref, +// force +// ) +// ); +// } +// } +mod given { + #![allow(dead_code)] + // + use crate as git; + use config::{ + BranchName, ForgeAlias, ForgeConfig, ForgeType, GitDir, RepoAlias, RepoBranches, + ServerRepoConfig, WebhookAuth, WebhookId, + }; + use git_next_config as config; + + use rand::RngCore; + + use crate::RepoDetails; + + pub fn a_webhook_auth() -> WebhookAuth { + WebhookAuth::generate() + } + + pub enum Header { + Valid(WebhookAuth, config::webhook::message::Body), + Missing, + Invalid, + } + + pub fn a_webhook_message_body() -> config::webhook::message::Body { + config::webhook::message::Body::new(a_name()) + } + + pub fn repo_branches() -> RepoBranches { + RepoBranches::new(a_name(), a_name(), a_name()) + } + + pub fn a_forge_alias() -> ForgeAlias { + ForgeAlias::new(a_name()) + } + + pub fn a_repo_alias() -> RepoAlias { + RepoAlias::new(a_name()) + } + + pub fn a_network() -> kxio::network::MockNetwork { + kxio::network::MockNetwork::new() + } + + pub fn a_webhook_url( + forge_alias: &ForgeAlias, + repo_alias: &RepoAlias, + ) -> git_next_config::server::WebhookUrl { + config::server::Webhook::new(a_name()).url(forge_alias, repo_alias) + } + + pub fn any_webhook_url() -> git_next_config::server::WebhookUrl { + a_webhook_url(&a_forge_alias(), &a_repo_alias()) + } + + pub fn a_name() -> String { + use rand::Rng; + use std::iter; + + fn generate(len: usize) -> String { + const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + let mut rng = rand::thread_rng(); + let one_char = || CHARSET[rng.gen_range(0..CHARSET.len())] as char; + iter::repeat_with(one_char).take(len).collect() + } + generate(5) + } + + pub fn a_webhook_id() -> WebhookId { + WebhookId::new(a_name()) + } + + pub fn a_github_webhook_id() -> i64 { + rand::thread_rng().next_u32().into() + } + + pub fn a_branch_name() -> BranchName { + BranchName::new(a_name()) + } + + pub fn a_git_dir(fs: &kxio::fs::FileSystem) -> GitDir { + let dir_name = a_name(); + let dir = fs.base().join(dir_name); + GitDir::new(&dir) + } + + pub fn a_forge_config() -> ForgeConfig { + ForgeConfig::new( + ForgeType::MockForge, + a_name(), + a_name(), + a_name(), + Default::default(), // no repos + ) + } + + pub fn a_server_repo_config() -> ServerRepoConfig { + let main = a_branch_name().into_string(); + let next = a_branch_name().into_string(); + let dev = a_branch_name().into_string(); + ServerRepoConfig::new( + format!("{}/{}", a_name(), a_name()), + main.clone(), + None, + Some(main), + Some(next), + Some(dev), + ) + } + + pub fn a_commit() -> git::Commit { + git::Commit::new(a_commit_sha(), a_commit_message()) + } + + pub fn a_commit_with_message(message: &git::commit::Message) -> git::Commit { + git::Commit::new(a_commit_sha(), message.to_owned()) + } + + pub fn a_commit_with_sha(sha: &git::commit::Sha) -> git::Commit { + git::Commit::new(sha.to_owned(), a_commit_message()) + } + + pub fn a_commit_with(sha: &git::commit::Sha, message: &git::commit::Message) -> git::Commit { + git::Commit::new(sha.to_owned(), message.to_owned()) + } + + pub fn a_commit_message() -> git::commit::Message { + git::commit::Message::new(a_name()) + } + + pub fn a_commit_sha() -> git::commit::Sha { + git::commit::Sha::new(a_name()) + } + + pub fn a_webhook_push( + sha: &git::commit::Sha, + message: &git::commit::Message, + ) -> config::webhook::Push { + let branch = a_branch_name(); + config::webhook::Push::new(branch, sha.to_string(), message.to_string()) + } + + pub fn a_filesystem() -> kxio::fs::FileSystem { + kxio::fs::temp().unwrap_or_else(|e| panic!("{}", e)) + } + + pub fn repo_details(fs: &kxio::fs::FileSystem) -> git::RepoDetails { + let generation = git::Generation::new(); + let repo_alias = a_repo_alias(); + let server_repo_config = a_server_repo_config(); + let forge_alias = a_forge_alias(); + let forge_config = a_forge_config(); + let gitdir = a_git_dir(fs); + RepoDetails::new( + generation, + &repo_alias, + &server_repo_config, + &forge_alias, + &forge_config, + gitdir, + ) + } +}