commitlint_rs/rule/
scope_empty.rs1use crate::{message::Message, result::Violation, rule::Rule};
2use serde::{Deserialize, Serialize};
3
4use super::Level;
5
6#[derive(Clone, Debug, Deserialize, Serialize)]
8#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
9pub struct ScopeEmpty {
10 level: Option<Level>,
15}
16
17impl Rule for ScopeEmpty {
19 const NAME: &'static str = "scope-empty";
20 const LEVEL: Level = Level::Error;
21
22 fn message(&self, _message: &Message) -> String {
23 "scope is empty".to_string()
24 }
25
26 fn validate(&self, message: &Message) -> Option<Violation> {
27 if message.scope.is_none() {
28 return Some(Violation {
29 level: self.level.unwrap_or(Self::LEVEL),
30 message: self.message(message),
31 });
32 }
33
34 None
35 }
36}
37
38impl Default for ScopeEmpty {
40 fn default() -> Self {
41 Self {
42 level: Some(Self::LEVEL),
43 }
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50
51 #[test]
52 fn test_non_empty_subject() {
53 let rule = ScopeEmpty::default();
54 let message = Message {
55 body: None,
56 description: None,
57 footers: None,
58 r#type: Some("feat".to_string()),
59 raw: "feat(scope): broadcast $destroy event on scope destruction".to_string(),
60 scope: Some("scope".to_string()),
61 subject: None,
62 };
63
64 assert!(rule.validate(&message).is_none());
65 }
66
67 #[test]
68 fn test_no_subject() {
69 let rule = ScopeEmpty::default();
70 let message = Message {
71 body: None,
72 description: None,
73 footers: None,
74 r#type: Some("feat".to_string()),
75 raw: "feat: broadcast $destroy event on scope destruction".to_string(),
76 scope: None,
77 subject: None,
78 };
79
80 let violation = rule.validate(&message);
81 assert!(violation.is_some());
82 assert_eq!(violation.clone().unwrap().level, Level::Error);
83 assert_eq!(violation.unwrap().message, "scope is empty".to_string());
84 }
85
86 #[test]
87 fn test_empty_subject() {
88 let rule = ScopeEmpty::default();
89 let message = Message {
90 body: None,
91 description: None,
92 footers: None,
93 r#type: Some("feat".to_string()),
94 raw: "feat(): broadcast $destroy event on scope destruction".to_string(),
95 scope: None,
96 subject: None,
97 };
98
99 let violation = rule.validate(&message);
100 assert!(violation.is_some());
101 assert_eq!(violation.clone().unwrap().level, Level::Error);
102 assert_eq!(violation.unwrap().message, "scope is empty".to_string());
103 }
104}