summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDawid Rycerz <dawid@rycerz.xyz>2025-07-30 19:32:16 +0300
committerDawid Rycerz <dawid@rycerz.xyz>2025-07-30 19:32:16 +0300
commit48296403cf7d911c73dcff9dc49082931c61db63 (patch)
tree3550978c8c14736c3cfcaf011c81831e25c541cb /src
parent228879a2c390e08c227b7b1b2a5f44e1c34bf4e3 (diff)
feat: make tests parallel friendly
Diffstat (limited to 'src')
-rw-r--r--src/config.rs148
1 files changed, 63 insertions, 85 deletions
diff --git a/src/config.rs b/src/config.rs
index 49bd995..04bd94a 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -14,15 +14,26 @@ pub struct Config {
impl Config {
pub fn from_env() -> Self {
- let database_url = Self::get_database_url();
- let openweathermap_api_key = env::var("OPENWEATHERMAP_API_KEY").ok();
- let admin_token = env::var("ADMIN_TOKEN").ok();
- let server_port = env::var("PORT")
- .unwrap_or_else(|_| "4000".to_string())
+ Self::from_env_vars(&env::vars().collect::<Vec<_>>())
+ }
+
+ pub fn from_env_vars(env_vars: &[(String, String)]) -> Self {
+ let get_env = |key: &str| {
+ env_vars
+ .iter()
+ .find(|(k, _)| k == key)
+ .map(|(_, v)| v.clone())
+ };
+
+ let database_url = Self::get_database_url_from_env_vars(env_vars);
+ let openweathermap_api_key = get_env("OPENWEATHERMAP_API_KEY");
+ let admin_token = get_env("ADMIN_TOKEN");
+ let server_port = get_env("PORT")
+ .unwrap_or_else(|| "4000".to_string())
.parse()
.unwrap_or(4000);
- let server_host = env::var("HOST").unwrap_or_else(|_| "0.0.0.0".to_string());
- let log_level = env::var("LOG_LEVEL").unwrap_or_else(|_| "info".to_string());
+ let server_host = get_env("HOST").unwrap_or_else(|| "0.0.0.0".to_string());
+ let log_level = get_env("LOG_LEVEL").unwrap_or_else(|| "info".to_string());
Self {
database_url,
@@ -34,19 +45,25 @@ impl Config {
}
}
- fn get_database_url() -> String {
+ fn get_database_url_from_env_vars(env_vars: &[(String, String)]) -> String {
+ let get_env = |key: &str| {
+ env_vars
+ .iter()
+ .find(|(k, _)| k == key)
+ .map(|(_, v)| v.clone())
+ };
+
// First, check if DATABASE_URL is explicitly set
- if let Ok(url) = env::var("DATABASE_URL") {
+ if let Some(url) = get_env("DATABASE_URL") {
return url;
}
// If not set, construct the path using XDG_DATA_HOME or fallback
- let data_dir = if let Ok(xdg_data_home) = env::var("XDG_DATA_HOME") {
+ let data_dir = if let Some(xdg_data_home) = get_env("XDG_DATA_HOME") {
PathBuf::from(xdg_data_home)
} else {
// Fallback to ~/.local/share
- let home = env::var("HOME")
- .unwrap_or_else(|_| env::var("USERPROFILE").unwrap_or_else(|_| "/tmp".to_string()));
+ let home = get_env("HOME").unwrap_or_else(|| "/tmp".to_string());
PathBuf::from(home).join(".local").join("share")
};
@@ -79,105 +96,66 @@ impl Config {
#[cfg(test)]
mod tests {
use super::*;
- use std::env;
- use std::sync::OnceLock;
- use std::sync::{Mutex, Once};
-
- static INIT: Once = Once::new();
- static TEST_MUTEX: OnceLock<Mutex<()>> = OnceLock::new();
-
- fn setup() {
- INIT.call_once(|| {
- // Clear all environment variables that might interfere with tests
- unsafe {
- env::remove_var("DATABASE_URL");
- env::remove_var("XDG_DATA_HOME");
- env::remove_var("PORT");
- env::remove_var("HOST");
- env::remove_var("LOG_LEVEL");
- }
- });
-
- // Get the test mutex to ensure sequential execution
- let _guard = TEST_MUTEX.get_or_init(|| Mutex::new(())).lock().unwrap();
-
- // Clear environment variables before each test
- unsafe {
- env::remove_var("DATABASE_URL");
- env::remove_var("XDG_DATA_HOME");
- env::remove_var("PORT");
- env::remove_var("HOST");
- env::remove_var("LOG_LEVEL");
- }
- }
#[test]
fn test_database_url_fallback() {
- setup();
+ let env_vars = vec![("HOME".to_string(), "/home/testuser".to_string())];
- let home = env::var("HOME").unwrap_or_else(|_| "/tmp".to_string());
- let expected_path = format!("sqlite:{home}/.local/share/silmataivas/silmataivas.db");
-
- let config = Config::from_env();
+ let config = Config::from_env_vars(&env_vars);
+ let expected_path = "sqlite:/home/testuser/.local/share/silmataivas/silmataivas.db";
assert_eq!(config.database_url, expected_path);
}
#[test]
fn test_database_url_xdg_data_home() {
- setup();
-
- unsafe {
- env::set_var("XDG_DATA_HOME", "/custom/data/path");
- }
+ let env_vars = vec![("XDG_DATA_HOME".to_string(), "/custom/data/path".to_string())];
+ let config = Config::from_env_vars(&env_vars);
let expected_path = "sqlite:/custom/data/path/silmataivas/silmataivas.db";
-
- let config = Config::from_env();
assert_eq!(config.database_url, expected_path);
-
- // Clean up after this test
- unsafe {
- env::remove_var("XDG_DATA_HOME");
- }
}
#[test]
fn test_database_url_explicit() {
- setup();
+ let env_vars = vec![(
+ "DATABASE_URL".to_string(),
+ "sqlite:/explicit/path.db".to_string(),
+ )];
- unsafe {
- env::set_var("DATABASE_URL", "sqlite:/explicit/path.db");
- }
-
- let config = Config::from_env();
+ let config = Config::from_env_vars(&env_vars);
assert_eq!(config.database_url, "sqlite:/explicit/path.db");
-
- // Clean up after this test
- unsafe {
- env::remove_var("DATABASE_URL");
- }
}
#[test]
fn test_server_config() {
- setup();
+ let env_vars = vec![
+ ("PORT".to_string(), "8080".to_string()),
+ ("HOST".to_string(), "127.0.0.1".to_string()),
+ ("LOG_LEVEL".to_string(), "debug".to_string()),
+ ];
- unsafe {
- env::set_var("PORT", "8080");
- env::set_var("HOST", "127.0.0.1");
- env::set_var("LOG_LEVEL", "debug");
- }
-
- let config = Config::from_env();
+ let config = Config::from_env_vars(&env_vars);
assert_eq!(config.server_port, 8080);
assert_eq!(config.server_host, "127.0.0.1");
assert_eq!(config.log_level, "debug");
+ }
- // Clean up after this test
- unsafe {
- env::remove_var("PORT");
- env::remove_var("HOST");
- env::remove_var("LOG_LEVEL");
- }
+ #[test]
+ fn test_default_values() {
+ let env_vars = vec![];
+
+ let config = Config::from_env_vars(&env_vars);
+ assert_eq!(config.server_port, 4000);
+ assert_eq!(config.server_host, "0.0.0.0");
+ assert_eq!(config.log_level, "info");
+ }
+
+ #[test]
+ fn test_home_fallback_to_tmp() {
+ let env_vars = vec![];
+
+ let config = Config::from_env_vars(&env_vars);
+ let expected_path = "sqlite:/tmp/.local/share/silmataivas/silmataivas.db";
+ assert_eq!(config.database_url, expected_path);
}
}