Compare commits

...

3 commits

Author SHA1 Message Date
1a69067570 WIP: test: add more tests to git crate
All checks were successful
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/push-next Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful
2024-06-07 08:00:19 +01:00
7fca2f7193 WIP: refactor: create git-test crate 2024-06-07 08:00:19 +01:00
a9c263cd9c WIP: refactor: create config-test crate 2024-06-07 08:00:15 +01:00
16 changed files with 287 additions and 80 deletions

View file

@ -4,7 +4,9 @@ members = [
"crates/cli", "crates/cli",
"crates/server", "crates/server",
"crates/config", "crates/config",
"crates/config/test",
"crates/git", "crates/git",
"crates/git/test",
"crates/forge", "crates/forge",
"crates/forge-forgejo", "crates/forge-forgejo",
"crates/forge-github", "crates/forge-github",
@ -24,7 +26,9 @@ expect_used = "warn"
[workspace.dependencies] [workspace.dependencies]
git-next-server = { path = "crates/server" } git-next-server = { path = "crates/server" }
git-next-config = { path = "crates/config" } git-next-config = { path = "crates/config" }
git-next-config-test = { path = "crates/config/test" }
git-next-git = { path = "crates/git" } git-next-git = { path = "crates/git" }
git-next-git-test = { path = "crates/git/test" }
git-next-forge = { path = "crates/forge" } git-next-forge = { path = "crates/forge" }
git-next-forge-forgejo = { path = "crates/forge-forgejo" } git-next-forge-forgejo = { path = "crates/forge-forgejo" }
git-next-forge-github = { path = "crates/forge-github" } git-next-forge-github = { path = "crates/forge-github" }

View file

@ -5,4 +5,7 @@ impl BranchName {
pub fn new(str: impl Into<String>) -> Self { pub fn new(str: impl Into<String>) -> Self {
Self(str.into()) Self(str.into())
} }
pub fn into_string(self) -> String {
self.0
}
} }

View file

@ -20,6 +20,10 @@ impl GitDir {
pub const fn pathbuf(&self) -> &PathBuf { pub const fn pathbuf(&self) -> &PathBuf {
&self.0 &self.0
} }
pub fn into_string(self) -> String {
self.to_string()
}
} }
impl std::fmt::Display for GitDir { impl std::fmt::Display for GitDir {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {

View file

@ -9,7 +9,9 @@ use crate::{BranchName, GitDir, RepoBranches, RepoConfig, RepoConfigSource, Repo
)] )]
#[display("{}@{}", repo, branch)] #[display("{}@{}", repo, branch)]
pub struct ServerRepoConfig { pub struct ServerRepoConfig {
/// repo path: owner/repo
repo: String, repo: String,
/// branch name
branch: String, branch: String,
gitdir: Option<PathBuf>, gitdir: Option<PathBuf>,
main: Option<String>, main: Option<String>,

View file

@ -0,0 +1,16 @@
[package]
name = "git-next-config-test"
version = { workspace = true }
edition = { workspace = true }
[dependencies]
git-next-config = { workspace = true }
rand = { workspace = true }
kxio = { workspace = true }
[lints.clippy]
nursery = { level = "warn", priority = -1 }
# pedantic = "warn"
unwrap_used = "warn"
expect_used = "warn"

View file

@ -0,0 +1,104 @@
//
use config::{
server::Webhook, webhook::message::Body, BranchName, ForgeAlias, RepoAlias, RepoBranches,
WebhookAuth, WebhookId,
};
use git_next_config::{self as config, ForgeConfig, ForgeType, GitDir, ServerRepoConfig};
use rand::RngCore;
pub fn a_webhook_auth() -> WebhookAuth {
WebhookAuth::generate()
}
pub enum Header {
Valid(WebhookAuth, Body),
Missing,
Invalid,
}
pub fn a_webhook_message_body() -> Body {
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 {
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),
)
}

View file

@ -0,0 +1 @@
pub mod given;

View file

@ -39,6 +39,8 @@ tokio = { workspace = true }
[dev-dependencies] [dev-dependencies]
# Testing # Testing
git-next-config-test = { workspace = true }
git-next-git-test = { workspace = true }
assert2 = { workspace = true } assert2 = { workspace = true }
rand = { workspace = true } rand = { workspace = true }

View file

@ -10,8 +10,8 @@ mod forgejo {
use crate::ForgeJo; use crate::ForgeJo;
use config::{ use config::{
webhook::message::Body, ForgeAlias, ForgeConfig, ForgeType, GitDir, RepoAlias, webhook::message::Body, ForgeConfig, ForgeType, GitDir, ServerRepoConfig, WebhookAuth,
RepoBranches, ServerRepoConfig, WebhookAuth, WebhookMessage, WebhookMessage,
}; };
use git::ForgeLike as _; use git::ForgeLike as _;
@ -568,9 +568,11 @@ mod forgejo {
} }
} }
mod given { mod given {
pub use git_next_config_test::given::*;
pub use git_next_git_test::given::*;
use std::collections::HashMap; use std::collections::HashMap;
use git_next_config::{server::Webhook, WebhookId};
use kxio::network::{MockNetwork, StatusCode}; use kxio::network::{MockNetwork, StatusCode};
use rand::RngCore; use rand::RngCore;
use serde_json::json; use serde_json::json;
@ -604,10 +606,6 @@ mod forgejo {
) )
} }
pub fn a_webhook_auth() -> WebhookAuth {
WebhookAuth::generate()
}
pub enum Header { pub enum Header {
Valid(WebhookAuth), Valid(WebhookAuth),
Missing, Missing,
@ -615,6 +613,7 @@ mod forgejo {
NonUlid, NonUlid,
WrongUlid, WrongUlid,
} }
pub fn a_webhook_message(header: Header) -> WebhookMessage { pub fn a_webhook_message(header: Header) -> WebhookMessage {
WebhookMessage::new( WebhookMessage::new(
given::a_forge_alias(), given::a_forge_alias(),
@ -623,6 +622,7 @@ mod forgejo {
given::a_webhook_message_body(), given::a_webhook_message_body(),
) )
} }
pub fn webhook_headers(header: Header) -> HashMap<String, String> { pub fn webhook_headers(header: Header) -> HashMap<String, String> {
let mut headers = HashMap::new(); let mut headers = HashMap::new();
match header { match header {
@ -645,19 +645,6 @@ mod forgejo {
} }
headers 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( pub fn a_forgejo_forge(
repo_details: &git::RepoDetails, repo_details: &git::RepoDetails,
@ -665,6 +652,7 @@ mod forgejo {
) -> ForgeJo { ) -> ForgeJo {
ForgeJo::new(repo_details.clone(), net.into()) ForgeJo::new(repo_details.clone(), net.into())
} }
pub fn repo_details() -> git::RepoDetails { pub fn repo_details() -> git::RepoDetails {
git::RepoDetails::new( git::RepoDetails::new(
git::Generation::new(), git::Generation::new(),
@ -689,44 +677,6 @@ mod forgejo {
) )
} }
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 {
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())
}
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(given::a_name())
}
pub fn a_forgejo_webhook_id() -> i64 { pub fn a_forgejo_webhook_id() -> i64 {
rand::thread_rng().next_u32().into() rand::thread_rng().next_u32().into()
} }

View file

@ -53,6 +53,8 @@ actix = { workspace = true }
# #
[dev-dependencies] [dev-dependencies]
# Testing # Testing
git-next-config-test = { workspace = true }
git-next-git-test = { workspace = true }
assert2 = { workspace = true } assert2 = { workspace = true }
[lints.clippy] [lints.clippy]

View file

@ -52,6 +52,7 @@ pub mod log {
} }
impl From<String> for Error { impl From<String> for Error {
#[cfg(not(tarpaulin_include))]
fn from(e: String) -> Self { fn from(e: String) -> Self {
Self::Gix(e) Self::Gix(e)
} }

View file

@ -52,26 +52,30 @@ pub enum Error {
TryId, TryId,
} }
impl From<gix::reference::find::existing::Error> for Error { mod gix_errors {
#![cfg(not(tarpaulin_include))] // third-party library errors
use super::Error;
impl From<gix::reference::find::existing::Error> for Error {
fn from(value: gix::reference::find::existing::Error) -> Self { fn from(value: gix::reference::find::existing::Error) -> Self {
Self::FindReference(value.to_string()) Self::FindReference(value.to_string())
} }
} }
impl From<gix::object::commit::Error> for Error { impl From<gix::object::commit::Error> for Error {
fn from(value: gix::object::commit::Error) -> Self { fn from(value: gix::object::commit::Error) -> Self {
Self::NoTreeInCommit(value.to_string()) Self::NoTreeInCommit(value.to_string())
} }
} }
impl From<gix::object::find::existing::Error> for Error { impl From<gix::object::find::existing::Error> for Error {
fn from(value: gix::object::find::existing::Error) -> Self { fn from(value: gix::object::find::existing::Error) -> Self {
Self::FindObject(value.to_string()) Self::FindObject(value.to_string())
} }
} }
impl From<std::string::FromUtf8Error> for Error { impl From<std::string::FromUtf8Error> for Error {
fn from(value: std::string::FromUtf8Error) -> Self { fn from(value: std::string::FromUtf8Error) -> Self {
Self::NonUtf8Blob(value.to_string()) Self::NonUtf8Blob(value.to_string())
} }
}
} }

View file

@ -1,22 +1,36 @@
use crate as git;
mod commit { mod commit {
use crate::{commit, Commit}; use super::*;
#[test] #[test]
fn should_return_sha() { fn should_return_sha() {
let sha = commit::Sha::new("sha".to_string()); let sha = given::a_commit_sha();
let message = commit::Message::new("message".to_string()); let commit = given::a_commit_with_sha(&sha);
let commit = Commit::new(sha.clone(), message);
assert_eq!(commit.sha(), &sha); assert_eq!(commit.sha(), &sha);
} }
#[test] #[test]
fn should_return_message() { fn should_return_message() {
let sha = commit::Sha::new("sha".to_string()); let message = given::a_commit_message();
let message = commit::Message::new("message".to_string()); let commit = given::a_commit_with_message(&message);
let commit = Commit::new(sha, message.clone());
assert_eq!(commit.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 { mod generation {
use crate::Generation; use crate::Generation;
@ -160,3 +174,27 @@ 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 {
// pub use git_next_config_test::given::*;
pub use git_next_git_test::given::*;
}

View file

@ -0,0 +1,19 @@
[package]
name = "git-next-git-test"
version = { workspace = true }
edition = { workspace = true }
[dependencies]
git-next-git = { workspace = true }
git-next-config = { workspace = true }
git-next-config-test = { workspace = true }
rand = { workspace = true }
kxio = { workspace = true }
# serde_json = { workspace = true }
[lints.clippy]
nursery = { level = "warn", priority = -1 }
# pedantic = "warn"
unwrap_used = "warn"
expect_used = "warn"

View file

@ -0,0 +1,56 @@
use git_next_config as config;
use git_next_config_test::given::*;
use git_next_git::{self as git, RepoDetails};
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,
)
}

View file

@ -0,0 +1 @@
pub mod given;