1use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
7use nextest_metadata::{BuildPlatform, FilterMatch, RustBinaryId};
8
9#[derive(Clone, Debug)]
10pub struct TestSuiteFixture {
11 pub binary_id: RustBinaryId,
12 pub binary_name: &'static str,
13 pub build_platform: BuildPlatform,
14 pub test_cases: IdOrdMap<TestCaseFixture>,
15 properties: u64,
16}
17
18impl IdOrdItem for TestSuiteFixture {
19 type Key<'a> = &'a RustBinaryId;
20 fn key(&self) -> Self::Key<'_> {
21 &self.binary_id
22 }
23 id_upcast!();
24}
25
26impl TestSuiteFixture {
27 pub fn new(
28 binary_id: &'static str,
29 binary_name: &'static str,
30 build_platform: BuildPlatform,
31 test_cases: IdOrdMap<TestCaseFixture>,
32 ) -> Self {
33 Self {
34 binary_id: binary_id.into(),
35 binary_name,
36 build_platform,
37 test_cases,
38 properties: 0,
39 }
40 }
41
42 pub fn with_property(mut self, property: TestSuiteFixtureProperty) -> Self {
43 self.properties |= property as u64;
44 self
45 }
46
47 pub fn has_property(&self, property: TestSuiteFixtureProperty) -> bool {
48 self.properties & property as u64 != 0
49 }
50
51 pub fn assert_test_cases_match(&self, other: &IdOrdMap<TestNameAndFilterMatch<'_>>) {
52 if self.test_cases.len() != other.len() {
53 panic!(
54 "test cases mismatch: expected {} test cases, found {}; \
55 expected: {self:#?}, actual: {other:#?}",
56 self.test_cases.len(),
57 other.len(),
58 );
59 }
60
61 for name_and_filter_match in other {
62 if let Some(test_case) = self.test_cases.get(name_and_filter_match.name) {
63 if test_case.status.is_ignored() == name_and_filter_match.filter_match.is_match() {
64 panic!(
65 "test case status mismatch for '{}': expected {:?}, found {:?}; \
66 expected: {self:#?}, actual: {other:#?}",
67 name_and_filter_match.name,
68 test_case.status,
69 name_and_filter_match.filter_match,
70 );
71 }
72 } else {
73 panic!(
74 "test case '{}' not found in test suite '{}'; \
75 expected: {self:#?}, actual: {other:#?}",
76 name_and_filter_match.name, self.binary_name,
77 );
78 }
79 }
80 }
81}
82
83#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
84#[repr(u64)]
85pub enum TestSuiteFixtureProperty {
86 NotInDefaultSet = 1,
87}
88
89#[derive(Clone, Debug)]
90pub struct TestCaseFixture {
91 pub name: &'static str,
92 pub status: TestCaseFixtureStatus,
93 properties: u64,
94}
95
96impl IdOrdItem for TestCaseFixture {
97 type Key<'a> = &'static str;
98 fn key(&self) -> Self::Key<'_> {
99 self.name
100 }
101 id_upcast!();
102}
103
104impl TestCaseFixture {
105 pub fn new(name: &'static str, status: TestCaseFixtureStatus) -> Self {
106 Self {
107 name,
108 status,
109 properties: 0,
110 }
111 }
112
113 pub fn with_property(mut self, property: TestCaseFixtureProperty) -> Self {
114 self.properties |= property as u64;
115 self
116 }
117
118 pub fn has_property(&self, property: TestCaseFixtureProperty) -> bool {
119 self.properties & property as u64 != 0
120 }
121}
122
123#[derive(Clone, Debug)]
124pub struct TestNameAndFilterMatch<'a> {
125 pub name: &'a str,
126 pub filter_match: FilterMatch,
127}
128
129impl<'a> IdOrdItem for TestNameAndFilterMatch<'a> {
130 type Key<'k>
131 = &'a str
132 where
133 Self: 'k;
134 fn key(&self) -> Self::Key<'_> {
135 self.name
136 }
137 id_upcast!();
138}
139
140impl PartialEq<TestNameAndFilterMatch<'_>> for TestCaseFixture {
143 fn eq(&self, other: &TestNameAndFilterMatch<'_>) -> bool {
144 self.name == other.name && self.status.is_ignored() != other.filter_match.is_match()
145 }
146}
147
148#[derive(Copy, Clone, Debug, Eq, PartialEq)]
149pub enum TestCaseFixtureStatus {
150 Pass,
151 Fail,
152 Flaky { pass_attempt: usize },
153 Leak,
154 LeakFail,
155 FailLeak,
156 Segfault,
157 IgnoredPass,
158 IgnoredFail,
159}
160
161impl TestCaseFixtureStatus {
162 pub fn is_ignored(self) -> bool {
163 matches!(
164 self,
165 TestCaseFixtureStatus::IgnoredPass | TestCaseFixtureStatus::IgnoredFail
166 )
167 }
168}
169
170#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
171#[repr(u64)]
172pub enum TestCaseFixtureProperty {
173 NeedsSameCwd = 1,
174 NotInDefaultSet = 2,
175 MatchesCdylib = 4,
176 MatchesTestMultiplyTwo = 8,
177 NotInDefaultSetUnix = 16,
178}