1use std::fmt;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct CIContext {
9 pub provider: String,
11 pub event: String,
13 pub ref_name: String,
15 pub base_ref: Option<String>,
17 pub sha: String,
19}
20
21impl Default for CIContext {
22 fn default() -> Self {
23 Self {
24 provider: String::from("local"),
25 event: String::from("manual"),
26 ref_name: String::new(),
27 base_ref: None,
28 sha: String::new(),
29 }
30 }
31}
32
33impl fmt::Display for CIContext {
34 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35 write!(
36 f,
37 "{}/{} on {} ({})",
38 self.provider,
39 self.event,
40 self.ref_name,
41 &self.sha.get(..7).unwrap_or(&self.sha)
42 )
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 #[test]
51 fn test_ci_context_default() {
52 let ctx = CIContext::default();
53 assert_eq!(ctx.provider, "local");
54 assert_eq!(ctx.event, "manual");
55 assert!(ctx.ref_name.is_empty());
56 assert!(ctx.base_ref.is_none());
57 assert!(ctx.sha.is_empty());
58 }
59
60 #[test]
61 fn test_ci_context_display_with_long_sha() {
62 let ctx = CIContext {
63 provider: "github".to_string(),
64 event: "push".to_string(),
65 ref_name: "refs/heads/main".to_string(),
66 base_ref: None,
67 sha: "abc1234567890def".to_string(),
68 };
69 let display = format!("{ctx}");
70 assert!(display.contains("github/push"));
71 assert!(display.contains("refs/heads/main"));
72 assert!(display.contains("abc1234")); assert!(!display.contains("567890def")); }
75
76 #[test]
77 fn test_ci_context_display_with_short_sha() {
78 let ctx = CIContext {
79 provider: "gitlab".to_string(),
80 event: "merge_request".to_string(),
81 ref_name: "refs/heads/feature".to_string(),
82 base_ref: Some("refs/heads/main".to_string()),
83 sha: "abc".to_string(),
84 };
85 let display = format!("{ctx}");
86 assert!(display.contains("gitlab/merge_request"));
87 assert!(display.contains("abc")); }
89
90 #[test]
91 fn test_ci_context_equality() {
92 let ctx1 = CIContext {
93 provider: "github".to_string(),
94 event: "push".to_string(),
95 ref_name: "refs/heads/main".to_string(),
96 base_ref: None,
97 sha: "abc123".to_string(),
98 };
99 let ctx2 = ctx1.clone();
100 assert_eq!(ctx1, ctx2);
101 }
102
103 #[test]
104 fn test_ci_context_inequality() {
105 let ctx1 = CIContext::default();
106 let ctx2 = CIContext {
107 provider: "github".to_string(),
108 ..CIContext::default()
109 };
110 assert_ne!(ctx1, ctx2);
111 }
112
113 #[test]
114 fn test_ci_context_debug() {
115 let ctx = CIContext::default();
116 let debug_str = format!("{ctx:?}");
117 assert!(debug_str.contains("CIContext"));
118 assert!(debug_str.contains("local"));
119 }
120
121 #[test]
122 fn test_ci_context_with_base_ref() {
123 let ctx = CIContext {
124 provider: "github".to_string(),
125 event: "pull_request".to_string(),
126 ref_name: "refs/pull/123/head".to_string(),
127 base_ref: Some("refs/heads/main".to_string()),
128 sha: "abc1234".to_string(),
129 };
130 assert_eq!(ctx.base_ref, Some("refs/heads/main".to_string()));
131 }
132}