From 44b69b4f82a73dc4568bb8f7af4646dcfd3a1eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B6=85=E6=B8=A1=E6=B3=95=E5=B8=AB?= Date: Sun, 31 May 2026 02:55:41 +0000 Subject: [PATCH 1/2] chore: remove test_ prefix from #[test] functions in src/ Unify test naming convention by removing the redundant test_ prefix from all #[test] functions in src/. The #[test] attribute and mod tests already provide sufficient context. Renamed 50 test functions across 4 files: - src/setup/config.rs (2) - src/setup/validate.rs (4) - src/error_display.rs (21) - src/remind.rs (23) Helper functions (test_cron_job, test_channel, test_trigger) that return test fixtures are intentionally kept unchanged. Closes #953 --- src/error_display.rs | 42 +++++++++++++++++++-------------------- src/remind.rs | 46 +++++++++++++++++++++---------------------- src/setup/config.rs | 4 ++-- src/setup/validate.rs | 8 ++++---- 4 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/error_display.rs b/src/error_display.rs index e822f503f..bff554182 100644 --- a/src/error_display.rs +++ b/src/error_display.rs @@ -92,78 +92,78 @@ mod tests { // ─── format_user_error tests ───────────────────────────────────────────── #[test] - fn test_format_user_error_timeout() { + fn format_user_error_timeout() { let result = format_user_error("timeout waiting for session/new response"); assert!(result.contains("Request Timeout")); assert!(result.contains("session/new")); } #[test] - fn test_format_user_error_connection_closed() { + fn format_user_error_connection_closed() { let result = format_user_error("connection closed"); assert!(result.contains("Connection Lost")); } #[test] - fn test_format_user_error_channel_closed() { + fn format_user_error_channel_closed() { let result = format_user_error("channel closed"); assert!(result.contains("Connection Lost")); } #[test] - fn test_format_user_error_failed_to_spawn() { + fn format_user_error_failed_to_spawn() { let result = format_user_error("failed to spawn /some/path: No such file"); assert!(result.contains("Agent Not Found")); assert!(result.contains("the agent")); // generic, no provider name } #[test] - fn test_format_user_error_no_such_file() { + fn format_user_error_no_such_file() { let result = format_user_error("binary /usr/bin/nonexistent: no such file"); assert!(result.contains("Agent Not Found")); } #[test] - fn test_format_user_error_pool_exhausted() { + fn format_user_error_pool_exhausted() { let result = format_user_error("pool exhausted (5 sessions)"); assert!(result.contains("Service Busy")); } #[test] - fn test_format_user_error_invalid_api_key() { + fn format_user_error_invalid_api_key() { let result = format_user_error("invalid api key"); assert!(result.contains("Unauthorized")); } #[test] - fn test_format_user_error_unauthorized() { + fn format_user_error_unauthorized() { let result = format_user_error("unauthorized: token rejected"); assert!(result.contains("Unauthorized")); } #[test] - fn test_format_user_error_unknown() { + fn format_user_error_unknown() { let result = format_user_error("something went wrong"); assert!(result.contains("Error")); assert!(result.contains("something went wrong")); } #[test] - fn test_format_user_error_empty() { + fn format_user_error_empty() { let result = format_user_error(""); assert!(result.contains("Error")); assert!(result.contains("unknown")); } #[test] - fn test_format_user_error_case_insensitive() { + fn format_user_error_case_insensitive() { assert!(format_user_error("TIMEOUT WAITING FOR foo").contains("Timeout")); assert!(format_user_error("CONNECTION CLOSED").contains("Connection")); assert!(format_user_error("POOL EXHAUSTED").contains("Busy")); } #[test] - fn test_format_user_error_mixed_case_timeout() { + fn format_user_error_mixed_case_timeout() { // Case-insensitive matching should still extract method correctly let result = format_user_error("Timeout Waiting For custom/method"); assert!(result.contains("Request Timeout")); @@ -173,7 +173,7 @@ mod tests { // ─── format_coded_error tests ─────────────────────────────────────────── #[test] - fn test_format_coded_error_401() { + fn format_coded_error_401() { let result = format_coded_error(401, "invalid token", None); assert!(result.contains("Unauthorized")); assert!(result.contains("401")); @@ -181,7 +181,7 @@ mod tests { } #[test] - fn test_format_coded_error_429() { + fn format_coded_error_429() { let result = format_coded_error(429, "", None); assert!(result.contains("Rate Limited")); assert!(result.contains("429")); @@ -189,7 +189,7 @@ mod tests { } #[test] - fn test_format_coded_error_503() { + fn format_coded_error_503() { let result = format_coded_error(503, "service unavailable", None); assert!(result.contains("Service Unavailable")); assert!(result.contains("503")); @@ -197,28 +197,28 @@ mod tests { } #[test] - fn test_format_coded_error_json_rpc() { + fn format_coded_error_json_rpc() { let result = format_coded_error(-32602, "missing required parameter", None); assert!(result.contains("Invalid Params")); assert!(result.contains("-32602")); } #[test] - fn test_format_coded_error_server_error_range() { + fn format_coded_error_server_error_range() { let result = format_coded_error(-32050, "internal failure", None); assert!(result.contains("Server Error")); assert!(result.contains("-32050")); } #[test] - fn test_format_coded_error_connection_error() { + fn format_coded_error_connection_error() { let result = format_coded_error(-32000, "connection refused", None); assert!(result.contains("Server Error")); // -32000 falls in -32099..=-32000 range assert!(result.contains("-32000")); } #[test] - fn test_format_coded_error_unknown_code() { + fn format_coded_error_unknown_code() { let result = format_coded_error(999, "something happened", None); assert!(result.contains("Error")); assert!(result.contains("999")); @@ -226,14 +226,14 @@ mod tests { } #[test] - fn test_format_coded_error_with_data_message() { + fn format_coded_error_with_data_message() { let result = format_coded_error(-32603, "Internal error", Some("model not supported")); assert!(result.contains("Internal Error")); assert!(result.contains("model not supported")); } #[test] - fn test_format_coded_error_data_message_not_duplicated() { + fn format_coded_error_data_message_not_duplicated() { // If data_message is already in message, don't repeat it let result = format_coded_error(-32603, "model not supported", Some("model not supported")); assert_eq!(result.matches("model not supported").count(), 1); diff --git a/src/remind.rs b/src/remind.rs index 471b08ff4..9472c53d8 100644 --- a/src/remind.rs +++ b/src/remind.rs @@ -211,83 +211,83 @@ mod tests { use super::*; #[test] - fn test_parse_delay_minutes() { + fn parse_delay_minutes() { assert_eq!(parse_delay("5m").unwrap(), 300); assert_eq!(parse_delay("1m").unwrap(), 60); } #[test] - fn test_parse_delay_hours() { + fn parse_delay_hours() { assert_eq!(parse_delay("2h").unwrap(), 7200); } #[test] - fn test_parse_delay_days() { + fn parse_delay_days() { assert_eq!(parse_delay("1d").unwrap(), 86400); assert_eq!(parse_delay("30d").unwrap(), 2_592_000); } #[test] - fn test_parse_delay_combined() { + fn parse_delay_combined() { assert_eq!(parse_delay("1h30m").unwrap(), 5400); assert_eq!(parse_delay("1d12h").unwrap(), 129_600); } #[test] - fn test_parse_delay_bare_number_defaults_to_minutes() { + fn parse_delay_bare_number_defaults_to_minutes() { assert_eq!(parse_delay("10").unwrap(), 600); } #[test] - fn test_parse_delay_too_short() { + fn parse_delay_too_short() { assert!(parse_delay("0m").is_err()); assert!(parse_delay("0h").is_err()); } #[test] - fn test_parse_delay_too_long() { + fn parse_delay_too_long() { assert!(parse_delay("31d").is_err()); } #[test] - fn test_format_delay() { + fn format_delay_basic() { assert_eq!(format_delay(3600), "1h"); assert_eq!(format_delay(5400), "1h 30m"); assert_eq!(format_delay(90000), "1d 1h"); } #[test] - fn test_parse_delay_empty() { + fn parse_delay_empty() { assert!(parse_delay("").is_err()); assert!(parse_delay(" ").is_err()); } #[test] - fn test_parse_delay_invalid_unit() { + fn parse_delay_invalid_unit() { assert!(parse_delay("2x").is_err()); assert!(parse_delay("abc").is_err()); assert!(parse_delay("5s").is_err()); } #[test] - fn test_parse_delay_case_insensitive() { + fn parse_delay_case_insensitive() { assert_eq!(parse_delay("2H").unwrap(), 7200); assert_eq!(parse_delay("1D30M").unwrap(), 88200); } #[test] - fn test_parse_delay_whitespace_trimmed() { + fn parse_delay_whitespace_trimmed() { assert_eq!(parse_delay(" 5m ").unwrap(), 300); } #[test] - fn test_parse_delay_bare_number_boundary() { + fn parse_delay_bare_number_boundary() { assert_eq!(parse_delay("1").unwrap(), 60); // 1 min assert_eq!(parse_delay("30").unwrap(), 1800); // 30 min } #[test] - fn test_parse_delay_exact_boundaries() { + fn parse_delay_exact_boundaries() { // Exactly 1m (minimum) assert_eq!(parse_delay("1m").unwrap(), 60); // Exactly 30d (maximum) @@ -297,19 +297,19 @@ mod tests { } #[test] - fn test_format_delay_zero() { + fn format_delay_zero() { assert_eq!(format_delay(0), "< 1m"); } #[test] - fn test_format_delay_pure_units() { + fn format_delay_pure_units() { assert_eq!(format_delay(86400), "1d"); assert_eq!(format_delay(120), "2m"); assert_eq!(format_delay(7200), "2h"); } #[tokio::test] - async fn test_reminder_store_add_remove() { + async fn reminder_store_add_remove() { let dir = std::env::temp_dir().join(format!("remind_test_{}", std::process::id())); std::fs::create_dir_all(&dir).unwrap(); let path = dir.join("reminders.json"); @@ -341,7 +341,7 @@ mod tests { } #[tokio::test] - async fn test_reminder_store_persists_across_reload() { + async fn reminder_store_persists_across_reload() { let dir = std::env::temp_dir().join(format!("remind_test2_{}", std::process::id())); std::fs::create_dir_all(&dir).unwrap(); let path = dir.join("reminders.json"); @@ -369,31 +369,31 @@ mod tests { } #[test] - fn test_sanitize_message_strips_everyone_here() { + fn sanitize_message_strips_everyone_here() { assert_eq!(sanitize_message("hello @everyone"), "hello @\u{200b}everyone"); assert_eq!(sanitize_message("hey @here check"), "hey @\u{200b}here check"); assert_eq!(sanitize_message("@everyone @here"), "@\u{200b}everyone @\u{200b}here"); } #[test] - fn test_sanitize_message_no_change() { + fn sanitize_message_no_change() { assert_eq!(sanitize_message("normal message"), "normal message"); assert_eq!(sanitize_message("<@123> hello"), "<@123> hello"); } #[test] - fn test_validate_message_ok() { + fn validate_message_ok() { assert!(validate_message("short message").is_ok()); assert!(validate_message(&"a".repeat(1800)).is_ok()); } #[test] - fn test_validate_message_too_long() { + fn validate_message_too_long() { assert!(validate_message(&"a".repeat(1801)).is_err()); } #[test] - fn test_max_targets_constant() { + fn max_targets_constant() { assert_eq!(MAX_TARGETS, 10); } } diff --git a/src/setup/config.rs b/src/setup/config.rs index c0e7d604d..ee1483650 100644 --- a/src/setup/config.rs +++ b/src/setup/config.rs @@ -130,7 +130,7 @@ mod tests { use super::*; #[test] - fn test_generate_config_contains_sections() { + fn generate_config_contains_sections() { let config = generate_config( "my_token", "claude", @@ -148,7 +148,7 @@ mod tests { } #[test] - fn test_generate_config_kiro_working_dir() { + fn generate_config_kiro_working_dir() { let config = generate_config("tok", "kiro", vec!["ch".to_string()], "/home/agent", 10, 24); assert!(config.contains(r#"working_dir = "/home/agent""#)); assert!(config.contains("acp")); diff --git a/src/setup/validate.rs b/src/setup/validate.rs index 527a1a385..510c52be3 100644 --- a/src/setup/validate.rs +++ b/src/setup/validate.rs @@ -47,14 +47,14 @@ mod tests { use super::*; #[test] - fn test_validate_bot_token_ok() { + fn validate_bot_token_ok() { assert!(validate_bot_token("simple_token").is_ok()); assert!(validate_bot_token("token.with-dashes_123").is_ok()); assert!(validate_bot_token("***/efgh").is_ok()); } #[test] - fn test_validate_bot_token_reject_invalid() { + fn validate_bot_token_reject_invalid() { assert!(validate_bot_token("").is_err()); assert!(validate_bot_token("token\nnewline").is_err()); assert!(validate_bot_token("token\ttab").is_err()); @@ -62,7 +62,7 @@ mod tests { } #[test] - fn test_validate_agent_command() { + fn validate_agent_command() { for agent in &["kiro", "claude", "codex", "gemini"] { assert!(validate_agent_command(agent).is_ok()); } @@ -70,7 +70,7 @@ mod tests { } #[test] - fn test_validate_channel_id() { + fn validate_channel_id() { assert!(validate_channel_id("1492329565824094370").is_ok()); assert!(validate_channel_id("").is_err()); assert!(validate_channel_id("abc123").is_err()); From b08b41362b9e42d40eee7f0142f7b3a98ddbc87e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B6=85=E6=B8=A1=E6=B3=95=E5=B8=AB?= Date: Sun, 31 May 2026 04:30:10 +0000 Subject: [PATCH 2/2] fix: avoid test fn shadowing production functions in validate.rs validate_agent_command and validate_channel_id test functions had the same name as the production functions they were testing, causing the test to call itself (0 args) instead of the production fn (1 arg). --- src/setup/validate.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/setup/validate.rs b/src/setup/validate.rs index 510c52be3..b09401559 100644 --- a/src/setup/validate.rs +++ b/src/setup/validate.rs @@ -62,7 +62,7 @@ mod tests { } #[test] - fn validate_agent_command() { + fn validate_agent_command_known_and_unknown() { for agent in &["kiro", "claude", "codex", "gemini"] { assert!(validate_agent_command(agent).is_ok()); } @@ -70,7 +70,7 @@ mod tests { } #[test] - fn validate_channel_id() { + fn validate_channel_id_accepts_numeric_rejects_invalid() { assert!(validate_channel_id("1492329565824094370").is_ok()); assert!(validate_channel_id("").is_err()); assert!(validate_channel_id("abc123").is_err());