diff --git a/crates/libtest-json/Cargo.toml b/crates/libtest-json/Cargo.toml index 775002e..9943063 100644 --- a/crates/libtest-json/Cargo.toml +++ b/crates/libtest-json/Cargo.toml @@ -36,6 +36,7 @@ schemars = { version = "1.0.0-alpha.17", features = ["preserve_order", "semver1" [dev-dependencies] snapbox = "0.6.21" +serde_json = "1.0.96" [lints] workspace = true diff --git a/crates/libtest-json/event.schema.json b/crates/libtest-json/event.schema.json index 218a358..0bb3b39 100644 --- a/crates/libtest-json/event.schema.json +++ b/crates/libtest-json/event.schema.json @@ -7,7 +7,7 @@ "properties": { "event": { "type": "string", - "const": "discover-start" + "const": "discover_start" } }, "required": [ @@ -24,34 +24,39 @@ "$ref": "#/$defs/RunMode" }, "run": { + "description": "Whether selected to be run by the user", "type": "boolean" }, "event": { "type": "string", - "const": "discover-case" + "const": "discover_case" } }, "required": [ "event", - "name", - "mode", - "run" + "name" ] }, { "type": "object", "properties": { "elapsed_s": { - "$ref": "#/$defs/Elapsed" + "anyOf": [ + { + "$ref": "#/$defs/Elapsed" + }, + { + "type": "null" + } + ] }, "event": { "type": "string", - "const": "discover-complete" + "const": "discover_complete" } }, "required": [ - "event", - "elapsed_s" + "event" ] }, { @@ -59,7 +64,7 @@ "properties": { "event": { "type": "string", - "const": "suite-start" + "const": "suite_start" } }, "required": [ @@ -74,7 +79,7 @@ }, "event": { "type": "string", - "const": "case-start" + "const": "case_start" } }, "required": [ @@ -92,6 +97,7 @@ "$ref": "#/$defs/RunMode" }, "status": { + "description": "`None` means success", "anyOf": [ { "$ref": "#/$defs/RunStatus" @@ -119,29 +125,34 @@ }, "event": { "type": "string", - "const": "case-complete" + "const": "case_complete" } }, "required": [ "event", - "name", - "mode" + "name" ] }, { "type": "object", "properties": { "elapsed_s": { - "$ref": "#/$defs/Elapsed" + "anyOf": [ + { + "$ref": "#/$defs/Elapsed" + }, + { + "type": "null" + } + ] }, "event": { "type": "string", - "const": "suite-complete" + "const": "suite_complete" } }, "required": [ - "event", - "elapsed_s" + "event" ] } ], @@ -154,26 +165,7 @@ ] }, "Elapsed": { - "$ref": "#/$defs/Duration" - }, - "Duration": { - "type": "object", - "properties": { - "secs": { - "type": "integer", - "format": "uint64", - "minimum": 0 - }, - "nanos": { - "type": "integer", - "format": "uint32", - "minimum": 0 - } - }, - "required": [ - "secs", - "nanos" - ] + "type": "string" }, "RunStatus": { "type": "string", diff --git a/crates/libtest-json/src/event.rs b/crates/libtest-json/src/event.rs index 036281c..e8bdc46 100644 --- a/crates/libtest-json/src/event.rs +++ b/crates/libtest-json/src/event.rs @@ -1,18 +1,30 @@ #[derive(Clone, Debug)] #[cfg_attr(feature = "unstable-schema", derive(schemars::JsonSchema))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] #[cfg_attr(feature = "serde", serde(tag = "event"))] pub enum Event { DiscoverStart, DiscoverCase { name: String, + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "RunMode::is_default") + )] mode: RunMode, + /// Whether selected to be run by the user + #[cfg_attr( + feature = "serde", + serde(default = "true_default", skip_serializing_if = "is_true") + )] run: bool, }, DiscoverComplete { - #[allow(dead_code)] - elapsed_s: Elapsed, + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Option::is_none") + )] + elapsed_s: Option, }, SuiteStart, CaseStart { @@ -20,15 +32,34 @@ pub enum Event { }, CaseComplete { name: String, - #[allow(dead_code)] + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "RunMode::is_default") + )] mode: RunMode, + /// `None` means success + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Option::is_none") + )] status: Option, + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Option::is_none") + )] message: Option, - #[allow(dead_code)] + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Option::is_none") + )] elapsed_s: Option, }, SuiteComplete { - elapsed_s: Elapsed, + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Option::is_none") + )] + elapsed_s: Option, }, } @@ -39,10 +70,18 @@ impl Event { } } +fn true_default() -> bool { + true +} + +fn is_true(yes: &bool) -> bool { + *yes +} + #[derive(Copy, Clone, Default, Debug, PartialEq, Eq)] #[cfg_attr(feature = "unstable-schema", derive(schemars::JsonSchema))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] pub enum RunMode { #[default] Test, @@ -56,12 +95,16 @@ impl RunMode { Self::Bench => "bench", } } + + fn is_default(&self) -> bool { + *self == Default::default() + } } #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "unstable-schema", derive(schemars::JsonSchema))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] -#[cfg_attr(feature = "serde", serde(rename_all = "kebab-case"))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] pub enum RunStatus { Ignored, Failed, @@ -69,8 +112,9 @@ pub enum RunStatus { #[derive(Copy, Clone, Default, Debug, PartialEq, Eq)] #[cfg_attr(feature = "unstable-schema", derive(schemars::JsonSchema))] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(into = "String"))] +#[cfg_attr(feature = "serde", serde(try_from = "String"))] pub struct Elapsed(pub std::time::Duration); impl std::fmt::Display for Elapsed { @@ -79,6 +123,23 @@ impl std::fmt::Display for Elapsed { } } +impl std::str::FromStr for Elapsed { + type Err = std::num::ParseFloatError; + + fn from_str(src: &str) -> Result { + let secs = src.parse()?; + Ok(Elapsed(std::time::Duration::from_secs_f64(secs))) + } +} + +impl TryFrom for Elapsed { + type Error = std::num::ParseFloatError; + + fn try_from(inner: String) -> Result { + inner.parse() + } +} + impl From for String { fn from(elapsed: Elapsed) -> Self { elapsed.0.as_secs_f64().to_string() diff --git a/crates/libtest-json/tests/roundtrip.rs b/crates/libtest-json/tests/roundtrip.rs new file mode 100644 index 0000000..6a78208 --- /dev/null +++ b/crates/libtest-json/tests/roundtrip.rs @@ -0,0 +1,119 @@ +#![cfg(feature = "serde")] +#![cfg(feature = "json")] + +use snapbox::prelude::*; +use snapbox::str; + +#[track_caller] +fn t(input: libtest_json::Event, snapshot: impl IntoData) { + let actual_encoded = input.to_jsonline(); + let expected_encoded = serde_json::to_string(&input).unwrap(); + snapbox::assert_data_eq!(&actual_encoded, expected_encoded.raw()); + snapbox::assert_data_eq!(&actual_encoded, snapshot.raw()); + + let _ = serde_json::from_str::(&actual_encoded).unwrap(); +} + +#[test] +fn discover_start() { + t( + libtest_json::Event::DiscoverStart, + str![[r#"{"event":"discover_start"}"#]], + ); +} + +#[test] +fn discover_case() { + t( + libtest_json::Event::DiscoverCase { + name: "Hello\tworld!".to_owned(), + mode: libtest_json::RunMode::Test, + run: true, + }, + str![[r#"{"event":"discover_case","name":"Hello\tworld!"}"#]], + ); + + t( + libtest_json::Event::DiscoverCase { + name: "Hello\tworld!".to_owned(), + mode: libtest_json::RunMode::Bench, + run: false, + }, + str![[r#"{"event":"discover_case","name":"Hello\tworld!","mode":"bench","run":false}"#]], + ); +} + +#[test] +fn discover_complete() { + t( + libtest_json::Event::DiscoverComplete { elapsed_s: None }, + str![[r#"{"event":"discover_complete"}"#]], + ); + + t( + libtest_json::Event::DiscoverComplete { + elapsed_s: Some(libtest_json::Elapsed(Default::default())), + }, + str![[r#"{"event":"discover_complete","elapsed_s":"0"}"#]], + ); +} + +#[test] +fn suite_start() { + t( + libtest_json::Event::SuiteStart, + str![[r#"{"event":"suite_start"}"#]], + ); +} + +#[test] +fn case_start() { + t( + libtest_json::Event::CaseStart { + name: "Hello\tworld!".to_owned(), + }, + str![[r#"{"event":"case_start","name":"Hello\tworld!"}"#]], + ); +} + +#[test] +fn case_complete() { + t( + libtest_json::Event::CaseComplete { + name: "Hello\tworld!".to_owned(), + mode: libtest_json::RunMode::Test, + status: None, + message: None, + elapsed_s: None, + }, + str![[r#"{"event":"case_complete","name":"Hello\tworld!"}"#]], + ); + + t( + libtest_json::Event::CaseComplete { + name: "Hello\tworld!".to_owned(), + mode: libtest_json::RunMode::Bench, + status: Some(libtest_json::RunStatus::Ignored), + message: Some("This\tfailed".to_owned()), + elapsed_s: Some(libtest_json::Elapsed(Default::default())), + }, + str![[ + r#"{"event":"case_complete","name":"Hello\tworld!","mode":"bench","status":"ignored","message":"This\tfailed","elapsed_s":"0"}"# + ]], + ); +} + +#[test] +fn suite_complete() { + t( + libtest_json::Event::SuiteComplete { elapsed_s: None }, + str![[r#"{"event":"suite_complete"}"#]], + ); + + t( + libtest_json::Event::SuiteComplete { + elapsed_s: Some(libtest_json::Elapsed(Default::default())), + }, + str![[r#"{"event":"suite_complete","elapsed_s":"0"}"#]], + ); +} diff --git a/crates/libtest2-harness/src/harness.rs b/crates/libtest2-harness/src/harness.rs index 432cd97..9d0d83e 100644 --- a/crates/libtest2-harness/src/harness.rs +++ b/crates/libtest2-harness/src/harness.rs @@ -233,7 +233,7 @@ fn discover( cases.retain(|_| retain_cases.next().unwrap()); notifier.notify(notify::Event::DiscoverComplete { - elapsed_s: notify::Elapsed(timer.elapsed()), + elapsed_s: Some(notify::Elapsed(timer.elapsed())), })?; Ok(()) @@ -389,7 +389,7 @@ fn run( } notifier.notify(notify::Event::SuiteComplete { - elapsed_s: notify::Elapsed(timer.elapsed()), + elapsed_s: Some(notify::Elapsed(timer.elapsed())), })?; Ok(success) diff --git a/crates/libtest2-harness/src/notify/summary.rs b/crates/libtest2-harness/src/notify/summary.rs index 4f72aa9..0ae5c4d 100644 --- a/crates/libtest2-harness/src/notify/summary.rs +++ b/crates/libtest2-harness/src/notify/summary.rs @@ -6,7 +6,7 @@ use super::OK; #[derive(Default, Clone, Debug)] pub(crate) struct Summary { pub(crate) failures: std::collections::BTreeMap>, - pub(crate) elapsed_s: super::Elapsed, + pub(crate) elapsed_s: Option, pub(crate) num_run: usize, /// Number of tests and benchmarks that were filtered out (either by the @@ -68,10 +68,15 @@ impl Summary { } } writeln!(writer)?; + let finished = if let Some(elapsed_s) = elapsed_s { + format!("; finished in {elapsed_s}") + } else { + "".to_owned() + }; writeln!( writer, "test result: {summary_style}{summary}{summary_style:#}. {num_passed} passed; {num_failed} failed; {num_ignored} ignored; \ - {num_filtered_out} filtered out; finished in {elapsed_s}", + {num_filtered_out} filtered out{finished}", )?; writeln!(writer)?; diff --git a/crates/libtest2-mimic/tests/testsuite/mixed_bag.rs b/crates/libtest2-mimic/tests/testsuite/mixed_bag.rs index b95d7eb..ffce1f1 100644 --- a/crates/libtest2-mimic/tests/testsuite/mixed_bag.rs +++ b/crates/libtest2-mimic/tests/testsuite/mixed_bag.rs @@ -706,59 +706,49 @@ fn list_json() { str![[r#" [ { - "event": "discover-start" + "event": "discover_start" }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "bunny", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "dog", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "fly", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "fox", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "frog", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "owl", "run": false }, { - "event": "discover-case", - "mode": "test", - "name": "bear", - "run": true + "event": "discover_case", + "name": "bear" }, { - "event": "discover-case", - "mode": "test", - "name": "cat", - "run": true + "event": "discover_case", + "name": "cat" }, { "elapsed_s": "[..]", - "event": "discover-complete" + "event": "discover_complete" } ] "#]] @@ -767,59 +757,49 @@ fn list_json() { str![[r#" [ { - "event": "discover-start" + "event": "discover_start" }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "bunny", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "dog", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "fly", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "fox", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "frog", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "owl", "run": false }, { - "event": "discover-case", - "mode": "test", - "name": "bear", - "run": true + "event": "discover_case", + "name": "bear" }, { - "event": "discover-case", - "mode": "test", - "name": "cat", - "run": true + "event": "discover_case", + "name": "cat" }, { "elapsed_s": "[..]", - "event": "discover-complete" + "event": "discover_complete" } ] "#]] @@ -837,90 +817,76 @@ fn test_json() { str![[r#" [ { - "event": "discover-start" + "event": "discover_start" }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "bunny", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "dog", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "fly", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "fox", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "frog", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "owl", "run": false }, { - "event": "discover-case", - "mode": "test", - "name": "bear", - "run": true + "event": "discover_case", + "name": "bear" }, { - "event": "discover-case", - "mode": "test", - "name": "cat", - "run": true + "event": "discover_case", + "name": "cat" }, { "elapsed_s": "[..]", - "event": "discover-complete" + "event": "discover_complete" }, { - "event": "suite-start" + "event": "suite_start" }, { - "event": "case-start", + "event": "case_start", "name": "bear" }, { "elapsed_s": "[..]", - "event": "case-complete", + "event": "case_complete", "message": "fails", - "mode": "test", "name": "bear", "status": "ignored" }, { - "event": "case-start", + "event": "case_start", "name": "cat" }, { "elapsed_s": "[..]", - "event": "case-complete", - "message": null, - "mode": "test", - "name": "cat", - "status": null + "event": "case_complete", + "name": "cat" }, { "elapsed_s": "[..]", - "event": "suite-complete" + "event": "suite_complete" } ] "#]] @@ -929,90 +895,76 @@ fn test_json() { str![[r#" [ { - "event": "discover-start" + "event": "discover_start" }, { - "event": "discover-case", - "mode": "test", - "name": "bear", - "run": true + "event": "discover_case", + "name": "bear" }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "bunny", "run": false }, { - "event": "discover-case", - "mode": "test", - "name": "cat", - "run": true + "event": "discover_case", + "name": "cat" }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "dog", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "fly", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "fox", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "frog", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "owl", "run": false }, { "elapsed_s": "[..]", - "event": "discover-complete" + "event": "discover_complete" }, { - "event": "suite-start" + "event": "suite_start" }, { - "event": "case-start", + "event": "case_start", "name": "bear" }, { "elapsed_s": "[..]", - "event": "case-complete", + "event": "case_complete", "message": "fails", - "mode": "test", "name": "bear", "status": "ignored" }, { - "event": "case-start", + "event": "case_start", "name": "cat" }, { "elapsed_s": "[..]", - "event": "case-complete", - "message": null, - "mode": "test", - "name": "cat", - "status": null + "event": "case_complete", + "name": "cat" }, { "elapsed_s": "[..]", - "event": "suite-complete" + "event": "suite_complete" } ] "#]] diff --git a/crates/libtest2/tests/testsuite/mixed_bag.rs b/crates/libtest2/tests/testsuite/mixed_bag.rs index c46391a..89e8c17 100644 --- a/crates/libtest2/tests/testsuite/mixed_bag.rs +++ b/crates/libtest2/tests/testsuite/mixed_bag.rs @@ -713,59 +713,49 @@ fn list_json() { str![[r#" [ { - "event": "discover-start" + "event": "discover_start" }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "bunny", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "dog", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "fly", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "fox", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "frog", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "owl", "run": false }, { - "event": "discover-case", - "mode": "test", - "name": "bear", - "run": true + "event": "discover_case", + "name": "bear" }, { - "event": "discover-case", - "mode": "test", - "name": "cat", - "run": true + "event": "discover_case", + "name": "cat" }, { "elapsed_s": "[..]", - "event": "discover-complete" + "event": "discover_complete" } ] "#]] @@ -774,59 +764,49 @@ fn list_json() { str![[r#" [ { - "event": "discover-start" + "event": "discover_start" }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "bunny", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "dog", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "fly", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "fox", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "frog", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "owl", "run": false }, { - "event": "discover-case", - "mode": "test", - "name": "bear", - "run": true + "event": "discover_case", + "name": "bear" }, { - "event": "discover-case", - "mode": "test", - "name": "cat", - "run": true + "event": "discover_case", + "name": "cat" }, { "elapsed_s": "[..]", - "event": "discover-complete" + "event": "discover_complete" } ] "#]] @@ -844,90 +824,76 @@ fn test_json() { str![[r#" [ { - "event": "discover-start" + "event": "discover_start" }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "bunny", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "dog", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "fly", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "fox", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "frog", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "owl", "run": false }, { - "event": "discover-case", - "mode": "test", - "name": "bear", - "run": true + "event": "discover_case", + "name": "bear" }, { - "event": "discover-case", - "mode": "test", - "name": "cat", - "run": true + "event": "discover_case", + "name": "cat" }, { "elapsed_s": "[..]", - "event": "discover-complete" + "event": "discover_complete" }, { - "event": "suite-start" + "event": "suite_start" }, { - "event": "case-start", + "event": "case_start", "name": "bear" }, { "elapsed_s": "[..]", - "event": "case-complete", + "event": "case_complete", "message": "fails", - "mode": "test", "name": "bear", "status": "ignored" }, { - "event": "case-start", + "event": "case_start", "name": "cat" }, { "elapsed_s": "[..]", - "event": "case-complete", - "message": null, - "mode": "test", - "name": "cat", - "status": null + "event": "case_complete", + "name": "cat" }, { "elapsed_s": "[..]", - "event": "suite-complete" + "event": "suite_complete" } ] "#]] @@ -936,90 +902,76 @@ fn test_json() { str![[r#" [ { - "event": "discover-start" + "event": "discover_start" }, { - "event": "discover-case", - "mode": "test", - "name": "bear", - "run": true + "event": "discover_case", + "name": "bear" }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "bunny", "run": false }, { - "event": "discover-case", - "mode": "test", - "name": "cat", - "run": true + "event": "discover_case", + "name": "cat" }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "dog", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "fly", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "fox", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "frog", "run": false }, { - "event": "discover-case", - "mode": "test", + "event": "discover_case", "name": "owl", "run": false }, { "elapsed_s": "[..]", - "event": "discover-complete" + "event": "discover_complete" }, { - "event": "suite-start" + "event": "suite_start" }, { - "event": "case-start", + "event": "case_start", "name": "bear" }, { "elapsed_s": "[..]", - "event": "case-complete", + "event": "case_complete", "message": "fails", - "mode": "test", "name": "bear", "status": "ignored" }, { - "event": "case-start", + "event": "case_start", "name": "cat" }, { "elapsed_s": "[..]", - "event": "case-complete", - "message": null, - "mode": "test", - "name": "cat", - "status": null + "event": "case_complete", + "name": "cat" }, { "elapsed_s": "[..]", - "event": "suite-complete" + "event": "suite_complete" } ] "#]]