diff --git a/DESIGN.md b/DESIGN.md index f454ca6..84c1f7a 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -38,6 +38,7 @@ Decisions - There is likely not enough value add in the failure message - This puts more of a burden on custom test harnesses for their implementation than is strictly needed - Report failures separate from test-complete so we can have multiple +- `DiscoverCase` order is unspecified so we can report them as found rather than waiting for a sort phase so users can identify slow discovery ### Prior Art diff --git a/crates/libtest-json/event.schema.json b/crates/libtest-json/event.schema.json index efff322..f0fafd1 100644 --- a/crates/libtest-json/event.schema.json +++ b/crates/libtest-json/event.schema.json @@ -135,6 +135,7 @@ ] }, "DiscoverCase": { + "description": "A test case was found\n\nThe order these are returned in is unspecified and is unrelated to the order they are run in.", "type": "object", "properties": { "name": { diff --git a/crates/libtest-json/src/event.rs b/crates/libtest-json/src/event.rs index 68132f5..5a7e7bc 100644 --- a/crates/libtest-json/src/event.rs +++ b/crates/libtest-json/src/event.rs @@ -115,6 +115,9 @@ impl DiscoverStart { } } +/// A test case was found +/// +/// The order these are returned in is unspecified and is unrelated to the order they are run in. #[derive(Clone, Debug)] #[cfg_attr(feature = "unstable-schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] diff --git a/crates/libtest2-harness/src/harness.rs b/crates/libtest2-harness/src/harness.rs index 20cfcff..d1f3897 100644 --- a/crates/libtest2-harness/src/harness.rs +++ b/crates/libtest2-harness/src/harness.rs @@ -93,22 +93,49 @@ impl Harness { mut self, cases: impl IntoIterator, ) -> std::io::Result> { - let mut cases = cases - .into_iter() - .map(|c| Box::new(c) as Box) - .collect(); - discover( - &self.state.start, - &self.state.opts, - &mut cases, - self.state.notifier.as_mut(), + self.state.notifier.notify( + notify::event::DiscoverStart { + elapsed_s: Some(notify::Elapsed(self.state.start.elapsed())), + } + .into(), + )?; + + let mut selected_cases = Vec::new(); + for case in cases { + let selected = case_priority(&case, &self.state.opts).is_some(); + self.state.notifier.notify( + notify::event::DiscoverCase { + name: case.name().to_owned(), + mode: RunMode::Test, + selected, + elapsed_s: Some(notify::Elapsed(self.state.start.elapsed())), + } + .into(), + )?; + if selected { + selected_cases.push(Box::new(case) as Box); + } + } + + selected_cases.sort_unstable_by_key(|case| { + let priority = case_priority(case.as_ref(), &self.state.opts); + let name = case.name().to_owned(); + (priority, name) + }); + + self.state.notifier.notify( + notify::event::DiscoverComplete { + elapsed_s: Some(notify::Elapsed(self.state.start.elapsed())), + } + .into(), )?; + Ok(Harness { state: StateDiscovered { start: self.state.start, opts: self.state.opts, notifier: self.state.notifier, - cases, + cases: selected_cases, }, }) } @@ -238,73 +265,27 @@ fn notifier(opts: &libtest_lexarg::TestOpts) -> Box { } } -fn discover( - start: &std::time::Instant, - opts: &libtest_lexarg::TestOpts, - cases: &mut Vec>, - notifier: &mut dyn notify::Notifier, -) -> std::io::Result<()> { - notifier.notify( - notify::event::DiscoverStart { - elapsed_s: Some(notify::Elapsed(start.elapsed())), - } - .into(), - )?; - - let matches_filter = |case: &dyn Case, filter: &str| { - let test_name = case.name(); - - match opts.filter_exact { - true => test_name == filter, - false => test_name.contains(filter), - } - }; - - // Do this first so it applies to both discover and running - cases.sort_unstable_by_key(|case| { - let priority = if opts.filters.is_empty() { - Some(0) - } else { - opts.filters - .iter() - .position(|filter| matches_filter(case.as_ref(), filter)) - }; - let name = case.name().to_owned(); - (priority, name) - }); - - let mut retain_cases = Vec::with_capacity(cases.len()); - for case in cases.iter() { - let filtered_in = opts.filters.is_empty() - || opts - .filters - .iter() - .any(|filter| matches_filter(case.as_ref(), filter)); - let filtered_out = - !opts.skip.is_empty() && opts.skip.iter().any(|sf| matches_filter(case.as_ref(), sf)); - let retain_case = filtered_in && !filtered_out; - retain_cases.push(retain_case); - notifier.notify( - notify::event::DiscoverCase { - name: case.name().to_owned(), - mode: RunMode::Test, - selected: retain_case, - elapsed_s: Some(notify::Elapsed(start.elapsed())), - } - .into(), - )?; +fn case_priority(case: &dyn Case, opts: &libtest_lexarg::TestOpts) -> Option { + let filtered_out = + !opts.skip.is_empty() && opts.skip.iter().any(|sf| matches_filter(case, sf, opts)); + if filtered_out { + None + } else if opts.filters.is_empty() { + Some(0) + } else { + opts.filters + .iter() + .position(|filter| matches_filter(case, filter, opts)) } - let mut retain_cases = retain_cases.into_iter(); - cases.retain(|_| retain_cases.next().unwrap()); +} - notifier.notify( - notify::event::DiscoverComplete { - elapsed_s: Some(notify::Elapsed(start.elapsed())), - } - .into(), - )?; +fn matches_filter(case: &dyn Case, filter: &str, opts: &libtest_lexarg::TestOpts) -> bool { + let test_name = case.name(); - Ok(()) + match opts.filter_exact { + true => test_name == filter, + false => test_name.contains(filter), + } } fn run( diff --git a/crates/libtest2-mimic/tests/testsuite/argfile.rs b/crates/libtest2-mimic/tests/testsuite/argfile.rs index 720fc63..8e14d77 100644 --- a/crates/libtest2-mimic/tests/testsuite/argfile.rs +++ b/crates/libtest2-mimic/tests/testsuite/argfile.rs @@ -90,9 +90,9 @@ fn list() { 0, str![[r#" one: test -one_two: test -three: test two: test +three: test +one_two: test 4 tests @@ -100,7 +100,7 @@ two: test "#]], str![[r#" one: test -one_two: test +two: test ... 4 tests diff --git a/crates/libtest2-mimic/tests/testsuite/mixed_bag.rs b/crates/libtest2-mimic/tests/testsuite/mixed_bag.rs index 1d124ee..1d1f7c9 100644 --- a/crates/libtest2-mimic/tests/testsuite/mixed_bag.rs +++ b/crates/libtest2-mimic/tests/testsuite/mixed_bag.rs @@ -220,28 +220,28 @@ fn list() { &["--list"], 0, str![[r#" -bear: test -bunny: test cat: test dog: test -fly: test fox: test +bunny: test frog: test owl: test +fly: test +bear: test 8 tests "#]], str![[r#" -bear: test -bunny: test cat: test dog: test -fly: test fox: test +bunny: test frog: test owl: test +fly: test +bear: test 8 tests @@ -256,28 +256,28 @@ fn list_ignored() { &["--list", "--ignored"], 0, str![[r#" -bear: test -bunny: test cat: test dog: test -fly: test fox: test +bunny: test frog: test owl: test +fly: test +bear: test 8 tests "#]], str![[r#" -bear: test -bunny: test cat: test dog: test -fly: test fox: test +bunny: test frog: test owl: test +fly: test +bear: test 8 tests @@ -292,16 +292,16 @@ fn list_with_filter() { &["--list", "a"], 0, str![[r#" -bear: test cat: test +bear: test 2 tests "#]], str![[r#" -bear: test cat: test +bear: test 2 tests @@ -316,20 +316,20 @@ fn list_with_specified_order() { &["--list", "--exact", "owl", "fox", "bunny", "frog"], 0, str![[r#" -owl: test fox: test bunny: test frog: test +owl: test 4 tests "#]], str![[r#" -owl: test fox: test bunny: test frog: test +owl: test 4 tests @@ -705,58 +705,58 @@ fn list_json() { str![[r#" [ { - "event": "discover_start", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "discover_start" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "bunny", - "selected": false, - "elapsed_s": "[..]" + "name": "cat" }, { + "elapsed_s": "[..]", "event": "discover_case", "name": "dog", - "selected": false, - "elapsed_s": "[..]" + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "fly", - "selected": false, - "elapsed_s": "[..]" + "name": "fox", + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "fox", - "selected": false, - "elapsed_s": "[..]" + "name": "bunny", + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", "name": "frog", - "selected": false, - "elapsed_s": "[..]" + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", "name": "owl", - "selected": false, - "elapsed_s": "[..]" + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "bear", - "elapsed_s": "[..]" + "name": "fly", + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "cat", - "elapsed_s": "[..]" + "name": "bear" }, { - "event": "discover_complete", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "discover_complete" } ] "#]] @@ -765,58 +765,58 @@ fn list_json() { str![[r#" [ { - "event": "discover_start", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "discover_start" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "bunny", - "selected": false, - "elapsed_s": "[..]" + "name": "cat" }, { + "elapsed_s": "[..]", "event": "discover_case", "name": "dog", - "selected": false, - "elapsed_s": "[..]" + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "fly", - "selected": false, - "elapsed_s": "[..]" + "name": "fox", + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "fox", - "selected": false, - "elapsed_s": "[..]" + "name": "bunny", + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", "name": "frog", - "selected": false, - "elapsed_s": "[..]" + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", "name": "owl", - "selected": false, - "elapsed_s": "[..]" + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "bear", - "elapsed_s": "[..]" + "name": "fly", + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "cat", - "elapsed_s": "[..]" + "name": "bear" }, { - "event": "discover_complete", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "discover_complete" } ] "#]] @@ -833,93 +833,93 @@ fn test_json() { str![[r#" [ { - "event": "discover_start", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "discover_start" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "bunny", - "selected": false, - "elapsed_s": "[..]" + "name": "cat" }, { + "elapsed_s": "[..]", "event": "discover_case", "name": "dog", - "selected": false, - "elapsed_s": "[..]" + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "fly", - "selected": false, - "elapsed_s": "[..]" + "name": "fox", + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "fox", - "selected": false, - "elapsed_s": "[..]" + "name": "bunny", + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", "name": "frog", - "selected": false, - "elapsed_s": "[..]" + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", "name": "owl", - "selected": false, - "elapsed_s": "[..]" + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "bear", - "elapsed_s": "[..]" + "name": "fly", + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "cat", - "elapsed_s": "[..]" + "name": "bear" }, { - "event": "discover_complete", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "discover_complete" }, { - "event": "run_start", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "run_start" }, { + "elapsed_s": "[..]", "event": "case_start", - "name": "bear", - "elapsed_s": "[..]" + "name": "bear" }, { + "elapsed_s": "[..]", "event": "case_message", - "name": "bear", "kind": "ignored", "message": "fails", - "elapsed_s": "[..]" + "name": "bear" }, { + "elapsed_s": "[..]", "event": "case_complete", - "name": "bear", - "elapsed_s": "[..]" + "name": "bear" }, { + "elapsed_s": "[..]", "event": "case_start", - "name": "cat", - "elapsed_s": "[..]" + "name": "cat" }, { + "elapsed_s": "[..]", "event": "case_complete", - "name": "cat", - "elapsed_s": "[..]" + "name": "cat" }, { - "event": "run_complete", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "run_complete" } ] "#]] @@ -1107,121 +1107,121 @@ fn fail_fast_json() { str![[r#" [ { - "event": "discover_start", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "discover_start" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "bear", - "elapsed_s": "[..]" + "name": "cat" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "bunny", - "elapsed_s": "[..]" + "name": "dog" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "cat", - "elapsed_s": "[..]" + "name": "fox" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "dog", - "elapsed_s": "[..]" + "name": "bunny" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "fly", - "elapsed_s": "[..]" + "name": "frog" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "fox", - "elapsed_s": "[..]" + "name": "owl" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "frog", - "elapsed_s": "[..]" + "name": "fly" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "owl", - "elapsed_s": "[..]" + "name": "bear" }, { - "event": "discover_complete", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "discover_complete" }, { - "event": "run_start", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "run_start" }, { + "elapsed_s": "[..]", "event": "case_start", - "name": "bear", - "elapsed_s": "[..]" + "name": "bear" }, { + "elapsed_s": "[..]", "event": "case_message", - "name": "bear", "kind": "ignored", "message": "fails", - "elapsed_s": "[..]" + "name": "bear" }, { + "elapsed_s": "[..]", "event": "case_complete", - "name": "bear", - "elapsed_s": "[..]" + "name": "bear" }, { + "elapsed_s": "[..]", "event": "case_start", - "name": "bunny", - "elapsed_s": "[..]" + "name": "bunny" }, { + "elapsed_s": "[..]", "event": "case_message", - "name": "bunny", "kind": "ignored", "message": "fails", - "elapsed_s": "[..]" + "name": "bunny" }, { + "elapsed_s": "[..]", "event": "case_complete", - "name": "bunny", - "elapsed_s": "[..]" + "name": "bunny" }, { + "elapsed_s": "[..]", "event": "case_start", - "name": "cat", - "elapsed_s": "[..]" + "name": "cat" }, { + "elapsed_s": "[..]", "event": "case_complete", - "name": "cat", - "elapsed_s": "[..]" + "name": "cat" }, { + "elapsed_s": "[..]", "event": "case_start", - "name": "dog", - "elapsed_s": "[..]" + "name": "dog" }, { + "elapsed_s": "[..]", "event": "case_message", - "name": "dog", "kind": "error", "message": "was not a good boy", - "elapsed_s": "[..]" + "name": "dog" }, { + "elapsed_s": "[..]", "event": "case_complete", - "name": "dog", - "elapsed_s": "[..]" + "name": "dog" }, { - "event": "run_complete", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "run_complete" } ] "#]] diff --git a/crates/libtest2/tests/testsuite/argfile.rs b/crates/libtest2/tests/testsuite/argfile.rs index fd42eee..ad2556b 100644 --- a/crates/libtest2/tests/testsuite/argfile.rs +++ b/crates/libtest2/tests/testsuite/argfile.rs @@ -95,9 +95,9 @@ fn list() { 0, str![[r#" one: test -one_two: test -three: test two: test +three: test +one_two: test 4 tests @@ -105,7 +105,7 @@ two: test "#]], str![[r#" one: test -one_two: test +two: test ... 4 tests diff --git a/crates/libtest2/tests/testsuite/mixed_bag.rs b/crates/libtest2/tests/testsuite/mixed_bag.rs index 054b762..a30cd53 100644 --- a/crates/libtest2/tests/testsuite/mixed_bag.rs +++ b/crates/libtest2/tests/testsuite/mixed_bag.rs @@ -227,28 +227,28 @@ fn list() { &["--list"], 0, str![[r#" -bear: test -bunny: test cat: test dog: test -fly: test fox: test +bunny: test frog: test owl: test +fly: test +bear: test 8 tests "#]], str![[r#" -bear: test -bunny: test cat: test dog: test -fly: test fox: test +bunny: test frog: test owl: test +fly: test +bear: test 8 tests @@ -263,28 +263,28 @@ fn list_ignored() { &["--list", "--ignored"], 0, str![[r#" -bear: test -bunny: test cat: test dog: test -fly: test fox: test +bunny: test frog: test owl: test +fly: test +bear: test 8 tests "#]], str![[r#" -bear: test -bunny: test cat: test dog: test -fly: test fox: test +bunny: test frog: test owl: test +fly: test +bear: test 8 tests @@ -299,16 +299,16 @@ fn list_with_filter() { &["--list", "a"], 0, str![[r#" -bear: test cat: test +bear: test 2 tests "#]], str![[r#" -bear: test cat: test +bear: test 2 tests @@ -323,20 +323,20 @@ fn list_with_specified_order() { &["--list", "--exact", "owl", "fox", "bunny", "frog"], 0, str![[r#" -owl: test fox: test bunny: test frog: test +owl: test 4 tests "#]], str![[r#" -owl: test fox: test bunny: test frog: test +owl: test 4 tests @@ -712,58 +712,58 @@ fn list_json() { str![[r#" [ { - "event": "discover_start", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "discover_start" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "bunny", - "selected": false, - "elapsed_s": "[..]" + "name": "cat" }, { + "elapsed_s": "[..]", "event": "discover_case", "name": "dog", - "selected": false, - "elapsed_s": "[..]" + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "fly", - "selected": false, - "elapsed_s": "[..]" + "name": "fox", + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "fox", - "selected": false, - "elapsed_s": "[..]" + "name": "bunny", + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", "name": "frog", - "selected": false, - "elapsed_s": "[..]" + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", "name": "owl", - "selected": false, - "elapsed_s": "[..]" + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "bear", - "elapsed_s": "[..]" + "name": "fly", + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "cat", - "elapsed_s": "[..]" + "name": "bear" }, { - "event": "discover_complete", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "discover_complete" } ] "#]] @@ -772,58 +772,58 @@ fn list_json() { str![[r#" [ { - "event": "discover_start", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "discover_start" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "bunny", - "selected": false, - "elapsed_s": "[..]" + "name": "cat" }, { + "elapsed_s": "[..]", "event": "discover_case", "name": "dog", - "selected": false, - "elapsed_s": "[..]" + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "fly", - "selected": false, - "elapsed_s": "[..]" + "name": "fox", + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "fox", - "selected": false, - "elapsed_s": "[..]" + "name": "bunny", + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", "name": "frog", - "selected": false, - "elapsed_s": "[..]" + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", "name": "owl", - "selected": false, - "elapsed_s": "[..]" + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "bear", - "elapsed_s": "[..]" + "name": "fly", + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "cat", - "elapsed_s": "[..]" + "name": "bear" }, { - "event": "discover_complete", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "discover_complete" } ] "#]] @@ -840,93 +840,93 @@ fn test_json() { str![[r#" [ { - "event": "discover_start", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "discover_start" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "bunny", - "selected": false, - "elapsed_s": "[..]" + "name": "cat" }, { + "elapsed_s": "[..]", "event": "discover_case", "name": "dog", - "selected": false, - "elapsed_s": "[..]" + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "fly", - "selected": false, - "elapsed_s": "[..]" + "name": "fox", + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "fox", - "selected": false, - "elapsed_s": "[..]" + "name": "bunny", + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", "name": "frog", - "selected": false, - "elapsed_s": "[..]" + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", "name": "owl", - "selected": false, - "elapsed_s": "[..]" + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "bear", - "elapsed_s": "[..]" + "name": "fly", + "selected": false }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "cat", - "elapsed_s": "[..]" + "name": "bear" }, { - "event": "discover_complete", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "discover_complete" }, { - "event": "run_start", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "run_start" }, { + "elapsed_s": "[..]", "event": "case_start", - "name": "bear", - "elapsed_s": "[..]" + "name": "bear" }, { + "elapsed_s": "[..]", "event": "case_message", - "name": "bear", "kind": "ignored", "message": "fails", - "elapsed_s": "[..]" + "name": "bear" }, { + "elapsed_s": "[..]", "event": "case_complete", - "name": "bear", - "elapsed_s": "[..]" + "name": "bear" }, { + "elapsed_s": "[..]", "event": "case_start", - "name": "cat", - "elapsed_s": "[..]" + "name": "cat" }, { + "elapsed_s": "[..]", "event": "case_complete", - "name": "cat", - "elapsed_s": "[..]" + "name": "cat" }, { - "event": "run_complete", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "run_complete" } ] "#]] @@ -1114,121 +1114,121 @@ fn fail_fast_json() { str![[r#" [ { - "event": "discover_start", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "discover_start" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "bear", - "elapsed_s": "[..]" + "name": "cat" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "bunny", - "elapsed_s": "[..]" + "name": "dog" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "cat", - "elapsed_s": "[..]" + "name": "fox" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "dog", - "elapsed_s": "[..]" + "name": "bunny" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "fly", - "elapsed_s": "[..]" + "name": "frog" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "fox", - "elapsed_s": "[..]" + "name": "owl" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "frog", - "elapsed_s": "[..]" + "name": "fly" }, { + "elapsed_s": "[..]", "event": "discover_case", - "name": "owl", - "elapsed_s": "[..]" + "name": "bear" }, { - "event": "discover_complete", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "discover_complete" }, { - "event": "run_start", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "run_start" }, { + "elapsed_s": "[..]", "event": "case_start", - "name": "bear", - "elapsed_s": "[..]" + "name": "bear" }, { + "elapsed_s": "[..]", "event": "case_message", - "name": "bear", "kind": "ignored", "message": "fails", - "elapsed_s": "[..]" + "name": "bear" }, { + "elapsed_s": "[..]", "event": "case_complete", - "name": "bear", - "elapsed_s": "[..]" + "name": "bear" }, { + "elapsed_s": "[..]", "event": "case_start", - "name": "bunny", - "elapsed_s": "[..]" + "name": "bunny" }, { + "elapsed_s": "[..]", "event": "case_message", - "name": "bunny", "kind": "ignored", "message": "fails", - "elapsed_s": "[..]" + "name": "bunny" }, { + "elapsed_s": "[..]", "event": "case_complete", - "name": "bunny", - "elapsed_s": "[..]" + "name": "bunny" }, { + "elapsed_s": "[..]", "event": "case_start", - "name": "cat", - "elapsed_s": "[..]" + "name": "cat" }, { + "elapsed_s": "[..]", "event": "case_complete", - "name": "cat", - "elapsed_s": "[..]" + "name": "cat" }, { + "elapsed_s": "[..]", "event": "case_start", - "name": "dog", - "elapsed_s": "[..]" + "name": "dog" }, { + "elapsed_s": "[..]", "event": "case_message", - "name": "dog", "kind": "error", "message": "was not a good boy", - "elapsed_s": "[..]" + "name": "dog" }, { + "elapsed_s": "[..]", "event": "case_complete", - "name": "dog", - "elapsed_s": "[..]" + "name": "dog" }, { - "event": "run_complete", - "elapsed_s": "[..]" + "elapsed_s": "[..]", + "event": "run_complete" } ] "#]]