1use serde::Serialize;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
7pub enum ReportType {
8 Coverage,
9 Violations,
10 Drift,
11 Stale,
12 Gates,
13 Integrity,
14 Versions,
15 Dependencies,
16 Lifecycle,
17 Summary,
18 All,
19}
20
21#[derive(Debug, Clone, PartialEq, Eq)]
23pub enum OutputFormat {
24 Json,
25 Markdown,
26 Table,
27}
28
29#[derive(Debug, Serialize)]
35pub struct HeadlessOutput {
36 pub report_type: String,
38 pub timestamp: String,
40 pub console_version: String,
42 pub exit_code: i32,
44 #[serde(flatten)]
46 pub data: serde_json::Value,
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn report_type_equality() {
55 assert_eq!(ReportType::Coverage, ReportType::Coverage);
56 assert_ne!(ReportType::Coverage, ReportType::Violations);
57 assert_eq!(ReportType::All, ReportType::All);
58 }
59
60 #[test]
61 fn output_format_equality() {
62 assert_eq!(OutputFormat::Json, OutputFormat::Json);
63 assert_ne!(OutputFormat::Json, OutputFormat::Markdown);
64 assert_eq!(OutputFormat::Table, OutputFormat::Table);
65 }
66
67 #[test]
68 fn headless_output_serializes_correctly() {
69 let output = HeadlessOutput {
70 report_type: "coverage".to_string(),
71 timestamp: "2025-01-01T00:00:00.000Z".to_string(),
72 console_version: "1.0.0".to_string(),
73 exit_code: 0,
74 data: serde_json::json!({"aggregate_score": 95.0}),
75 };
76 let json = serde_json::to_string(&output).expect("serialize");
77 let parsed: serde_json::Value = serde_json::from_str(&json).expect("parse");
78
79 assert_eq!(parsed["report_type"], "coverage");
80 assert_eq!(parsed["timestamp"], "2025-01-01T00:00:00.000Z");
81 assert_eq!(parsed["console_version"], "1.0.0");
82 assert_eq!(parsed["exit_code"], 0);
83 assert_eq!(parsed["aggregate_score"], 95.0);
85 }
86
87 #[test]
88 fn headless_output_flatten_merges_data() {
89 let output = HeadlessOutput {
91 report_type: "gates".to_string(),
92 timestamp: "2025-06-01T00:00:00.000Z".to_string(),
93 console_version: "2.0.0".to_string(),
94 exit_code: 1,
95 data: serde_json::json!({"gates_passed": 3, "gates_failed": 1}),
96 };
97 let json = serde_json::to_string(&output).unwrap();
98 let parsed: serde_json::Value = serde_json::from_str(&json).unwrap();
99
100 assert_eq!(parsed["exit_code"], 1);
101 assert_eq!(parsed["gates_passed"], 3);
102 assert_eq!(parsed["gates_failed"], 1);
103 assert!(parsed.get("data").is_none());
105 }
106
107 #[test]
108 fn report_type_all_variants_are_distinct() {
109 let variants = [
110 ReportType::Coverage,
111 ReportType::Violations,
112 ReportType::Drift,
113 ReportType::Stale,
114 ReportType::Gates,
115 ReportType::Integrity,
116 ReportType::Versions,
117 ReportType::Dependencies,
118 ReportType::Lifecycle,
119 ReportType::Summary,
120 ReportType::All,
121 ];
122 for (i, a) in variants.iter().enumerate() {
124 for (j, b) in variants.iter().enumerate() {
125 if i == j {
126 assert_eq!(a, b);
127 } else {
128 assert_ne!(a, b);
129 }
130 }
131 }
132 }
133}