From b26887e05ad0536ee6337c90637a7a70048e4c59 Mon Sep 17 00:00:00 2001 From: Jeremiah Russell Date: Mon, 20 Oct 2025 09:56:39 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=A8=20style:=20fix=20clippy=20warnings?= =?UTF-8?q?=20and=20clean=20up=20test=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/gmail_client.rs | 14 +++--- src/gmail_client/message_summary.rs | 55 ++++++++++++----------- tests/gmail_client_unit_tests.rs | 68 ++++++++--------------------- 3 files changed, 56 insertions(+), 81 deletions(-) diff --git a/src/gmail_client.rs b/src/gmail_client.rs index 217988a..8049f03 100644 --- a/src/gmail_client.rs +++ b/src/gmail_client.rs @@ -118,28 +118,28 @@ use crate::{ClientConfig, Error, Result, rules::EolRule}; /// /// This constant defines the default page size for Gmail API list operations. /// The value "200" represents a balance between API efficiency and memory usage. -/// +/// /// Gmail API supports up to 500 results per page, but 200 provides good performance /// while keeping response sizes manageable. pub const DEFAULT_MAX_RESULTS: &str = "200"; /// Gmail API client providing authenticated access to Gmail operations. -/// +/// /// `GmailClient` manages the connection to Gmail's REST API, handles OAuth2 authentication, /// maintains label mappings, and provides methods for message list operations. -/// +/// /// The client contains internal state for: /// - Authentication credentials and tokens /// - Label name-to-ID mappings /// - Query filters and pagination settings /// - Retrieved message summaries /// - Rule processing configuration -/// +/// /// # Examples -/// +/// /// ```rust,no_run /// use cull_gmail::{ClientConfig, GmailClient}; -/// +/// /// # async fn example() -> cull_gmail::Result<()> { /// let config = ClientConfig::builder() /// .with_client_id("client-id") @@ -378,7 +378,7 @@ impl GmailClient { /// # async fn example() -> cull_gmail::Result<()> { /// # let config = ClientConfig::builder().build(); /// let client = GmailClient::new_with_config(config).await?; - /// + /// /// // Display all labels (output goes to log) /// client.show_label(); /// # Ok(()) diff --git a/src/gmail_client/message_summary.rs b/src/gmail_client/message_summary.rs index 6672875..466f9fd 100644 --- a/src/gmail_client/message_summary.rs +++ b/src/gmail_client/message_summary.rs @@ -190,15 +190,15 @@ mod tests { #[test] fn test_message_summary_set_subject() { let mut summary = MessageSummary::new("test_id"); - + // Test setting a subject summary.set_subject(Some("Test Subject".to_string())); assert_eq!(summary.subject(), "Test Subject"); - + // Test setting subject to None summary.set_subject(None); assert_eq!(summary.subject(), "*** No Subject for Message ***"); - + // Test empty subject summary.set_subject(Some("".to_string())); assert_eq!(summary.subject(), ""); @@ -207,15 +207,15 @@ mod tests { #[test] fn test_message_summary_set_date() { let mut summary = MessageSummary::new("test_id"); - + // Test setting a date summary.set_date(Some("2023-12-25 10:30:00".to_string())); assert_eq!(summary.date(), "2023-12-25 10:30:00"); - + // Test setting date to None summary.set_date(None); assert_eq!(summary.date(), "*** No Date for Message ***"); - + // Test empty date summary.set_date(Some("".to_string())); assert_eq!(summary.date(), ""); @@ -224,13 +224,15 @@ mod tests { #[test] fn test_message_summary_list_date_and_subject_valid() { let mut summary = MessageSummary::new("test_id"); - + // Set up a realistic date and subject summary.set_date(Some("2023-12-25 10:30:00 GMT".to_string())); - summary.set_subject(Some("This is a very long subject that should be elided".to_string())); - + summary.set_subject(Some( + "This is a very long subject that should be elided".to_string(), + )); + let display = summary.list_date_and_subject(); - + // The method extracts characters 5-16 from date and elides subject to 24 chars // "2023-12-25 10:30:00 GMT" -> chars 5-16 would be "2-25 10:30" assert!(display.contains("2-25 10:30")); @@ -241,18 +243,18 @@ mod tests { #[test] fn test_message_summary_list_date_and_subject_missing_fields() { let mut summary = MessageSummary::new("test_id"); - + // Test with missing date summary.set_subject(Some("Test Subject".to_string())); let result = summary.list_date_and_subject(); assert_eq!(result, "***invalid date or subject***"); - + // Test with missing subject let mut summary2 = MessageSummary::new("test_id"); summary2.set_date(Some("2023-12-25 10:30:00".to_string())); let result2 = summary2.list_date_and_subject(); assert_eq!(result2, "***invalid date or subject***"); - + // Test with both missing let summary3 = MessageSummary::new("test_id"); let result3 = summary3.list_date_and_subject(); @@ -264,9 +266,9 @@ mod tests { let mut original = MessageSummary::new("original_id"); original.set_subject(Some("Original Subject".to_string())); original.set_date(Some("2023-12-25 10:30:00".to_string())); - + let cloned = original.clone(); - + assert_eq!(original.id(), cloned.id()); assert_eq!(original.subject(), cloned.subject()); assert_eq!(original.date(), cloned.date()); @@ -277,9 +279,9 @@ mod tests { let mut summary = MessageSummary::new("debug_test_id"); summary.set_subject(Some("Debug Subject".to_string())); summary.set_date(Some("2023-12-25".to_string())); - - let debug_str = format!("{:?}", summary); - + + let debug_str = format!("{summary:?}"); + // Verify the debug output contains expected fields assert!(debug_str.contains("MessageSummary")); assert!(debug_str.contains("debug_test_id")); @@ -290,14 +292,14 @@ mod tests { #[test] fn test_message_summary_unicode_handling() { let mut summary = MessageSummary::new("unicode_test"); - + // Test with Unicode characters in subject and date summary.set_subject(Some("📧 Important émails with 中文字符".to_string())); summary.set_date(Some("2023-12-25 10:30:00 UTC+8 🕒".to_string())); - + assert_eq!(summary.subject(), "📧 Important émails with 中文字符"); assert_eq!(summary.date(), "2023-12-25 10:30:00 UTC+8 🕒"); - + // Ensure list formatting doesn't panic with Unicode let display = summary.list_date_and_subject(); assert!(!display.is_empty()); @@ -307,16 +309,19 @@ mod tests { fn test_message_summary_edge_cases() { let test_cases = vec![ ("", "Empty ID"), - ("a", "Single char ID"), - ("very_long_message_id_that_exceeds_normal_length_expectations_123456789", "Very long ID"), + ("a", "Single char ID"), + ( + "very_long_message_id_that_exceeds_normal_length_expectations_123456789", + "Very long ID", + ), ("msg-with-dashes", "ID with dashes"), ("msg_with_underscores", "ID with underscores"), ("123456789", "Numeric ID"), ]; - + for (id, description) in test_cases { let summary = MessageSummary::new(id); - assert_eq!(summary.id(), id, "Failed for case: {}", description); + assert_eq!(summary.id(), id, "Failed for case: {description}"); } } } diff --git a/tests/gmail_client_unit_tests.rs b/tests/gmail_client_unit_tests.rs index 2513446..761bdab 100644 --- a/tests/gmail_client_unit_tests.rs +++ b/tests/gmail_client_unit_tests.rs @@ -3,19 +3,20 @@ //! These tests focus on testing the individual components and methods of the Gmail client //! that can be tested without requiring actual Gmail API calls. -use cull_gmail::{GmailClient, ClientConfig}; - /// Test module for Gmail client functionality mod gmail_client_tests { + use cull_gmail::ClientConfig; /// Test the default max results constant #[test] fn test_default_max_results() { let default_max = cull_gmail::DEFAULT_MAX_RESULTS; assert_eq!(default_max, "200"); - + // Verify it can be parsed as u32 - let parsed: u32 = default_max.parse().expect("DEFAULT_MAX_RESULTS should be a valid u32"); + let parsed: u32 = default_max + .parse() + .expect("DEFAULT_MAX_RESULTS should be a valid u32"); assert_eq!(parsed, 200); } @@ -25,57 +26,26 @@ mod gmail_client_tests { let default_max: u32 = cull_gmail::DEFAULT_MAX_RESULTS .parse() .expect("DEFAULT_MAX_RESULTS should be a valid u32"); - + // Gmail API supports up to 500 results per page assert!(default_max > 0, "Max results should be positive"); - assert!(default_max <= 500, "Max results should not exceed Gmail API limit"); - assert!(default_max >= 10, "Max results should be reasonable for performance"); + assert!( + default_max <= 500, + "Max results should not exceed Gmail API limit" + ); + assert!( + default_max >= 10, + "Max results should be reasonable for performance" + ); } - /// Test Debug implementation for GmailClient - /// This test doesn't need actual Gmail authentication since Debug works on the struct fields + /// Test that ClientConfig builder compiles and creates a config #[test] - fn test_gmail_client_debug() { - // We can't easily construct a GmailClient without authentication, - // so we'll test the debug formatting indirectly by checking the implementation exists - // and that it's properly named in the debug output structure. - - // This test mainly ensures the Debug trait is properly implemented - // and doesn't panic or cause compilation issues - - // Note: A full test would require mocking the Gmail authentication, - // which is complex and beyond the scope of unit tests - assert!(true, "Debug trait implementation compiles successfully"); - } -} - -/// Tests for public API constants and utilities -mod public_api_tests { - use cull_gmail::ClientConfig; - - #[test] - fn test_client_config_builder_basic() { - // Test that ClientConfig builder works and creates valid configs - let config = ClientConfig::builder() - .with_client_id("test-client-id") + fn test_client_config_builder_works() { + let _config = ClientConfig::builder() + .with_client_id("test-id") .with_client_secret("test-secret") .build(); - - // Basic validation that config was created successfully - // (We can't easily test the internal fields without making them public) - // This at least ensures the builder pattern compiles and doesn't panic - assert!(true, "ClientConfig builder works without panicking"); - } - - #[test] - fn test_client_config_builder_chain() { - // Test that builder methods can be chained - let _config = ClientConfig::builder() - .with_client_id("client") - .with_client_secret("secret") - .build(); - - // If we reach this point, the chaining worked - assert!(true, "Builder method chaining works"); + // Test passes if we reach here without panicking } }