//! Comprehensive tests for error handling //! //! These tests ensure all error variants are properly handled //! and that error conversions work correctly. use jj_cz::{CommitMessageError, DescriptionError, Error, ScopeError}; /// Test that all error variants can be created and displayed #[test] fn test_all_error_variants() { // Domain errors let invalid_scope = Error::InvalidScope("test".to_string()); let _invalid_desc = Error::InvalidDescription("test".to_string()); let _invalid_msg = Error::InvalidCommitMessage("test".to_string()); // Infrastructure errors let not_repo = Error::NotARepository; let _jj_op = Error::JjOperation { context: "test".to_string(), }; let _repo_locked = Error::RepositoryLocked; let _failed_dir = Error::FailedGettingCurrentDir; let _failed_config = Error::FailedReadingConfig; // Application errors let cancelled = Error::Cancelled; let _non_interactive = Error::NonInteractive; // Verify all variants can be displayed assert_eq!(format!("{}", invalid_scope), "Invalid scope: test"); assert_eq!(format!("{}", not_repo), "Not a Jujutsu repository"); assert_eq!(format!("{}", cancelled), "Operation cancelled by user"); } /// Test error conversions from domain types #[test] fn test_error_conversions() { // ScopeError -> Error::InvalidScope let scope_err = ScopeError::TooLong { actual: 31, max: 30, }; let error: Error = scope_err.into(); assert!(matches!(error, Error::InvalidScope(_))); // DescriptionError -> Error::InvalidDescription let desc_err = DescriptionError::Empty; let error: Error = desc_err.into(); assert!(matches!(error, Error::InvalidDescription(_))); // CommitMessageError -> Error::InvalidCommitMessage let msg_err = CommitMessageError::FirstLineTooLong { actual: 73, max: 72, }; let error: Error = msg_err.into(); assert!(matches!(error, Error::InvalidCommitMessage(_))); } /// Test error equality and partial equality #[test] fn test_error_equality() { let err1 = Error::NotARepository; let err2 = Error::NotARepository; assert_eq!(err1, err2); let err3 = Error::Cancelled; assert_ne!(err1, err3); } /// Test error debugging #[test] fn test_error_debug() { let error = Error::JjOperation { context: "test operation".to_string(), }; let debug_str = format!("{:?}", error); assert!(debug_str.contains("JjOperation")); assert!(debug_str.contains("test operation")); } /// Test error cloning #[test] fn test_error_clone() { let original = Error::JjOperation { context: "original".to_string(), }; let cloned = original.clone(); assert_eq!(original, cloned); } /// Test error send and sync traits #[test] fn test_error_send_sync() { fn assert_send() {} fn assert_sync() {} let _error = Error::NotARepository; assert_send::(); assert_sync::(); // Test with owned data let _owned_error = Error::JjOperation { context: "test".to_string(), }; assert_send::(); assert_sync::(); } /// Test error matching patterns #[test] fn test_error_matching() { let error = Error::Cancelled; match error { Error::Cancelled => {} Error::NotARepository => panic!("Should not match"), Error::JjOperation { context } => panic!("Should not match: {}", context), _ => panic!("Should not match other variants"), } } /// Test error context extraction #[test] fn test_jj_operation_context() { let error = Error::JjOperation { context: "repository locked".to_string(), }; if let Error::JjOperation { context } = error { assert_eq!(context, "repository locked"); } else { panic!("Expected JjOperation variant"); } }