mirror of https://github.com/fafhrd91/actix-web
add test runtime macro
This commit is contained in:
parent
ad22cc4e7f
commit
1da77b5efa
|
@ -67,7 +67,7 @@ __compress = []
|
|||
|
||||
[dependencies]
|
||||
actix-codec = "0.4.0"
|
||||
actix-macros = "0.2.1"
|
||||
actix-macros = "0.2.2"
|
||||
actix-router = "0.5.0-beta.2"
|
||||
actix-rt = "2.2"
|
||||
actix-server = "2.0.0-beta.3"
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
|
||||
## Unreleased - 2021-xx-xx
|
||||
* Improve error recovery potential when macro input is invalid. [#2410]
|
||||
* Add `#[actix_web::test_rt]` macro for setting up tests with a runtime. [#2409]
|
||||
* Minimum supported Rust version (MSRV) is now 1.52.
|
||||
|
||||
[#2410]: https://github.com/actix/actix-web/pull/2410
|
||||
[#2409]: https://github.com/actix/actix-web/pull/2409
|
||||
|
||||
|
||||
## 0.5.0-beta.4 - 2021-09-09
|
||||
|
|
|
@ -2,10 +2,8 @@
|
|||
name = "actix-web-codegen"
|
||||
version = "0.5.0-beta.4"
|
||||
description = "Routing and runtime macros for Actix Web"
|
||||
readme = "README.md"
|
||||
homepage = "https://actix.rs"
|
||||
repository = "https://github.com/actix/actix-web"
|
||||
documentation = "https://docs.rs/actix-web-codegen"
|
||||
repository = "https://github.com/actix/actix-web.git"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2018"
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#![recursion_limit = "512"]
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
|
||||
mod route;
|
||||
|
||||
|
@ -157,24 +158,41 @@ method_macro! {
|
|||
}
|
||||
|
||||
/// Marks async main function as the actix system entry-point.
|
||||
///
|
||||
/// # Actix Web Re-export
|
||||
/// This macro can be applied with `#[actix_web::main]` when used in Actix Web applications.
|
||||
///
|
||||
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// #[actix_web_codegen::main]
|
||||
/// #[actix_web::main]
|
||||
/// async fn main() {
|
||||
/// async { println!("Hello world"); }.await
|
||||
/// }
|
||||
/// ```
|
||||
#[proc_macro_attribute]
|
||||
pub fn main(_: TokenStream, item: TokenStream) -> TokenStream {
|
||||
use quote::quote;
|
||||
let input = syn::parse_macro_input!(item as syn::ItemFn);
|
||||
let input = proc_macro2::TokenStream::from(item);
|
||||
|
||||
(quote! {
|
||||
#[actix_web::rt::main(system = "::actix_web::rt::System")]
|
||||
#input
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Marks async test functions to use the actix system entry-point.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// #[actix_web::test_rt]
|
||||
/// async fn test() {
|
||||
/// assert_eq!(async { "Hello world" }.await, "Hello world");
|
||||
/// }
|
||||
/// ```
|
||||
#[proc_macro_attribute]
|
||||
pub fn test_rt(_: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let input = proc_macro2::TokenStream::from(item);
|
||||
|
||||
(quote! {
|
||||
#[actix_web::rt::test(system = "::actix_web::rt::System")]
|
||||
#input
|
||||
})
|
||||
.into()
|
||||
}
|
||||
|
|
|
@ -220,7 +220,7 @@ fn guess_resource_type(typ: &syn::Type) -> ResourceType {
|
|||
impl Route {
|
||||
pub fn new(
|
||||
args: AttributeArgs,
|
||||
input: TokenStream,
|
||||
ast: syn::ItemFn,
|
||||
method: Option<MethodType>,
|
||||
) -> syn::Result<Self> {
|
||||
if args.is_empty() {
|
||||
|
@ -234,14 +234,11 @@ impl Route {
|
|||
),
|
||||
));
|
||||
}
|
||||
let ast: syn::ItemFn = syn::parse(input)?;
|
||||
|
||||
let name = ast.sig.ident.clone();
|
||||
|
||||
// Try and pull out the doc comments so that we can reapply them to the
|
||||
// generated struct.
|
||||
//
|
||||
// Note that multi line doc comments are converted to multiple doc
|
||||
// attributes.
|
||||
// Try and pull out the doc comments so that we can reapply them to the generated struct.
|
||||
// Note that multi line doc comments are converted to multiple doc attributes.
|
||||
let doc_attributes = ast
|
||||
.attrs
|
||||
.iter()
|
||||
|
@ -349,10 +346,16 @@ pub(crate) fn with_method(
|
|||
input: TokenStream,
|
||||
) -> TokenStream {
|
||||
let args = parse_macro_input!(args as syn::AttributeArgs);
|
||||
match Route::new(args, input.clone(), method) {
|
||||
Ok(route) => route.into_token_stream().into(),
|
||||
|
||||
let ast = match syn::parse::<syn::ItemFn>(input.clone()) {
|
||||
Ok(ast) => ast,
|
||||
// on parse err, make IDEs happy; see fn docs
|
||||
Err(err) => input_and_compile_error(input, err),
|
||||
Err(err) => return input_and_compile_error(input, err),
|
||||
};
|
||||
|
||||
match Route::new(args, ast, method) {
|
||||
Ok(route) => route.into_token_stream().into(),
|
||||
Err(err) => err.into_compile_error().into(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -256,7 +256,7 @@ async fn test_auto_async() {
|
|||
assert!(response.status().is_success());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[actix_web::test_rt]
|
||||
async fn test_wrap() {
|
||||
let srv = actix_test::start(|| App::new().service(get_wrap));
|
||||
|
||||
|
|
|
@ -13,4 +13,6 @@ fn compile_macros() {
|
|||
t.compile_fail("tests/trybuild/route-malformed-path-fail.rs");
|
||||
|
||||
t.pass("tests/trybuild/docstring-ok.rs");
|
||||
|
||||
t.pass("tests/trybuild/test-runtime.rs");
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ error: HTTP method defined more than once: `GET`
|
|||
3 | #[route("/", method="GET", method="GET")]
|
||||
| ^^^^^
|
||||
|
||||
error[E0277]: the trait bound `fn() -> impl std::future::Future {index}: HttpServiceFactory` is not satisfied
|
||||
error[E0425]: cannot find value `index` in this scope
|
||||
--> $DIR/route-duplicate-method-fail.rs:12:55
|
||||
|
|
||||
12 | let srv = actix_test::start(|| App::new().service(index));
|
||||
| ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future {index}`
|
||||
| ^^^^^ not found in this scope
|
||||
|
|
|
@ -6,8 +6,8 @@ error: The #[route(..)] macro requires at least one `method` attribute
|
|||
|
|
||||
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: the trait bound `fn() -> impl std::future::Future {index}: HttpServiceFactory` is not satisfied
|
||||
error[E0425]: cannot find value `index` in this scope
|
||||
--> $DIR/route-missing-method-fail.rs:12:55
|
||||
|
|
||||
12 | let srv = actix_test::start(|| App::new().service(index));
|
||||
| ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future {index}`
|
||||
| ^^^^^ not found in this scope
|
||||
|
|
|
@ -4,8 +4,8 @@ error: Unexpected HTTP method: `UNEXPECTED`
|
|||
3 | #[route("/", method="UNEXPECTED")]
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error[E0277]: the trait bound `fn() -> impl std::future::Future {index}: HttpServiceFactory` is not satisfied
|
||||
error[E0425]: cannot find value `index` in this scope
|
||||
--> $DIR/route-unexpected-method-fail.rs:12:55
|
||||
|
|
||||
12 | let srv = actix_test::start(|| App::new().service(index));
|
||||
| ^^^^^ the trait `HttpServiceFactory` is not implemented for `fn() -> impl std::future::Future {index}`
|
||||
| ^^^^^ not found in this scope
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#[actix_web::test_rt]
|
||||
async fn my_test() {
|
||||
assert!(async { 1 }.await, 1);
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -35,7 +35,7 @@ async fn main() -> std::io::Result<()> {
|
|||
)
|
||||
.service(web::resource("/test1.html").to(|| async { "Test\r\n" }))
|
||||
})
|
||||
.bind("127.0.0.1:8080")?
|
||||
.bind(("127.0.0.1", 8080))?
|
||||
.workers(1)
|
||||
.run()
|
||||
.await
|
||||
|
|
Loading…
Reference in New Issue