1 //! Test runner emitted events. 2 //! 3 //! Required feature: `test_unstable` since the format parsed is unstable. 4 5 use serde::Deserialize; 6 7 // See https://github.com/rust-lang/rust/tree/master/src/libtest/formatters/json.rs 8 9 /// Test-runner event. 10 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] 11 #[serde(rename_all = "snake_case")] 12 #[serde(tag = "type")] 13 pub enum Event { 14 /// Suite event. 15 Suite(Suite), 16 /// Test case event. 17 Test(Test), 18 /// Benchmark event. 19 Bench(Bench), 20 #[cfg(not(feature = "strict_unstable"))] 21 #[doc(hidden)] 22 #[serde(other)] 23 Unknown, 24 } 25 26 /// Suite event. 27 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] 28 #[serde(rename_all = "snake_case")] 29 #[serde(tag = "event")] 30 pub enum Suite { 31 /// Suite-started event. 32 Started(SuiteStarted), 33 /// Suite-finished successfully event. 34 Ok(SuiteOk), 35 /// Suite-finished with failure event. 36 Failed(SuiteFailed), 37 #[cfg(not(feature = "strict_unstable"))] 38 #[doc(hidden)] 39 #[serde(other)] 40 Unknown, 41 } 42 43 /// Suite-started event. 44 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] 45 #[non_exhaustive] 46 pub struct SuiteStarted { 47 /// Number of test cases in the suite. 48 pub test_count: usize, 49 } 50 51 /// Suite-finished successfully event. 52 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] 53 #[non_exhaustive] 54 pub struct SuiteOk { 55 /// Cases that passed. 56 pub passed: usize, 57 /// Cases that failed. 58 pub failed: usize, 59 /// Cases that were allowed to fail. 60 pub allowed_fail: usize, 61 /// Ignored cases. 62 pub ignored: usize, 63 /// Benchmarks 64 pub measured: usize, 65 /// Cases filtered out by caller. 66 pub filtered_out: usize, 67 } 68 69 /// Suite-finished with failure event. 70 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] 71 #[non_exhaustive] 72 pub struct SuiteFailed { 73 /// Cases that passed. 74 pub passed: usize, 75 /// Cases that failed. 76 pub failed: usize, 77 /// Cases that were allowed to fail. 78 pub allowed_fail: usize, 79 /// Ignored cases. 80 pub ignored: usize, 81 /// Benchmarks 82 pub measured: usize, 83 /// Cases filtered out by caller. 84 pub filtered_out: usize, 85 } 86 87 /// Test case event. 88 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] 89 #[serde(rename_all = "snake_case")] 90 #[serde(tag = "event")] 91 pub enum Test { 92 /// Case-started event. 93 Started(TestStarted), 94 /// Case-finished successfully event. 95 Ok(TestOk), 96 /// Case-finished with failure event. 97 Failed(TestFailed), 98 /// Case-ignored event. 99 Ignored(TestIgnored), 100 /// Case-allowed-failure event. 101 AllowedFailure(TestAllowedFailured), 102 /// Case-timeout event. 103 Timeout(TestTimeout), 104 #[cfg(not(feature = "strict_unstable"))] 105 #[doc(hidden)] 106 #[serde(other)] 107 Unknown, 108 } 109 110 /// Case-started event. 111 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] 112 #[non_exhaustive] 113 pub struct TestStarted { 114 /// Test case name. 115 pub name: String, 116 } 117 118 /// Case-finished successfully event. 119 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] 120 #[non_exhaustive] 121 pub struct TestOk { 122 /// Test case name. 123 pub name: String, 124 } 125 126 /// Case-finished with failure event. 127 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] 128 #[non_exhaustive] 129 pub struct TestFailed { 130 /// Test case name. 131 pub name: String, 132 /// Test's stdout 133 pub stdout: Option<String>, 134 /// Test failure mssage 135 pub message: Option<String>, 136 } 137 138 /// Case-ignored event. 139 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] 140 #[non_exhaustive] 141 pub struct TestIgnored { 142 /// Test case name. 143 pub name: String, 144 } 145 146 /// Case-allowed-failure event. 147 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] 148 #[non_exhaustive] 149 pub struct TestAllowedFailured { 150 /// Test case name. 151 pub name: String, 152 } 153 154 /// Case-timeout event. 155 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] 156 #[non_exhaustive] 157 pub struct TestTimeout { 158 /// Test case name. 159 pub name: String, 160 } 161 162 /// Benchmark event. 163 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] 164 #[non_exhaustive] 165 pub struct Bench { 166 /// Benchmark name. 167 pub name: String, 168 /// Median performance. 169 pub median: usize, 170 /// Deviation from median. 171 pub deviation: usize, 172 /// Mb/s 173 pub mib_per_second: Option<usize>, 174 } 175 176 #[cfg(test)] 177 mod tests { 178 use super::*; 179 180 #[test] suite_started()181 fn suite_started() { 182 let input = r#"{ "type": "suite", "event": "started", "test_count": 10 }"#; 183 let _data: Event = serde_json::from_str(input).unwrap(); 184 } 185 186 #[test] suite_ok()187 fn suite_ok() { 188 let input = "{ \"type\": \"suite\", \ 189 \"event\": \"ok\", \ 190 \"passed\": 6, \ 191 \"failed\": 5, \ 192 \"allowed_fail\": 4, \ 193 \"ignored\": 3, \ 194 \"measured\": 2, \ 195 \"filtered_out\": 1 }"; 196 let _data: Event = serde_json::from_str(input).unwrap(); 197 } 198 199 #[test] suite_failed()200 fn suite_failed() { 201 let input = "{ \"type\": \"suite\", \ 202 \"event\": \"failed\", \ 203 \"passed\": 6, \ 204 \"failed\": 5, \ 205 \"allowed_fail\": 4, \ 206 \"ignored\": 3, \ 207 \"measured\": 2, \ 208 \"filtered_out\": 1 }"; 209 let _data: Event = serde_json::from_str(input).unwrap(); 210 } 211 212 #[test] test_started()213 fn test_started() { 214 let input = r#"{ "type": "test", "event": "started", "name": "foo" }"#; 215 let _data: Event = serde_json::from_str(input).unwrap(); 216 } 217 218 #[test] test_timeout()219 fn test_timeout() { 220 let input = r#"{ "type": "test", "event": "timeout", "name": "foo" }"#; 221 let _data: Event = serde_json::from_str(input).unwrap(); 222 } 223 224 #[test] bench()225 fn bench() { 226 let input = "{ \"type\": \"bench\", \ 227 \"name\": \"foo\", \ 228 \"median\": 10, \ 229 \"deviation\": 2 }"; 230 let _data: Event = serde_json::from_str(input).unwrap(); 231 } 232 233 #[test] bench_full()234 fn bench_full() { 235 let input = "{ \"type\": \"bench\", \ 236 \"name\": \"foo\", \ 237 \"median\": 10, \ 238 \"deviation\": 2, \ 239 \"mib_per_second\": 1 }"; 240 let _data: Event = serde_json::from_str(input).unwrap(); 241 } 242 } 243