From 623b8210cf97246592717fbb4d8058eeea0ae8e1 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Wed, 20 Jul 2022 14:16:54 +0100 Subject: [PATCH] Support giving a reason to inconclusive/ignored cases Since Rust 1.61.0 `cargo test` has included the reason string in the output. The new syntax is optional, so `inconclusive` is still accepted, a reason may be given inside optional brackets `inconclusive["some reason"]`. Parentheses are not used to avoid ambiguity with the output/result. A custom `impl Debug` is used to avoid injecting an unsightly `inconclusivewithreason_litstr_token` into the test name by default. Fixes: #102 --- crates/test-case-macros/src/modifier.rs | 33 ++++++++++++++++--- .../cases_can_be_ignored/src/lib.rs | 7 ++++ .../acceptance__cases_can_be_ignored.snap | 8 +++-- .../acceptance__cases_can_be_ignored.snap | 8 +++-- .../acceptance__cases_can_be_ignored.snap | 8 +++-- 5 files changed, 51 insertions(+), 13 deletions(-) diff --git a/crates/test-case-macros/src/modifier.rs b/crates/test-case-macros/src/modifier.rs index 9065d26..f78da15 100644 --- a/crates/test-case-macros/src/modifier.rs +++ b/crates/test-case-macros/src/modifier.rs @@ -1,25 +1,38 @@ use std::collections::HashSet; +use std::fmt::{Debug, Formatter}; use syn::parse::{Parse, ParseStream}; -use syn::{parse_quote, Attribute}; +use syn::token::Bracket; +use syn::{bracketed, parse_quote, Attribute, LitStr}; mod kw { syn::custom_keyword!(inconclusive); syn::custom_keyword!(ignore); } -#[derive(Debug, PartialEq, Eq, Hash)] +#[derive(PartialEq, Eq, Hash)] pub enum Modifier { Inconclusive, + InconclusiveWithReason(LitStr), +} + +impl Debug for Modifier { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Modifier::Inconclusive | Modifier::InconclusiveWithReason(_) => { + write!(f, "inconclusive") + } + } + } } impl Parse for Modifier { fn parse(input: ParseStream) -> syn::Result { if input.peek(kw::inconclusive) { let _: kw::inconclusive = input.parse()?; - Ok(Self::Inconclusive) + Self::parse_inconclusive(input) } else if input.peek(kw::ignore) { let _: kw::ignore = input.parse()?; - Ok(Self::Inconclusive) + Self::parse_inconclusive(input) } else { Err(syn::Error::new(input.span(), "unknown modifier keyword")) } @@ -27,9 +40,21 @@ impl Parse for Modifier { } impl Modifier { + pub fn parse_inconclusive(input: ParseStream) -> syn::Result { + if input.peek(Bracket) { + let content; + let _: Bracket = bracketed!(content in input); + let reason: LitStr = content.parse()?; + Ok(Self::InconclusiveWithReason(reason)) + } else { + Ok(Self::Inconclusive) + } + } + pub fn attribute(&self) -> Attribute { match self { Modifier::Inconclusive => parse_quote! { #[ignore] }, + Modifier::InconclusiveWithReason(r) => parse_quote! { #[ignore = #r] }, } } } diff --git a/tests/acceptance_cases/cases_can_be_ignored/src/lib.rs b/tests/acceptance_cases/cases_can_be_ignored/src/lib.rs index 46ed540..89c9c9d 100644 --- a/tests/acceptance_cases/cases_can_be_ignored/src/lib.rs +++ b/tests/acceptance_cases/cases_can_be_ignored/src/lib.rs @@ -14,3 +14,10 @@ fn inconclusives(_: ()) { fn ignore_void(input: u8) { assert_eq!(input, 1) } + +#[test_case(() => inconclusive["reason but no comment"] ())] +#[test_case(() => inconclusive["reason and comment"] (); "test is not run")] +#[test_case(() => ignore["reason and comment"] (); "ignore keyword")] +fn descriptions(_: ()) { + unreachable!() +} diff --git a/tests/snapshots/rust-1.49.0/acceptance__cases_can_be_ignored.snap b/tests/snapshots/rust-1.49.0/acceptance__cases_can_be_ignored.snap index b8444d8..d8a51d8 100644 --- a/tests/snapshots/rust-1.49.0/acceptance__cases_can_be_ignored.snap +++ b/tests/snapshots/rust-1.49.0/acceptance__cases_can_be_ignored.snap @@ -1,13 +1,15 @@ --- source: tests/acceptance_tests.rs -assertion_line: 88 expression: output --- -running 6 tests +running 9 tests +test descriptions::_expects_inconclusive_ ... ignored +test descriptions::ignore_keyword ... ignored +test descriptions::test_is_not_run ... ignored test ignore_void::_1_expects_inconclusiveempty ... ignored test ignore_void::_2_expects_inconclusiveempty ... ignored test inconclusives::_expects_inconclusive_ ... ignored test inconclusives::ignore_keyword ... ignored test inconclusives::inconclusive_test ... ignored test inconclusives::test_is_not_ran ... ignored -test result: ok. 0 passed; 0 failed; 6 ignored; 0 measured; 0 filtered out +test result: ok. 0 passed; 0 failed; 9 ignored; 0 measured; 0 filtered out diff --git a/tests/snapshots/rust-nightly/acceptance__cases_can_be_ignored.snap b/tests/snapshots/rust-nightly/acceptance__cases_can_be_ignored.snap index aa668a3..7603741 100644 --- a/tests/snapshots/rust-nightly/acceptance__cases_can_be_ignored.snap +++ b/tests/snapshots/rust-nightly/acceptance__cases_can_be_ignored.snap @@ -1,13 +1,15 @@ --- source: tests/acceptance_tests.rs -assertion_line: 88 expression: output --- -running 6 tests +running 9 tests +test descriptions::_expects_inconclusive_ ... ignored, reason but no comment +test descriptions::ignore_keyword ... ignored, reason and comment +test descriptions::test_is_not_run ... ignored, reason and comment test ignore_void::_1_expects_inconclusiveempty ... ignored test ignore_void::_2_expects_inconclusiveempty ... ignored test inconclusives::_expects_inconclusive_ ... ignored test inconclusives::ignore_keyword ... ignored test inconclusives::inconclusive_test ... ignored test inconclusives::test_is_not_ran ... ignored -test result: ok. 0 passed; 0 failed; 6 ignored; 0 measured; 0 filtered out; finished in 0.00s +test result: ok. 0 passed; 0 failed; 9 ignored; 0 measured; 0 filtered out; finished in 0.00s diff --git a/tests/snapshots/rust-stable/acceptance__cases_can_be_ignored.snap b/tests/snapshots/rust-stable/acceptance__cases_can_be_ignored.snap index aa668a3..7603741 100644 --- a/tests/snapshots/rust-stable/acceptance__cases_can_be_ignored.snap +++ b/tests/snapshots/rust-stable/acceptance__cases_can_be_ignored.snap @@ -1,13 +1,15 @@ --- source: tests/acceptance_tests.rs -assertion_line: 88 expression: output --- -running 6 tests +running 9 tests +test descriptions::_expects_inconclusive_ ... ignored, reason but no comment +test descriptions::ignore_keyword ... ignored, reason and comment +test descriptions::test_is_not_run ... ignored, reason and comment test ignore_void::_1_expects_inconclusiveempty ... ignored test ignore_void::_2_expects_inconclusiveempty ... ignored test inconclusives::_expects_inconclusive_ ... ignored test inconclusives::ignore_keyword ... ignored test inconclusives::inconclusive_test ... ignored test inconclusives::test_is_not_ran ... ignored -test result: ok. 0 passed; 0 failed; 6 ignored; 0 measured; 0 filtered out; finished in 0.00s +test result: ok. 0 passed; 0 failed; 9 ignored; 0 measured; 0 filtered out; finished in 0.00s