mirror of
https://codeberg.org/JasterV/test-context.git
synced 2026-04-26 18:10:06 +00:00
chore: internal refactor & update docs (#64)
This commit is contained in:
parent
b37885d27c
commit
63cb4631a3
6 changed files with 27 additions and 144 deletions
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
|
|
@ -56,4 +56,3 @@ jobs:
|
||||||
with:
|
with:
|
||||||
command: clippy
|
command: clippy
|
||||||
args: --all-targets -- -D warnings
|
args: --all-targets -- -D warnings
|
||||||
|
|
||||||
|
|
|
||||||
25
README.md
25
README.md
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
A library for providing custom setup/teardown for Rust tests without needing a test harness.
|
A library for providing custom setup/teardown for Rust tests without needing a test harness.
|
||||||
|
|
||||||
```rust
|
```rust ignore
|
||||||
use test_context::{test_context, TestContext};
|
use test_context::{test_context, TestContext};
|
||||||
|
|
||||||
struct MyContext {
|
struct MyContext {
|
||||||
|
|
@ -77,7 +77,7 @@ The `AsyncTestContext` works well with async test wrappers like
|
||||||
[`actix_rt::test`](https://docs.rs/actix-rt/1.1.1/actix_rt/attr.test.html) or
|
[`actix_rt::test`](https://docs.rs/actix-rt/1.1.1/actix_rt/attr.test.html) or
|
||||||
[`tokio::test`](https://docs.rs/tokio/1.0.2/tokio/attr.test.html).
|
[`tokio::test`](https://docs.rs/tokio/1.0.2/tokio/attr.test.html).
|
||||||
|
|
||||||
```rust
|
```rust ignore
|
||||||
#[test_context(MyAsyncContext)]
|
#[test_context(MyAsyncContext)]
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_works(ctx: &mut MyAsyncContext) {
|
async fn test_works(ctx: &mut MyAsyncContext) {
|
||||||
|
|
@ -95,7 +95,7 @@ that runs setup/teardown.
|
||||||
|
|
||||||
Valid:
|
Valid:
|
||||||
|
|
||||||
```rust
|
```rust ignore
|
||||||
#[test_context(MyAsyncContext)]
|
#[test_context(MyAsyncContext)]
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn my_test(ctx: &mut MyAsyncContext) {}
|
async fn my_test(ctx: &mut MyAsyncContext) {}
|
||||||
|
|
@ -103,7 +103,7 @@ async fn my_test(ctx: &mut MyAsyncContext) {}
|
||||||
|
|
||||||
Invalid:
|
Invalid:
|
||||||
|
|
||||||
```rust
|
```rust ignore
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[test_context(MyAsyncContext)]
|
#[test_context(MyAsyncContext)]
|
||||||
async fn my_test(ctx: &mut MyAsyncContext) {}
|
async fn my_test(ctx: &mut MyAsyncContext) {}
|
||||||
|
|
@ -130,7 +130,7 @@ tests annotated with `#[tokio::test]` continue to work as usual without the feat
|
||||||
Also, if you don't care about the teardown execution for a specific test,
|
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:
|
you can use the `skip_teardown` keyword on the macro like this:
|
||||||
|
|
||||||
```rust
|
```rust ignore
|
||||||
use test_context::{test_context, TestContext};
|
use test_context::{test_context, TestContext};
|
||||||
|
|
||||||
struct MyContext {}
|
struct MyContext {}
|
||||||
|
|
@ -150,7 +150,7 @@ fn test_without_teardown(ctx: &MyContext) {}
|
||||||
|
|
||||||
If the teardown is ON (default behavior), you can only take a reference to the context, either mutable or immutable, as follows:
|
If the teardown is ON (default behavior), you can only take a reference to the context, either mutable or immutable, as follows:
|
||||||
|
|
||||||
```rust
|
```rust ignore
|
||||||
#[test_context(MyContext)]
|
#[test_context(MyContext)]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_with_teardown_using_immutable_ref(ctx: &MyContext) {}
|
fn test_with_teardown_using_immutable_ref(ctx: &MyContext) {}
|
||||||
|
|
@ -162,7 +162,7 @@ fn test_with_teardown_using_mutable_ref(ctx: &mut MyContext) {}
|
||||||
|
|
||||||
❌The following is invalid:
|
❌The following is invalid:
|
||||||
|
|
||||||
```rust
|
```rust ignore
|
||||||
#[test_context(MyContext)]
|
#[test_context(MyContext)]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_with_teardown_taking_ownership(ctx: MyContext) {}
|
fn test_with_teardown_taking_ownership(ctx: MyContext) {}
|
||||||
|
|
@ -170,7 +170,7 @@ fn test_with_teardown_taking_ownership(ctx: MyContext) {}
|
||||||
|
|
||||||
If the teardown is skipped (as specified in the section above), you can take an immutable ref, mutable ref or full ownership of the context:
|
If the teardown is skipped (as specified in the section above), you can take an immutable ref, mutable ref or full ownership of the context:
|
||||||
|
|
||||||
```rust
|
```rust ignore
|
||||||
#[test_context(MyContext, skip_teardown)]
|
#[test_context(MyContext, skip_teardown)]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_without_teardown(ctx: MyContext) {
|
fn test_without_teardown(ctx: MyContext) {
|
||||||
|
|
@ -186,14 +186,13 @@ fn test_without_teardown_taking_a_ref(ctx: &MyContext) {}
|
||||||
fn test_without_teardown_taking_a_mut_ref(ctx: &mut MyContext) {}
|
fn test_without_teardown_taking_a_mut_ref(ctx: &mut MyContext) {}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## ⚠️ Ensure that the context type specified in the macro matches the test function argument type exactly
|
## ⚠️ Ensure that the context type specified in the macro matches the test function argument type exactly
|
||||||
|
|
||||||
The error occurs when a context type with an absolute path is mixed with an it's alias.
|
The error occurs when a context type with an absolute path is mixed with an it's alias.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
```
|
```rust ignore
|
||||||
mod database {
|
mod database {
|
||||||
use test_context::TestContext;
|
use test_context::TestContext;
|
||||||
|
|
||||||
|
|
@ -207,7 +206,8 @@ mod database {
|
||||||
```
|
```
|
||||||
|
|
||||||
✅The following code will work:
|
✅The following code will work:
|
||||||
```
|
|
||||||
|
```rust ignore
|
||||||
use database::Connection as DbConn;
|
use database::Connection as DbConn;
|
||||||
|
|
||||||
#[test_context(DbConn)]
|
#[test_context(DbConn)]
|
||||||
|
|
@ -228,7 +228,8 @@ fn test1(ctx: &mut database::Connection) {
|
||||||
```
|
```
|
||||||
|
|
||||||
❌The following code will not work:
|
❌The following code will not work:
|
||||||
```
|
|
||||||
|
```rust ignore
|
||||||
use database::Connection as DbConn;
|
use database::Connection as DbConn;
|
||||||
|
|
||||||
#[test_context(database::Connection)]
|
#[test_context(database::Connection)]
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ mod macro_args;
|
||||||
mod test_args;
|
mod test_args;
|
||||||
|
|
||||||
use crate::test_args::{ContextArg, ContextArgMode, TestArg};
|
use crate::test_args::{ContextArg, ContextArgMode, TestArg};
|
||||||
use macro_args::TestContextArgs;
|
use macro_args::MacroArgs;
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use quote::{format_ident, quote};
|
use quote::{format_ident, quote};
|
||||||
use syn::ItemFn;
|
use syn::ItemFn;
|
||||||
|
|
@ -29,7 +29,7 @@ use syn::ItemFn;
|
||||||
/// ```
|
/// ```
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn test_context(attr: TokenStream, item: TokenStream) -> TokenStream {
|
pub fn test_context(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
let args = syn::parse_macro_input!(attr as TestContextArgs);
|
let args = syn::parse_macro_input!(attr as MacroArgs);
|
||||||
let input = syn::parse_macro_input!(item as syn::ItemFn);
|
let input = syn::parse_macro_input!(item as syn::ItemFn);
|
||||||
|
|
||||||
let (input, context_args) = remove_context_args(input, args.context_type.clone());
|
let (input, context_args) = remove_context_args(input, args.context_type.clone());
|
||||||
|
|
@ -86,7 +86,7 @@ fn remove_context_args(
|
||||||
|
|
||||||
fn refactor_input_body(
|
fn refactor_input_body(
|
||||||
input: syn::ItemFn,
|
input: syn::ItemFn,
|
||||||
args: &TestContextArgs,
|
args: &MacroArgs,
|
||||||
context_arg: ContextArg,
|
context_arg: ContextArg,
|
||||||
) -> syn::ItemFn {
|
) -> syn::ItemFn {
|
||||||
let context_type = &args.context_type;
|
let context_type = &args.context_type;
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
use syn::{Token, Type, parse::Parse};
|
use syn::{Token, Type, parse::Parse};
|
||||||
|
|
||||||
pub(crate) struct TestContextArgs {
|
/// Contains the parsed arguments passed to the macro `#[test_context(..)]`
|
||||||
|
pub(crate) struct MacroArgs {
|
||||||
|
/// The context type passed in the macro arguments.
|
||||||
|
/// It must implement `TestContext` or `AsyncTestContext`
|
||||||
pub(crate) context_type: Type,
|
pub(crate) context_type: Type,
|
||||||
|
|
||||||
pub(crate) skip_teardown: bool,
|
pub(crate) skip_teardown: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for TestContextArgs {
|
impl Parse for MacroArgs {
|
||||||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
||||||
let mut skip_teardown = false;
|
let mut skip_teardown = false;
|
||||||
let mut context_type: Option<Type> = None;
|
let mut context_type: Option<Type> = None;
|
||||||
|
|
@ -28,7 +32,7 @@ impl Parse for TestContextArgs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(TestContextArgs {
|
Ok(MacroArgs {
|
||||||
context_type: context_type
|
context_type: context_type
|
||||||
.ok_or(input.error("expected at least one type identifier"))?,
|
.ok_or(input.error("expected at least one type identifier"))?,
|
||||||
skip_teardown,
|
skip_teardown,
|
||||||
|
|
|
||||||
|
|
@ -1,128 +1,4 @@
|
||||||
//! A library for providing custom setup/teardown for Rust tests without needing a test harness.
|
#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/../README.md"))]
|
||||||
//!
|
|
||||||
//! ```no_run
|
|
||||||
//! use test_context::{test_context, TestContext};
|
|
||||||
//!
|
|
||||||
//! struct MyContext {
|
|
||||||
//! value: String
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! impl TestContext for MyContext {
|
|
||||||
//! fn setup() -> MyContext {
|
|
||||||
//! MyContext { value: "Hello, world!".to_string() }
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! fn teardown(self) {
|
|
||||||
//! // Perform any teardown you wish.
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! #[test_context(MyContext)]
|
|
||||||
//! #[test]
|
|
||||||
//! fn test_works(ctx: &mut MyContext) {
|
|
||||||
//! assert_eq!(ctx.value, "Hello, world!");
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! Alternatively, you can use `async` functions in your test context by using the
|
|
||||||
//! `AsyncTestContext`.
|
|
||||||
//!
|
|
||||||
//! ```no_run
|
|
||||||
//! use test_context::{test_context, AsyncTestContext};
|
|
||||||
//!
|
|
||||||
//! struct MyAsyncContext {
|
|
||||||
//! value: String
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! impl AsyncTestContext for MyAsyncContext {
|
|
||||||
//! async fn setup() -> MyAsyncContext {
|
|
||||||
//! MyAsyncContext { value: "Hello, world!".to_string() }
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! async fn teardown(self) {
|
|
||||||
//! // Perform any teardown you wish.
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! #[test_context(MyAsyncContext)]
|
|
||||||
//! #[test]
|
|
||||||
//! fn test_works(ctx: &mut MyAsyncContext) {
|
|
||||||
//! assert_eq!(ctx.value, "Hello, World!");
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! The `AsyncTestContext` works well with async test wrappers like
|
|
||||||
//! [`actix_rt::test`](https://docs.rs/actix-rt/1.1.1/actix_rt/attr.test.html) or
|
|
||||||
//! [`tokio::test`](https://docs.rs/tokio/1.0.2/tokio/attr.test.html).
|
|
||||||
//!
|
|
||||||
//! ```no_run
|
|
||||||
//! use test_context::{test_context, AsyncTestContext};
|
|
||||||
//!
|
|
||||||
//! struct MyAsyncContext {
|
|
||||||
//! value: String
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! impl AsyncTestContext for MyAsyncContext {
|
|
||||||
//! async fn setup() -> MyAsyncContext {
|
|
||||||
//! MyAsyncContext { value: "Hello, world!".to_string() }
|
|
||||||
//! }
|
|
||||||
//! async fn teardown(self) {
|
|
||||||
//! // Perform any teardown you wish.
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! #[test_context(MyAsyncContext)]
|
|
||||||
//! #[tokio::test]
|
|
||||||
//! async fn test_async_works(ctx: &mut MyAsyncContext) {
|
|
||||||
//! assert_eq!(ctx.value, "Hello, World!");
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! # Attribute order
|
|
||||||
//!
|
|
||||||
//! Attribute order matters. Always place `#[test_context(...)]` before other test attributes
|
|
||||||
//! like `#[tokio::test]` or `#[test]`.
|
|
||||||
//!
|
|
||||||
//! Why: Rust expands attributes in source order. `#[test_context]` wraps your function and
|
|
||||||
//! re-attaches the remaining attributes to the wrapper; it must run first so the test attributes
|
|
||||||
//! apply to the wrapper that performs setup/teardown.
|
|
||||||
//!
|
|
||||||
//! Valid:
|
|
||||||
//! ```ignore
|
|
||||||
//! #[test_context(MyAsyncContext)]
|
|
||||||
//! #[tokio::test]
|
|
||||||
//! async fn my_test(ctx: &mut MyAsyncContext) {}
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! Invalid:
|
|
||||||
//! ```ignore
|
|
||||||
//! #[tokio::test]
|
|
||||||
//! #[test_context(MyAsyncContext)]
|
|
||||||
//! async fn my_test(ctx: &mut MyAsyncContext) {}
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! # Skipping the teardown execution
|
|
||||||
//!
|
|
||||||
//! 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};
|
|
||||||
//!
|
|
||||||
//! struct MyContext {}
|
|
||||||
//!
|
|
||||||
//! impl TestContext for MyContext {
|
|
||||||
//! fn setup() -> MyContext {
|
|
||||||
//! MyContext {}
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! #[test_context(MyContext, skip_teardown)]
|
|
||||||
//! #[test]
|
|
||||||
//! fn test_without_teardown(ctx: &mut MyContext) {
|
|
||||||
//! // Perform any operations that require full ownership of your context
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
|
|
||||||
// Reimported to allow for use in the macro.
|
// Reimported to allow for use in the macro.
|
||||||
pub use futures;
|
pub use futures;
|
||||||
|
|
|
||||||
3
yamlfmt.yml
Normal file
3
yamlfmt.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
formatter:
|
||||||
|
type: basic
|
||||||
|
retain_line_breaks_single: true
|
||||||
Loading…
Reference in a new issue