[FIX-CONFLICT-WITH-RSTEST-V2]: stable version, fix context name extraction function, fix readme, fix docs, increase version of crate

This commit is contained in:
Vyacheslav Volkov 2025-10-02 16:41:02 +03:00
parent 02bbbb7244
commit f853aac180
5 changed files with 32 additions and 14 deletions

View file

@ -4,7 +4,7 @@ members = ["test-context", "test-context-macros"]
[workspace.package]
edition = "2021"
version = "0.4.0"
version = "0.5.0"
rust-version = "1.75.0"
homepage = "https://github.com/JasterV/test-context"
repository = "https://github.com/JasterV/test-context"

View file

@ -118,7 +118,7 @@ enable the optional `tokio-runtime` feature so those steps run inside a Tokio ru
```toml
[dependencies]
test-context = { version = "0.4", features = ["tokio-runtime"] }
test-context = { version = "0.5", features = ["tokio-runtime"] }
```
With this feature, the crate tries to reuse an existing runtime; if none is present, it creates
@ -127,7 +127,7 @@ tests annotated with `#[tokio::test]` continue to work as usual without the feat
## Skipping the teardown execution
If what you need is to take full **ownership** of the context and don't care about the
Also, if you don't care about the
teardown execution for a specific test, you can use the `skip_teardown` keyword on the macro
like this:
@ -144,7 +144,7 @@ like this:
#[test_context(MyContext, skip_teardown)]
#[test]
fn test_without_teardown(ctx: MyContext) {
fn test_without_teardown(ctx: &mut MyContext) {
// Perform any operations that require full ownership of your context
}
```

View file

@ -32,7 +32,8 @@ pub fn test_context(attr: TokenStream, item: TokenStream) -> TokenStream {
let input = syn::parse_macro_input!(item as syn::ItemFn);
let is_async = input.sig.asyncness.is_some();
let (new_input, context_arg_name) = extract_and_remove_context_arg(input.clone());
let (new_input, context_arg_name) =
extract_and_remove_context_arg(input.clone(), args.context_type.clone());
let wrapper_body = if is_async {
async_wrapper_body(args, &context_arg_name, &input.block)
@ -131,16 +132,26 @@ fn handle_result(result_name: Ident) -> proc_macro2::TokenStream {
}
}
fn extract_and_remove_context_arg(mut input: syn::ItemFn) -> (syn::ItemFn, Option<syn::Ident>) {
// TODO: Possible bugs when using: type aliases, full and relative paths, generic types in context type
fn extract_and_remove_context_arg(
mut input: syn::ItemFn,
expected_context_type: syn::Type,
) -> (syn::ItemFn, Option<syn::Ident>) {
let mut context_arg_name = None;
let mut new_args = syn::punctuated::Punctuated::new();
for arg in &input.sig.inputs {
// Extract function arg:
if let syn::FnArg::Typed(pat_type) = arg {
// Extract arg identifier:
if let syn::Pat::Ident(pat_ident) = &*pat_type.pat {
if let syn::Type::Reference(_) = &*pat_type.ty {
context_arg_name = Some(pat_ident.ident.clone());
continue;
// Check that context arg is only ref or mutable ref:
if let syn::Type::Reference(type_ref) = &*pat_type.ty {
// Check that context has expected type:
if types_equal(&type_ref.elem, &expected_context_type) {
context_arg_name = Some(pat_ident.ident.clone());
continue;
}
}
}
}
@ -150,3 +161,11 @@ fn extract_and_remove_context_arg(mut input: syn::ItemFn) -> (syn::ItemFn, Optio
input.sig.inputs = new_args;
(input, context_arg_name)
}
fn types_equal(a: &syn::Type, b: &syn::Type) -> bool {
if let (syn::Type::Path(a_path), syn::Type::Path(b_path)) = (a, b) {
return a_path.path.segments.last().unwrap().ident
== b_path.path.segments.last().unwrap().ident;
}
quote!(#a).to_string() == quote!(#b).to_string()
}

View file

@ -13,7 +13,7 @@ authors.workspace = true
license.workspace = true
[dependencies]
test-context-macros = { version = "0.4.0", path = "../test-context-macros/" }
test-context-macros = { version = "0.5.0", path = "../test-context-macros/" }
futures = "0.3"
[dev-dependencies]

View file

@ -103,9 +103,8 @@
//!
//! # Skipping the teardown execution
//!
//! If what you need is to take full __ownership__ of the context and don't care about the
//! teardown execution for a specific test, you can use the `skip_teardown` keyword on the macro
//! like this:
//! Also, if you don't care about the teardown execution for a specific test,
//! you can use the `skip_teardown` keyword on the macro like this:
//!
//! ```no_run
//! use test_context::{test_context, TestContext};
@ -120,7 +119,7 @@
//!
//! #[test_context(MyContext, skip_teardown)]
//! #[test]
//! fn test_without_teardown(ctx: MyContext) {
//! fn test_without_teardown(ctx: &mut MyContext) {
//! // Perform any operations that require full ownership of your context
//! }
//! ```