fallow_config/config/
health.rs1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4const fn default_max_cyclomatic() -> u16 {
5 20
6}
7
8const fn default_max_cognitive() -> u16 {
9 15
10}
11
12#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema)]
14#[serde(rename_all = "camelCase")]
15pub struct HealthConfig {
16 #[serde(default = "default_max_cyclomatic")]
19 pub max_cyclomatic: u16,
20
21 #[serde(default = "default_max_cognitive")]
24 pub max_cognitive: u16,
25
26 #[serde(default)]
28 pub ignore: Vec<String>,
29}
30
31impl Default for HealthConfig {
32 fn default() -> Self {
33 Self {
34 max_cyclomatic: default_max_cyclomatic(),
35 max_cognitive: default_max_cognitive(),
36 ignore: vec![],
37 }
38 }
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44
45 #[test]
46 fn health_config_defaults() {
47 let config = HealthConfig::default();
48 assert_eq!(config.max_cyclomatic, 20);
49 assert_eq!(config.max_cognitive, 15);
50 assert!(config.ignore.is_empty());
51 }
52
53 #[test]
54 fn health_config_json_all_fields() {
55 let json = r#"{
56 "maxCyclomatic": 30,
57 "maxCognitive": 25,
58 "ignore": ["**/generated/**", "vendor/**"]
59 }"#;
60 let config: HealthConfig = serde_json::from_str(json).unwrap();
61 assert_eq!(config.max_cyclomatic, 30);
62 assert_eq!(config.max_cognitive, 25);
63 assert_eq!(config.ignore, vec!["**/generated/**", "vendor/**"]);
64 }
65
66 #[test]
67 fn health_config_json_partial_uses_defaults() {
68 let json = r#"{"maxCyclomatic": 10}"#;
69 let config: HealthConfig = serde_json::from_str(json).unwrap();
70 assert_eq!(config.max_cyclomatic, 10);
71 assert_eq!(config.max_cognitive, 15); assert!(config.ignore.is_empty()); }
74
75 #[test]
76 fn health_config_json_empty_object_uses_all_defaults() {
77 let config: HealthConfig = serde_json::from_str("{}").unwrap();
78 assert_eq!(config.max_cyclomatic, 20);
79 assert_eq!(config.max_cognitive, 15);
80 assert!(config.ignore.is_empty());
81 }
82
83 #[test]
84 fn health_config_json_only_ignore() {
85 let json = r#"{"ignore": ["test/**"]}"#;
86 let config: HealthConfig = serde_json::from_str(json).unwrap();
87 assert_eq!(config.max_cyclomatic, 20); assert_eq!(config.max_cognitive, 15); assert_eq!(config.ignore, vec!["test/**"]);
90 }
91
92 #[test]
95 fn health_config_toml_all_fields() {
96 let toml_str = r#"
97maxCyclomatic = 25
98maxCognitive = 20
99ignore = ["generated/**", "vendor/**"]
100"#;
101 let config: HealthConfig = toml::from_str(toml_str).unwrap();
102 assert_eq!(config.max_cyclomatic, 25);
103 assert_eq!(config.max_cognitive, 20);
104 assert_eq!(config.ignore, vec!["generated/**", "vendor/**"]);
105 }
106
107 #[test]
108 fn health_config_toml_defaults() {
109 let config: HealthConfig = toml::from_str("").unwrap();
110 assert_eq!(config.max_cyclomatic, 20);
111 assert_eq!(config.max_cognitive, 15);
112 assert!(config.ignore.is_empty());
113 }
114
115 #[test]
118 fn health_config_json_roundtrip() {
119 let config = HealthConfig {
120 max_cyclomatic: 50,
121 max_cognitive: 40,
122 ignore: vec!["test/**".to_string()],
123 };
124 let json = serde_json::to_string(&config).unwrap();
125 let restored: HealthConfig = serde_json::from_str(&json).unwrap();
126 assert_eq!(restored.max_cyclomatic, 50);
127 assert_eq!(restored.max_cognitive, 40);
128 assert_eq!(restored.ignore, vec!["test/**"]);
129 }
130
131 #[test]
134 fn health_config_zero_thresholds() {
135 let json = r#"{"maxCyclomatic": 0, "maxCognitive": 0}"#;
136 let config: HealthConfig = serde_json::from_str(json).unwrap();
137 assert_eq!(config.max_cyclomatic, 0);
138 assert_eq!(config.max_cognitive, 0);
139 }
140
141 #[test]
144 fn health_config_large_thresholds() {
145 let json = r#"{"maxCyclomatic": 65535, "maxCognitive": 65535}"#;
146 let config: HealthConfig = serde_json::from_str(json).unwrap();
147 assert_eq!(config.max_cyclomatic, u16::MAX);
148 assert_eq!(config.max_cognitive, u16::MAX);
149 }
150}