feat: add tests for git setup

Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
Kasper Juul Hermansen 2023-07-29 19:23:05 +02:00
parent ff9b61ee4a
commit 5e26707e42
Signed by: kjuulh
GPG Key ID: 9AA7BC13CE474394
7 changed files with 86 additions and 19 deletions

View File

@ -9,7 +9,10 @@ use anyhow::Context;
use clap::{Args, Parser, Subcommand}; use clap::{Args, Parser, Subcommand};
use serde::{de::DeserializeOwned, Deserialize, Serialize}; use serde::{de::DeserializeOwned, Deserialize, Serialize};
use crate::ui::{ConsoleUi, DynUi}; use crate::{
git_client::VcsClient,
ui::{ConsoleUi, DynUi},
};
#[derive(Parser)] #[derive(Parser)]
#[command(author, version, about, long_about = None)] #[command(author, version, about, long_about = None)]
@ -35,7 +38,6 @@ struct GlobalArgs {
long, long,
long_help = "token is the personal access token from gitea. It requires at least repository write access, it isn't required by default, but for most usecases the flow will fail without it", long_help = "token is the personal access token from gitea. It requires at least repository write access, it isn't required by default, but for most usecases the flow will fail without it",
global = true, global = true,
group = "global",
help_heading = "Global" help_heading = "Global"
)] )]
token: Option<String>, token: Option<String>,
@ -48,11 +50,19 @@ struct GlobalArgs {
#[arg(long, global = true, group = "global", help_heading = "Global")] #[arg(long, global = true, group = "global", help_heading = "Global")]
source: Option<PathBuf>, source: Option<PathBuf>,
/// no version control system, forces please to allow no .git/ or friends
#[arg(
long,
global = true,
help_heading = "Global",
long_help = "no version control system. This forces cuddle-please to accept that it won't be running in git. All fields will have to be fed through values in the given commands."
)]
no_vcs: bool,
/// Inject configuration from stdin /// Inject configuration from stdin
#[arg( #[arg(
long, long,
global = true, global = true,
group = "global",
help_heading = "Global", help_heading = "Global",
long_help = "inject via stdin long_help = "inject via stdin
cat <<EOF | cuddle-please --config-stdin cat <<EOF | cuddle-please --config-stdin
@ -146,6 +156,8 @@ impl Command {
// 2. Parse the cuddle.please.yaml let cuddle.please.yaml take precedence // 2. Parse the cuddle.please.yaml let cuddle.please.yaml take precedence
// 2a. if not existing use default. // 2a. if not existing use default.
// 2b. if not in a git repo abort. (unless --no-vcs is turned added) // 2b. if not in a git repo abort. (unless --no-vcs is turned added)
let _config = self.get_config(&current_dir, stdin)?;
let git_client = self.get_git(&current_dir)?;
// 3. Create gitea client and do a health check // 3. Create gitea client and do a health check
// 4. Fetch git tags for the current repository // 4. Fetch git tags for the current repository
@ -166,6 +178,14 @@ impl Command {
Ok(()) Ok(())
} }
fn get_git(&self, current_dir: &PathBuf) -> anyhow::Result<VcsClient> {
if self.global.no_vcs {
Ok(VcsClient::new_noop())
} else {
VcsClient::new_git(current_dir)
}
}
} }
#[derive(Debug, Clone, Subcommand)] #[derive(Debug, Clone, Subcommand)]

View File

@ -0,0 +1,22 @@
use std::path::{Path, PathBuf};
#[derive(Clone, Debug, PartialEq)]
pub enum VcsClient {
Noop {},
Git { source: PathBuf },
}
impl VcsClient {
pub fn new_noop() -> VcsClient {
Self::Noop {}
}
pub fn new_git(path: &Path) -> anyhow::Result<VcsClient> {
if !path.to_path_buf().join(".git").exists() {
anyhow::bail!("git directory not found in: {}", path.display().to_string())
}
Ok(Self::Git {
source: path.to_path_buf(),
})
}
}

View File

@ -1,2 +1,3 @@
pub mod command; pub mod command;
pub mod git_client;
pub mod ui; pub mod ui;

View File

@ -1,7 +1,9 @@
pub mod command; pub mod command;
pub mod git_client;
pub mod ui; pub mod ui;
use command::Command; use command::Command;
use ui::ConsoleUi;
#[tokio::main] #[tokio::main]
async fn main() -> anyhow::Result<()> { async fn main() -> anyhow::Result<()> {

View File

@ -2,6 +2,7 @@ use cuddle_please::ui::{DynUi, Ui};
use std::{ use std::{
io::Write, io::Write,
path::PathBuf,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
@ -111,3 +112,17 @@ impl From<&BufferUi> for DynUi {
value.clone().into() value.clone().into()
} }
} }
pub fn assert_output(ui: &BufferUi, expected_stdout: &str, expected_stderr: &str) {
let (stdout, stderr) = ui.get_output();
assert_eq!(expected_stdout, &stdout);
assert_eq!(expected_stderr, &stderr);
}
pub fn get_test_data_path(item: &str) -> PathBuf {
std::env::current_dir()
.ok()
.map(|p| p.join("testdata").join(item))
.unwrap()
}

View File

@ -1,29 +1,15 @@
pub mod common; pub mod common;
use std::path::PathBuf;
use common::BufferUi; use common::BufferUi;
use cuddle_please::command::Command; use cuddle_please::command::Command;
use tracing_test::traced_test; use tracing_test::traced_test;
use crate::common::{assert_output, get_test_data_path};
fn get_base_args<'a>() -> Vec<&'a str> { fn get_base_args<'a>() -> Vec<&'a str> {
vec!["cuddle-please", "config", "list"] vec!["cuddle-please", "config", "list"]
} }
fn assert_output(ui: &BufferUi, expected_stdout: &str, expected_stderr: &str) {
let (stdout, stderr) = ui.get_output();
assert_eq!(expected_stdout, &stdout);
assert_eq!(expected_stderr, &stderr);
}
fn get_test_data_path(item: &str) -> PathBuf {
std::env::current_dir()
.ok()
.map(|p| p.join("testdata").join(item))
.unwrap()
}
#[test] #[test]
#[traced_test] #[traced_test]
fn test_config_from_current_dir() { fn test_config_from_current_dir() {

View File

@ -0,0 +1,21 @@
pub mod common;
use cuddle_please::git_client::VcsClient;
use tracing_test::traced_test;
use crate::common::get_test_data_path;
#[test]
#[traced_test]
fn test_vcs_get_noop() {
let noop = VcsClient::new_noop();
assert!(matches!(noop, VcsClient::Noop {}));
}
#[test]
#[traced_test]
fn test_vcs_get_git_found() {
let testdata = get_test_data_path("git-found");
let git = VcsClient::new_git(&testdata).unwrap();
assert_eq!(git, VcsClient::Git { source: testdata })
}