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