diff --git a/crates/test-case-core/src/test_case.rs b/crates/test-case-core/src/test_case.rs index 977742c..5ac9ffb 100644 --- a/crates/test-case-core/src/test_case.rs +++ b/crates/test-case-core/src/test_case.rs @@ -5,7 +5,36 @@ use proc_macro2::{Span as Span2, TokenStream as TokenStream2}; use quote::quote; use syn::parse::{Parse, ParseStream}; use syn::punctuated::Punctuated; -use syn::{parse_quote, Error, Expr, Ident, ItemFn, ReturnType, Token}; +use syn::{parse_quote, Attribute, Error, Expr, Ident, ItemFn, ReturnType, Token}; + +// Check whether given attribute is a test attribute of forms: +// * `#[test]` +// * `#[core::prelude::*::test]` or `#[::core::prelude::*::test]` +// * `#[std::prelude::*::test]` or `#[::std::prelude::*::test]` +fn is_test_attribute(attr: &Attribute) -> bool { + let path = match &attr.meta { + syn::Meta::Path(path) => path, + _ => return false, + }; + let candidates = [ + ["core", "prelude", "*", "test"], + ["std", "prelude", "*", "test"], + ]; + if path.leading_colon.is_none() + && path.segments.len() == 1 + && path.segments[0].arguments.is_none() + && path.segments[0].ident == "test" + { + return true; + } else if path.segments.len() != candidates[0].len() { + return false; + } + candidates.into_iter().any(|segments| { + path.segments.iter().zip(segments).all(|(segment, path)| { + segment.arguments.is_none() && (path == "*" || segment.ident == path) + }) + }) +} #[derive(Debug)] pub struct TestCase { @@ -99,14 +128,9 @@ impl TestCase { quote! { let _result = super::#item_name(#(#arg_values),*).await; }, ) } else { - let test_attr = parse_quote! { #[test] }; let qualified_test_attr = parse_quote! { #[::core::prelude::v1::test] }; - if let Some(attr) = attrs - .iter() - .find(|attr| **attr == test_attr || **attr == qualified_test_attr) - { - let msg = - "second test attribute is supplied, consider removing it or ordering it after `test_case` macros"; + if let Some(attr) = attrs.iter().find(|attr| is_test_attribute(attr)) { + let msg = "second test attribute is supplied, consider removing or changing the order of your test attributes"; return Error::new_spanned(attr, msg).into_compile_error(); } attrs.push(qualified_test_attr); diff --git a/tests/acceptance_tests.rs b/tests/acceptance_tests.rs index 8b5726f..929d156 100644 --- a/tests/acceptance_tests.rs +++ b/tests/acceptance_tests.rs @@ -22,7 +22,7 @@ macro_rules! run_acceptance_test { let output = sanitize_lines(output); - insta::assert_display_snapshot!(output); + insta::assert_snapshot!(output); }) }; ($case_name:expr) => { diff --git a/tests/snapshots/rust-nightly/acceptance__matrices_compilation_errors.snap b/tests/snapshots/rust-nightly/acceptance__matrices_compilation_errors.snap index 2617d4f..2a83f9c 100644 --- a/tests/snapshots/rust-nightly/acceptance__matrices_compilation_errors.snap +++ b/tests/snapshots/rust-nightly/acceptance__matrices_compilation_errors.snap @@ -5,6 +5,6 @@ expression: output error: All literal values must be of the same type error: Range bounds can only be an integer literal error: Unbounded ranges are not supported -error: could not compile `matrices_compilation_errors` (lib test) due to 5 previous errors +error: could not compile `matrices_compilation_errors` (lib test) due to 5 previous errors; 1 warning emitted error: number too large to fit in target type error[E0308]: mismatched types diff --git a/tests/snapshots/rust-stable/acceptance__features_produce_human_readable_errors.snap b/tests/snapshots/rust-stable/acceptance__features_produce_human_readable_errors.snap index 2646115..2b5a76f 100644 --- a/tests/snapshots/rust-stable/acceptance__features_produce_human_readable_errors.snap +++ b/tests/snapshots/rust-stable/acceptance__features_produce_human_readable_errors.snap @@ -3,4 +3,4 @@ source: tests/acceptance_tests.rs expression: output --- error: 'with-regex' feature is required to use 'matches-regex' keyword -error: could not compile `features_produce_human_readable_errors` (lib test) due to previous error +error: could not compile `features_produce_human_readable_errors` (lib test) due to 1 previous error