clnrm_core/formatting/
test_result.rs1use std::time::Duration;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
10pub enum TestStatus {
11 Passed,
13 Failed,
15 Skipped,
17 Unknown,
19}
20
21#[derive(Debug, Clone)]
23pub struct TestResult {
24 pub name: String,
26 pub status: TestStatus,
28 pub duration: Option<Duration>,
30 pub error: Option<String>,
32 pub stdout: Option<String>,
34 pub stderr: Option<String>,
36 pub metadata: std::collections::HashMap<String, String>,
38}
39
40impl TestResult {
41 pub fn passed(name: impl Into<String>) -> Self {
43 Self {
44 name: name.into(),
45 status: TestStatus::Passed,
46 duration: None,
47 error: None,
48 stdout: None,
49 stderr: None,
50 metadata: std::collections::HashMap::new(),
51 }
52 }
53
54 pub fn failed(name: impl Into<String>, error: impl Into<String>) -> Self {
56 Self {
57 name: name.into(),
58 status: TestStatus::Failed,
59 duration: None,
60 error: Some(error.into()),
61 stdout: None,
62 stderr: None,
63 metadata: std::collections::HashMap::new(),
64 }
65 }
66
67 pub fn skipped(name: impl Into<String>) -> Self {
69 Self {
70 name: name.into(),
71 status: TestStatus::Skipped,
72 duration: None,
73 error: None,
74 stdout: None,
75 stderr: None,
76 metadata: std::collections::HashMap::new(),
77 }
78 }
79
80 pub fn with_duration(mut self, duration: Duration) -> Self {
82 self.duration = Some(duration);
83 self
84 }
85
86 pub fn with_stdout(mut self, stdout: impl Into<String>) -> Self {
88 self.stdout = Some(stdout.into());
89 self
90 }
91
92 pub fn with_stderr(mut self, stderr: impl Into<String>) -> Self {
94 self.stderr = Some(stderr.into());
95 self
96 }
97
98 pub fn with_metadata(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
100 self.metadata.insert(key.into(), value.into());
101 self
102 }
103
104 pub fn is_passed(&self) -> bool {
106 self.status == TestStatus::Passed
107 }
108
109 pub fn is_failed(&self) -> bool {
111 self.status == TestStatus::Failed
112 }
113
114 pub fn is_skipped(&self) -> bool {
116 self.status == TestStatus::Skipped
117 }
118}
119
120#[derive(Debug, Clone)]
122pub struct TestSuite {
123 pub name: String,
125 pub results: Vec<TestResult>,
127 pub duration: Option<Duration>,
129 pub metadata: std::collections::HashMap<String, String>,
131}
132
133impl TestSuite {
134 pub fn new(name: impl Into<String>) -> Self {
136 Self {
137 name: name.into(),
138 results: Vec::new(),
139 duration: None,
140 metadata: std::collections::HashMap::new(),
141 }
142 }
143
144 pub fn add_result(mut self, result: TestResult) -> Self {
146 self.results.push(result);
147 self
148 }
149
150 pub fn with_duration(mut self, duration: Duration) -> Self {
152 self.duration = Some(duration);
153 self
154 }
155
156 pub fn with_metadata(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
158 self.metadata.insert(key.into(), value.into());
159 self
160 }
161
162 pub fn passed_count(&self) -> usize {
164 self.results.iter().filter(|r| r.is_passed()).count()
165 }
166
167 pub fn failed_count(&self) -> usize {
169 self.results.iter().filter(|r| r.is_failed()).count()
170 }
171
172 pub fn skipped_count(&self) -> usize {
174 self.results.iter().filter(|r| r.is_skipped()).count()
175 }
176
177 pub fn total_count(&self) -> usize {
179 self.results.len()
180 }
181
182 pub fn is_success(&self) -> bool {
184 self.failed_count() == 0 && self.total_count() > 0
185 }
186}