mockforge_reporting/
lib.rs1pub mod comparison;
8pub mod csv_export;
9pub mod dashboard_layouts;
10pub mod email;
11pub mod flamegraph;
12pub mod pdf;
13pub mod trend_analysis;
14
15pub use comparison::{ComparisonReport, ComparisonReportGenerator};
16pub use csv_export::{CsvBatchExporter, CsvExportConfig, CsvExporter};
17pub use dashboard_layouts::{
18 DashboardLayout, DashboardLayoutBuilder, DashboardLayoutManager, DashboardTemplates,
19 DataSource, GridConfig, Widget, WidgetType,
20};
21pub use email::{EmailConfig, EmailNotifier, EmailReport};
22pub use flamegraph::{FlamegraphGenerator, FlamegraphStats, TraceData, TraceSpan};
23pub use pdf::{PdfConfig, PdfReportGenerator};
24pub use trend_analysis::{TrendAnalyzer, TrendDirection, TrendReport};
25
26use thiserror::Error;
27
28#[derive(Error, Debug)]
29pub enum ReportingError {
30 #[error("PDF generation error: {0}")]
31 Pdf(String),
32
33 #[error("Email sending error: {0}")]
34 Email(String),
35
36 #[error("Analysis error: {0}")]
37 Analysis(String),
38
39 #[error("IO error: {0}")]
40 Io(#[from] std::io::Error),
41
42 #[error("Serialization error: {0}")]
43 Serialization(#[from] serde_json::Error),
44}
45
46pub type Result<T> = std::result::Result<T, ReportingError>;
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn test_reporting_error_pdf() {
54 let error = ReportingError::Pdf("font not found".to_string());
55 assert_eq!(error.to_string(), "PDF generation error: font not found");
56 }
57
58 #[test]
59 fn test_reporting_error_email() {
60 let error = ReportingError::Email("SMTP connection failed".to_string());
61 assert_eq!(error.to_string(), "Email sending error: SMTP connection failed");
62 }
63
64 #[test]
65 fn test_reporting_error_analysis() {
66 let error = ReportingError::Analysis("insufficient data".to_string());
67 assert_eq!(error.to_string(), "Analysis error: insufficient data");
68 }
69
70 #[test]
71 fn test_reporting_error_from_io() {
72 let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
73 let error: ReportingError = io_error.into();
74 assert!(matches!(error, ReportingError::Io(_)));
75 assert!(error.to_string().contains("IO error"));
76 }
77
78 #[test]
79 fn test_reporting_error_from_serde_json() {
80 let json_error = serde_json::from_str::<serde_json::Value>("invalid").unwrap_err();
81 let error: ReportingError = json_error.into();
82 assert!(matches!(error, ReportingError::Serialization(_)));
83 assert!(error.to_string().contains("Serialization error"));
84 }
85
86 #[test]
87 fn test_reporting_error_debug() {
88 let error = ReportingError::Pdf("test".to_string());
89 let debug = format!("{:?}", error);
90 assert!(debug.contains("Pdf"));
91 }
92
93 #[test]
94 fn test_result_ok() {
95 let result: Result<i32> = Ok(42);
96 assert!(result.is_ok());
97 assert_eq!(result.unwrap(), 42);
98 }
99
100 #[test]
101 fn test_result_err() {
102 let result: Result<i32> = Err(ReportingError::Pdf("test".to_string()));
103 assert!(result.is_err());
104 }
105}