1use std::fmt::Debug;
4use std::time::Duration;
5use std::time::Instant;
6
7use ecow::EcoVec;
8use ecow::eco_vec;
9use typst::diag::SourceDiagnostic;
10
11use crate::doc::compare;
12use crate::doc::compile;
13
14mod annotation;
15mod id;
16pub mod template;
17pub mod unit;
18
19pub use self::annotation::Annotation;
20pub use self::annotation::ParseAnnotationError;
21pub use self::id::Id;
22pub use self::id::ParseIdError;
23pub use self::template::Test as TemplateTest;
24pub use self::unit::Test as UnitTest;
25
26#[derive(Debug, Clone, PartialEq)]
28pub enum Test {
29 Unit(UnitTest),
31
32 Template(TemplateTest),
34}
35
36impl Test {
37 pub fn id(&self) -> &Id {
39 match self {
40 Test::Unit(test) => test.id(),
41 Test::Template(test) => test.id(),
42 }
43 }
44
45 pub fn as_unit_test(&self) -> Option<&UnitTest> {
47 match self {
48 Test::Unit(test) => Some(test),
49 Test::Template(_) => None,
50 }
51 }
52
53 pub fn as_template_test(&self) -> Option<&TemplateTest> {
55 match self {
56 Test::Unit(_) => None,
57 Test::Template(test) => Some(test),
58 }
59 }
60}
61
62#[derive(Debug, Clone, Default)]
64pub enum Stage {
65 #[default]
67 Skipped,
68
69 Filtered,
73
74 FailedCompilation {
76 error: compile::Error,
78
79 reference: bool,
81 },
82
83 FailedComparison(compare::Error),
85
86 PassedCompilation,
88
89 PassedComparison,
91
92 Updated {
94 optimized: bool,
96 },
97}
98
99#[derive(Debug, Clone)]
101pub struct TestResult {
102 stage: Stage,
103 warnings: EcoVec<SourceDiagnostic>,
104 timestamp: Instant,
105 duration: Duration,
106}
107
108impl TestResult {
109 pub fn skipped() -> Self {
115 Self {
116 stage: Stage::Skipped,
117 warnings: eco_vec![],
118 timestamp: Instant::now(),
119 duration: Duration::ZERO,
120 }
121 }
122
123 pub fn filtered() -> Self {
126 Self {
127 stage: Stage::Filtered,
128 warnings: eco_vec![],
129 timestamp: Instant::now(),
130 duration: Duration::ZERO,
131 }
132 }
133}
134
135impl TestResult {
136 pub fn stage(&self) -> &Stage {
138 &self.stage
139 }
140
141 pub fn warnings(&self) -> &[SourceDiagnostic] {
143 &self.warnings
144 }
145
146 pub fn timestamp(&self) -> Instant {
148 self.timestamp
149 }
150
151 pub fn duration(&self) -> Duration {
153 self.duration
154 }
155
156 pub fn is_skipped(&self) -> bool {
158 matches!(&self.stage, Stage::Skipped)
159 }
160
161 pub fn is_filtered(&self) -> bool {
163 matches!(&self.stage, Stage::Filtered)
164 }
165
166 pub fn is_pass(&self) -> bool {
168 matches!(
169 &self.stage,
170 Stage::PassedCompilation | Stage::PassedComparison | Stage::Updated { .. }
171 )
172 }
173
174 pub fn is_fail(&self) -> bool {
176 matches!(
177 &self.stage,
178 Stage::FailedCompilation { .. } | Stage::FailedComparison(..),
179 )
180 }
181
182 pub fn errors(&self) -> Option<&[SourceDiagnostic]> {
184 match &self.stage {
185 Stage::FailedCompilation { error, .. } => Some(&error.0),
186 _ => None,
187 }
188 }
189}
190
191impl TestResult {
192 pub fn start(&mut self) {
196 self.timestamp = Instant::now();
197 }
198
199 pub fn end(&mut self) {
202 self.duration = self.timestamp.elapsed();
203 }
204
205 pub fn set_passed_compilation(&mut self) {
207 self.stage = Stage::PassedCompilation;
208 }
209
210 pub fn set_failed_reference_compilation(&mut self, error: compile::Error) {
212 self.stage = Stage::FailedCompilation {
213 error,
214 reference: true,
215 };
216 }
217
218 pub fn set_failed_test_compilation(&mut self, error: compile::Error) {
220 self.stage = Stage::FailedCompilation {
221 error,
222 reference: false,
223 };
224 }
225
226 pub fn set_passed_comparison(&mut self) {
228 self.stage = Stage::PassedComparison;
229 }
230
231 pub fn set_failed_comparison(&mut self, error: compare::Error) {
233 self.stage = Stage::FailedComparison(error);
234 }
235
236 pub fn set_updated(&mut self, optimized: bool) {
238 self.stage = Stage::Updated { optimized };
239 }
240
241 pub fn set_warnings<I>(&mut self, warnings: I)
243 where
244 I: Into<EcoVec<SourceDiagnostic>>,
245 {
246 self.warnings = warnings.into();
247 }
248}
249
250impl Default for TestResult {
251 fn default() -> Self {
252 Self::skipped()
253 }
254}