From 6165b7ceeb678b0a3e168d219374834a98a39df8 Mon Sep 17 00:00:00 2001 From: Leynos Date: Tue, 29 Jul 2025 18:27:15 +0100 Subject: [PATCH 1/3] Add test helpers for config and Octocrab --- crates/comenqd/src/daemon.rs | 36 ++++++--------------- tests/cucumber.rs | 1 + tests/steps/listener_steps.rs | 8 ++--- tests/steps/worker_steps.rs | 20 +++--------- tests/util/mod.rs | 3 ++ tests/util/test_helpers.rs | 59 +++++++++++++++++++++++++++++++++++ 6 files changed, 80 insertions(+), 47 deletions(-) create mode 100644 tests/util/mod.rs create mode 100644 tests/util/test_helpers.rs diff --git a/crates/comenqd/src/daemon.rs b/crates/comenqd/src/daemon.rs index d1d2140..123f3e4 100644 --- a/crates/comenqd/src/daemon.rs +++ b/crates/comenqd/src/daemon.rs @@ -164,7 +164,11 @@ pub async fn run_worker( mod tests { //! Tests for the daemon tasks. use super::*; + mod test_helpers { + include!("../../../tests/util/test_helpers.rs"); + } use tempfile::tempdir; + use test_helpers::{octocrab_for, temp_config}; use tokio::io::AsyncWriteExt; use tokio::net::{UnixListener, UnixStream}; use tokio::sync::{mpsc, watch}; @@ -174,12 +178,9 @@ mod tests { async fn setup_run_worker(status: u16) -> (MockServer, Arc, Receiver, Arc) { let dir = tempdir().expect("tempdir"); - let cfg = Arc::new(Config { - github_token: "t".into(), - socket_path: dir.path().join("sock"), - queue_path: dir.path().join("q"), - cooldown_period_seconds: 0, - }); + let mut c = temp_config(&dir); + c.cooldown_period_seconds = 0; + let cfg = Arc::new(c); let (sender, rx) = channel(&cfg.queue_path).expect("channel"); let req = CommentRequest { owner: "o".into(), @@ -199,14 +200,7 @@ mod tests { .mount(&server) .await; - let octo = Arc::new( - Octocrab::builder() - .personal_token("t".to_string()) - .base_uri(server.uri()) - .expect("base_uri") - .build() - .expect("build octocrab"), - ); + let octo = octocrab_for(&server); (server, cfg, rx, octo) } @@ -224,12 +218,7 @@ mod tests { #[tokio::test] async fn run_creates_queue_directory() { let dir = tempdir().expect("Failed to create temporary directory"); - let cfg = Config { - github_token: "t".into(), - socket_path: dir.path().join("sock"), - queue_path: dir.path().join("q"), - cooldown_period_seconds: 1, - }; + let cfg = temp_config(&dir); assert!(!cfg.queue_path.exists()); @@ -292,12 +281,7 @@ mod tests { #[tokio::test] async fn run_listener_accepts_connections() { let dir = tempdir().expect("tempdir"); - let cfg = Arc::new(Config { - github_token: "t".into(), - socket_path: dir.path().join("sock"), - queue_path: dir.path().join("q"), - cooldown_period_seconds: 1, - }); + let cfg = Arc::new(temp_config(&dir)); let (sender, mut receiver) = channel(&cfg.queue_path).expect("channel"); let (client_tx, writer_rx) = mpsc::unbounded_channel(); diff --git a/tests/cucumber.rs b/tests/cucumber.rs index de5e190..6eb4f26 100644 --- a/tests/cucumber.rs +++ b/tests/cucumber.rs @@ -1,4 +1,5 @@ mod steps; +mod util; use cucumber::World as _; use steps::{CliWorld, ClientWorld, CommentWorld, ConfigWorld, ListenerWorld, WorkerWorld}; diff --git a/tests/steps/listener_steps.rs b/tests/steps/listener_steps.rs index 4ac9802..7c640ed 100644 --- a/tests/steps/listener_steps.rs +++ b/tests/steps/listener_steps.rs @@ -12,6 +12,7 @@ use tokio::net::UnixStream; use tokio::sync::{mpsc, watch}; use tokio::time::sleep; +use crate::util::test_helpers::temp_config; use comenq_lib::CommentRequest; use comenqd::config::Config; use comenqd::daemon::{queue_writer, run_listener}; @@ -36,12 +37,7 @@ impl std::fmt::Debug for ListenerWorld { #[given("a running listener task")] async fn running_listener(world: &mut ListenerWorld) { let dir = TempDir::new().expect("tempdir"); - let cfg = Arc::new(Config { - github_token: String::from("t"), - socket_path: dir.path().join("sock"), - queue_path: dir.path().join("q"), - cooldown_period_seconds: 1, - }); + let cfg = Arc::new(temp_config(&dir)); let (sender, receiver) = channel(&cfg.queue_path).expect("channel"); let (client_tx, writer_rx) = mpsc::unbounded_channel(); let (shutdown_tx, shutdown_rx) = watch::channel(()); diff --git a/tests/steps/worker_steps.rs b/tests/steps/worker_steps.rs index 297e466..517304a 100644 --- a/tests/steps/worker_steps.rs +++ b/tests/steps/worker_steps.rs @@ -7,11 +7,11 @@ use std::sync::Arc; use std::time::Duration; +use crate::util::test_helpers::{octocrab_for, temp_config}; use comenq_lib::CommentRequest; use comenqd::config::Config; use comenqd::daemon::run_worker; use cucumber::{World, given, then, when}; -use octocrab::Octocrab; use tempfile::TempDir; use tokio::time::sleep; use wiremock::matchers::{method, path}; @@ -36,12 +36,9 @@ impl std::fmt::Debug for WorkerWorld { #[given("a queued comment request")] async fn queued_request(world: &mut WorkerWorld) { let dir = TempDir::new().expect("tempdir"); - let cfg = Arc::new(Config { - github_token: "t".into(), - socket_path: dir.path().join("sock"), - queue_path: dir.path().join("q"), - cooldown_period_seconds: 0, - }); + let mut cfg = temp_config(&dir); + cfg.cooldown_period_seconds = 0; + let cfg = Arc::new(cfg); let (mut sender, receiver) = channel(&cfg.queue_path).expect("channel"); let req = CommentRequest { owner: "o".into(), @@ -83,14 +80,7 @@ async fn worker_runs(world: &mut WorkerWorld) { let cfg = world.cfg.as_ref().unwrap().clone(); let rx = world.receiver.take().unwrap(); let server = world.server.as_ref().unwrap(); - let octocrab = Arc::new( - Octocrab::builder() - .personal_token("t".to_string()) - .base_uri(server.uri()) - .expect("base_uri") - .build() - .expect("build octocrab"), - ); + let octocrab = octocrab_for(server); let handle = tokio::spawn(async move { let _ = run_worker(cfg, rx, octocrab).await; }); diff --git a/tests/util/mod.rs b/tests/util/mod.rs new file mode 100644 index 0000000..a5b0ca8 --- /dev/null +++ b/tests/util/mod.rs @@ -0,0 +1,3 @@ +//! Test utility modules. + +pub mod test_helpers; diff --git a/tests/util/test_helpers.rs b/tests/util/test_helpers.rs new file mode 100644 index 0000000..4927d7c --- /dev/null +++ b/tests/util/test_helpers.rs @@ -0,0 +1,59 @@ +//! Helper utilities for behavioural and unit tests. +//! +//! These functions create temporary daemon configuration objects and +//! Octocrab clients tailored for a `wiremock::MockServer`. +#![allow(clippy::expect_used, reason = "simplify test helper setup")] + +use std::sync::Arc; + +use comenqd::config::Config; +use octocrab::Octocrab; +use tempfile::TempDir; +use wiremock::MockServer; + +/// Build a temporary [`Config`] using paths under `tmp`. +/// +/// # Examples +/// +/// ``` +/// use tempfile::tempdir; +/// use comenqd::config::Config; +/// use comenq_lib::tests::util::test_helpers::temp_config; +/// +/// let dir = tempdir().unwrap(); +/// let cfg: Config = temp_config(&dir); +/// assert!(cfg.socket_path.ends_with("sock")); +/// ``` +pub fn temp_config(tmp: &TempDir) -> Config { + Config { + github_token: String::from("t"), + socket_path: tmp.path().join("sock"), + queue_path: tmp.path().join("q"), + cooldown_period_seconds: 1, + } +} + +/// Create an [`Octocrab`] instance configured for `server`. +/// +/// # Examples +/// +/// ``` +/// use wiremock::MockServer; +/// use comenq_lib::tests::util::test_helpers::octocrab_for; +/// +/// # tokio_test::block_on(async { +/// let server = MockServer::start().await; +/// let octocrab = octocrab_for(&server); +/// assert!(octocrab.base_url().as_str().contains(&server.uri())); +/// # }); +/// ``` +pub fn octocrab_for(server: &MockServer) -> Arc { + Arc::new( + Octocrab::builder() + .personal_token("t".to_string()) + .base_uri(server.uri()) + .expect("base_uri") + .build() + .expect("build octocrab"), + ) +} From dcfc26d1f5a8adeb14975b5b03175785bcefd01c Mon Sep 17 00:00:00 2001 From: Leynos Date: Fri, 1 Aug 2025 18:18:38 +0100 Subject: [PATCH 2/3] Refine test helper integration --- crates/comenqd/src/daemon.rs | 5 ++--- tests/util/test_helpers.rs | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/crates/comenqd/src/daemon.rs b/crates/comenqd/src/daemon.rs index 123f3e4..b9f729f 100644 --- a/crates/comenqd/src/daemon.rs +++ b/crates/comenqd/src/daemon.rs @@ -164,9 +164,8 @@ pub async fn run_worker( mod tests { //! Tests for the daemon tasks. use super::*; - mod test_helpers { - include!("../../../tests/util/test_helpers.rs"); - } + #[path = "../../../../../tests/util/test_helpers.rs"] + mod test_helpers; use tempfile::tempdir; use test_helpers::{octocrab_for, temp_config}; use tokio::io::AsyncWriteExt; diff --git a/tests/util/test_helpers.rs b/tests/util/test_helpers.rs index 4927d7c..8e90dcc 100644 --- a/tests/util/test_helpers.rs +++ b/tests/util/test_helpers.rs @@ -2,7 +2,6 @@ //! //! These functions create temporary daemon configuration objects and //! Octocrab clients tailored for a `wiremock::MockServer`. -#![allow(clippy::expect_used, reason = "simplify test helper setup")] use std::sync::Arc; @@ -18,7 +17,7 @@ use wiremock::MockServer; /// ``` /// use tempfile::tempdir; /// use comenqd::config::Config; -/// use comenq_lib::tests::util::test_helpers::temp_config; +/// use util::test_helpers::temp_config; /// /// let dir = tempdir().unwrap(); /// let cfg: Config = temp_config(&dir); @@ -39,7 +38,7 @@ pub fn temp_config(tmp: &TempDir) -> Config { /// /// ``` /// use wiremock::MockServer; -/// use comenq_lib::tests::util::test_helpers::octocrab_for; +/// use util::test_helpers::octocrab_for; /// /// # tokio_test::block_on(async { /// let server = MockServer::start().await; @@ -47,6 +46,7 @@ pub fn temp_config(tmp: &TempDir) -> Config { /// assert!(octocrab.base_url().as_str().contains(&server.uri())); /// # }); /// ``` +#[expect(clippy::expect_used, reason = "simplify test helper setup")] pub fn octocrab_for(server: &MockServer) -> Arc { Arc::new( Octocrab::builder() From bf93f70c022774dd62ea514674a8a07544f297f6 Mon Sep 17 00:00:00 2001 From: Leynos Date: Fri, 1 Aug 2025 18:42:10 +0100 Subject: [PATCH 3/3] Include test helpers with env path --- crates/comenqd/src/daemon.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/comenqd/src/daemon.rs b/crates/comenqd/src/daemon.rs index b9f729f..64466d6 100644 --- a/crates/comenqd/src/daemon.rs +++ b/crates/comenqd/src/daemon.rs @@ -164,8 +164,12 @@ pub async fn run_worker( mod tests { //! Tests for the daemon tasks. use super::*; - #[path = "../../../../../tests/util/test_helpers.rs"] - mod test_helpers; + mod test_helpers { + include!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/../../tests/util/test_helpers.rs" + )); + } use tempfile::tempdir; use test_helpers::{octocrab_for, temp_config}; use tokio::io::AsyncWriteExt;