cli_testing_specialist/reporter/
json.rs1use crate::error::Result;
2use crate::types::TestReport;
3use crate::utils::{write_json_compact_optimized, write_json_optimized};
4use std::path::Path;
5
6pub struct JsonReporter;
8
9impl JsonReporter {
10 pub fn generate(report: &TestReport, output_path: &Path) -> Result<()> {
14 write_json_optimized(report, output_path)?;
16
17 Ok(())
18 }
19
20 pub fn generate_compact(report: &TestReport, output_path: &Path) -> Result<()> {
24 write_json_compact_optimized(report, output_path)?;
26
27 Ok(())
28 }
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34 use crate::types::{EnvironmentInfo, TestResult, TestStatus, TestSuite};
35 use chrono::Utc;
36 use std::fs;
37 use std::time::Duration;
38 use tempfile::NamedTempFile;
39
40 fn create_test_report() -> TestReport {
41 let suite = TestSuite {
42 name: "test_suite".to_string(),
43 file_path: "/path/to/test.bats".to_string(),
44 tests: vec![
45 TestResult {
46 name: "successful test".to_string(),
47 status: TestStatus::Passed,
48 duration: Duration::from_millis(150),
49 output: String::new(),
50 error_message: None,
51 file_path: "/path/to/test.bats".to_string(),
52 line_number: Some(5),
53 tags: vec![],
54 priority: crate::types::TestPriority::Important,
55 },
56 TestResult {
57 name: "failed test".to_string(),
58 status: TestStatus::Failed,
59 duration: Duration::from_millis(200),
60 output: "error output".to_string(),
61 error_message: Some("assertion failed".to_string()),
62 file_path: "/path/to/test.bats".to_string(),
63 line_number: Some(10),
64 tags: vec![],
65 priority: crate::types::TestPriority::Important,
66 },
67 ],
68 duration: Duration::from_millis(350),
69 started_at: Utc::now(),
70 finished_at: Utc::now(),
71 };
72
73 TestReport {
74 binary_name: "test-cli".to_string(),
75 binary_version: Some("1.0.0".to_string()),
76 suites: vec![suite],
77 total_duration: Duration::from_millis(350),
78 started_at: Utc::now(),
79 finished_at: Utc::now(),
80 environment: EnvironmentInfo::default(),
81 security_findings: vec![],
82 }
83 }
84
85 #[test]
86 fn test_json_generation() {
87 let report = create_test_report();
88 let temp_file = NamedTempFile::new().unwrap();
89 let output_path = temp_file.path();
90
91 JsonReporter::generate(&report, output_path).unwrap();
92
93 let content = fs::read_to_string(output_path).unwrap();
95 let parsed: serde_json::Value = serde_json::from_str(&content).unwrap();
96
97 assert_eq!(parsed["binary_name"], "test-cli");
99 assert_eq!(parsed["binary_version"], "1.0.0");
100 assert!(parsed["suites"].is_array());
101 assert_eq!(parsed["suites"].as_array().unwrap().len(), 1);
102
103 let suite = &parsed["suites"][0];
105 assert_eq!(suite["name"], "test_suite");
106 assert_eq!(suite["tests"].as_array().unwrap().len(), 2);
107
108 let test1 = &suite["tests"][0];
110 assert_eq!(test1["name"], "successful test");
111 assert_eq!(test1["status"], "passed");
112
113 let test2 = &suite["tests"][1];
114 assert_eq!(test2["name"], "failed test");
115 assert_eq!(test2["status"], "failed");
116 assert_eq!(test2["error_message"], "assertion failed");
117 }
118
119 #[test]
120 fn test_json_compact_generation() {
121 let report = create_test_report();
122 let temp_file = NamedTempFile::new().unwrap();
123 let output_path = temp_file.path();
124
125 JsonReporter::generate_compact(&report, output_path).unwrap();
126
127 let content = fs::read_to_string(output_path).unwrap();
129
130 let parsed: serde_json::Value = serde_json::from_str(&content).unwrap();
132 assert_eq!(parsed["binary_name"], "test-cli");
133
134 assert!(!content.contains(" ")); }
137
138 #[test]
139 fn test_json_roundtrip() {
140 let original = create_test_report();
141 let temp_file = NamedTempFile::new().unwrap();
142 let output_path = temp_file.path();
143
144 JsonReporter::generate(&original, output_path).unwrap();
146
147 let content = fs::read_to_string(output_path).unwrap();
149 let deserialized: TestReport = serde_json::from_str(&content).unwrap();
150
151 assert_eq!(deserialized.binary_name, original.binary_name);
153 assert_eq!(deserialized.binary_version, original.binary_version);
154 assert_eq!(deserialized.suites.len(), original.suites.len());
155 assert_eq!(
156 deserialized.suites[0].tests.len(),
157 original.suites[0].tests.len()
158 );
159 }
160}