clnrm_core/reporting/
mod.rs1pub mod digest;
7pub mod json;
8pub mod junit;
9
10use crate::error::Result;
11use crate::validation::ValidationReport;
12use std::path::Path;
13
14pub use digest::DigestReporter;
15pub use json::JsonReporter;
16pub use junit::JunitReporter;
17
18#[derive(Debug, Clone, Default)]
20pub struct ReportConfig {
21 pub json_path: Option<String>,
23 pub junit_path: Option<String>,
25 pub digest_path: Option<String>,
27}
28
29impl ReportConfig {
30 pub fn new() -> Self {
32 Self::default()
33 }
34
35 pub fn with_json(mut self, path: impl Into<String>) -> Self {
37 self.json_path = Some(path.into());
38 self
39 }
40
41 pub fn with_junit(mut self, path: impl Into<String>) -> Self {
43 self.junit_path = Some(path.into());
44 self
45 }
46
47 pub fn with_digest(mut self, path: impl Into<String>) -> Self {
49 self.digest_path = Some(path.into());
50 self
51 }
52}
53
54pub fn generate_reports(
67 config: &ReportConfig,
68 report: &ValidationReport,
69 spans_json: &str,
70) -> Result<()> {
71 if let Some(ref json_path) = config.json_path {
72 JsonReporter::write(Path::new(json_path), report)?;
73 }
74
75 if let Some(ref junit_path) = config.junit_path {
76 JunitReporter::write(Path::new(junit_path), report)?;
77 }
78
79 if let Some(ref digest_path) = config.digest_path {
80 DigestReporter::write(Path::new(digest_path), spans_json)?;
81 }
82
83 Ok(())
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89 use crate::validation::ValidationReport;
90 use tempfile::TempDir;
91
92 #[test]
93 fn test_report_config_builder() {
94 let config = ReportConfig::new()
96 .with_json("report.json")
97 .with_junit("junit.xml")
98 .with_digest("digest.txt");
99
100 assert_eq!(config.json_path, Some("report.json".to_string()));
102 assert_eq!(config.junit_path, Some("junit.xml".to_string()));
103 assert_eq!(config.digest_path, Some("digest.txt".to_string()));
104 }
105
106 #[test]
107 fn test_generate_reports_all_formats() -> Result<()> {
108 let temp_dir = TempDir::new().map_err(|e| {
110 crate::error::CleanroomError::io_error(format!("Failed to create temp dir: {}", e))
111 })?;
112
113 let json_path = temp_dir.path().join("report.json");
114 let junit_path = temp_dir.path().join("junit.xml");
115 let digest_path = temp_dir.path().join("digest.txt");
116
117 let config = ReportConfig::new()
118 .with_json(json_path.to_string_lossy().to_string())
119 .with_junit(junit_path.to_string_lossy().to_string())
120 .with_digest(digest_path.to_string_lossy().to_string());
121
122 let mut report = ValidationReport::new();
123 report.add_pass("test_pass");
124 report.add_fail("test_fail", "Test error".to_string());
125
126 let spans_json = r#"{"spans": []}"#;
127
128 generate_reports(&config, &report, spans_json)?;
130
131 assert!(json_path.exists());
133 assert!(junit_path.exists());
134 assert!(digest_path.exists());
135
136 Ok(())
137 }
138
139 #[test]
140 fn test_generate_reports_partial_config() -> Result<()> {
141 let temp_dir = TempDir::new().map_err(|e| {
143 crate::error::CleanroomError::io_error(format!("Failed to create temp dir: {}", e))
144 })?;
145
146 let json_path = temp_dir.path().join("report.json");
147
148 let config = ReportConfig::new().with_json(json_path.to_string_lossy().to_string());
149
150 let report = ValidationReport::new();
151 let spans_json = r#"{"spans": []}"#;
152
153 generate_reports(&config, &report, spans_json)?;
155
156 assert!(json_path.exists());
158
159 Ok(())
160 }
161
162 #[test]
163 fn test_generate_reports_empty_config() -> Result<()> {
164 let config = ReportConfig::new();
166 let report = ValidationReport::new();
167 let spans_json = r#"{"spans": []}"#;
168
169 let result = generate_reports(&config, &report, spans_json);
171
172 assert!(result.is_ok());
174
175 Ok(())
176 }
177}