fallow_cli/health_types/
mod.rs1mod scores;
8mod targets;
9mod trends;
10mod vital_signs;
11
12pub use scores::*;
13pub use targets::*;
14pub use trends::*;
15pub use vital_signs::*;
16
17#[derive(Debug, serde::Serialize)]
19pub struct HealthReport {
20 pub findings: Vec<HealthFinding>,
22 pub summary: HealthSummary,
24 #[serde(skip_serializing_if = "Option::is_none")]
26 pub vital_signs: Option<VitalSigns>,
27 #[serde(skip_serializing_if = "Option::is_none")]
29 pub health_score: Option<HealthScore>,
30 #[serde(skip_serializing_if = "Vec::is_empty")]
32 pub file_scores: Vec<FileHealthScore>,
33 #[serde(skip_serializing_if = "Vec::is_empty")]
35 pub hotspots: Vec<HotspotEntry>,
36 #[serde(skip_serializing_if = "Option::is_none")]
38 pub hotspot_summary: Option<HotspotSummary>,
39 #[serde(skip_serializing_if = "Vec::is_empty")]
41 pub targets: Vec<RefactoringTarget>,
42 #[serde(skip_serializing_if = "Option::is_none")]
44 pub target_thresholds: Option<TargetThresholds>,
45 #[serde(skip_serializing_if = "Option::is_none")]
47 pub health_trend: Option<HealthTrend>,
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53
54 #[test]
55 fn health_report_skips_empty_collections() {
56 let report = HealthReport {
57 findings: vec![],
58 summary: HealthSummary {
59 files_analyzed: 0,
60 functions_analyzed: 0,
61 functions_above_threshold: 0,
62 max_cyclomatic_threshold: 20,
63 max_cognitive_threshold: 15,
64 files_scored: None,
65 average_maintainability: None,
66 },
67 vital_signs: None,
68 health_score: None,
69 file_scores: vec![],
70 hotspots: vec![],
71 hotspot_summary: None,
72 targets: vec![],
73 target_thresholds: None,
74 health_trend: None,
75 };
76 let json = serde_json::to_string(&report).unwrap();
77 assert!(!json.contains("file_scores"));
79 assert!(!json.contains("hotspots"));
80 assert!(!json.contains("hotspot_summary"));
81 assert!(!json.contains("targets"));
82 assert!(!json.contains("vital_signs"));
83 assert!(!json.contains("health_score"));
84 }
85
86 #[test]
87 fn health_score_none_skipped_in_report() {
88 let report = HealthReport {
89 findings: vec![],
90 summary: HealthSummary {
91 files_analyzed: 0,
92 functions_analyzed: 0,
93 functions_above_threshold: 0,
94 max_cyclomatic_threshold: 20,
95 max_cognitive_threshold: 15,
96 files_scored: None,
97 average_maintainability: None,
98 },
99 vital_signs: None,
100 health_score: None,
101 file_scores: vec![],
102 hotspots: vec![],
103 hotspot_summary: None,
104 targets: vec![],
105 target_thresholds: None,
106 health_trend: None,
107 };
108 let json = serde_json::to_string(&report).unwrap();
109 assert!(!json.contains("health_score"));
110 }
111}