Hi Jonas,

> I'm currently traveling and cannot focus on this issue as much as I
> would like to at the moment. I also don't see any issue in the actual
> upstream code; rather the issue is with the tests. As such, I honestly
> beleive that for the time being, disabling those tests doesn't loose
> us coverage, but to the contrary, is an impediment of finding other,
> real issues in the code by using it from application code that
> actually needs it in the wild.

Please find an upstream patch attached to this email. In that patch I
was sprinkling conditional compilation constraint throughout the
codebase that allows `cargo test --no-default features`, as well as
`--no-default-fetaures --features $F` for $F in all features indivually
to pass.

Thank you for your timely reponses!

From: Reinhard Tartler <siret...@tauware.de>
Date: Sat, 20 Jul 2024 07:05:45 +0200
Subject: Unbreak 'cargo test --no-default-features'

Add appropriate feature constraints throughout the code
---
 axum/src/extract/host.rs               |  1 +
 axum/src/extract/matched_path.rs       |  1 +
 axum/src/extract/mod.rs                |  1 +
 axum/src/extract/multipart.rs          |  1 +
 axum/src/extract/path/mod.rs           |  1 +
 axum/src/extract/query.rs              |  1 +
 axum/src/extract/request_parts.rs      |  1 +
 axum/src/form.rs                       |  1 +
 axum/src/handler/mod.rs                |  1 +
 axum/src/middleware/from_extractor.rs  |  1 +
 axum/src/middleware/map_request.rs     |  1 +
 axum/src/middleware/map_response.rs    |  1 +
 axum/src/response/sse.rs               |  1 +
 axum/src/routing/method_routing.rs     |  1 +
 axum/src/routing/tests/fallback.rs     | 21 +++++++++++++++
 axum/src/routing/tests/handle_error.rs |  4 +++
 axum/src/routing/tests/merge.rs        | 24 ++++++++++++++++-
 axum/src/routing/tests/mod.rs          | 48 +++++++++++++++++++++++++++++++++-
 axum/src/routing/tests/nest.rs         | 17 ++++++++++++
 axum/src/test_helpers/test_client.rs   |  6 +++++
 axum/src/typed_header.rs               |  1 +
 21 files changed, 133 insertions(+), 2 deletions(-)

diff --git a/axum/src/extract/host.rs b/axum/src/extract/host.rs
index d5be6a9..a3e374d 100644
--- a/axum/src/extract/host.rs
+++ b/axum/src/extract/host.rs
@@ -76,6 +76,7 @@ fn parse_forwarded(headers: &HeaderMap) -> Option<&str> {
     })
 }
 
+#[cfg(feature = "tokio")]
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/axum/src/extract/matched_path.rs b/axum/src/extract/matched_path.rs
index c3bd7b4..760748c 100644
--- a/axum/src/extract/matched_path.rs
+++ b/axum/src/extract/matched_path.rs
@@ -168,6 +168,7 @@ fn append_nested_matched_path(matched_path: &Arc<str>, extensions: &http::Extens
     }
 }
 
+#[cfg(feature = "tokio")]
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/axum/src/extract/mod.rs b/axum/src/extract/mod.rs
index cb4ebcd..4d327a8 100644
--- a/axum/src/extract/mod.rs
+++ b/axum/src/extract/mod.rs
@@ -98,6 +98,7 @@ pub(super) fn has_content_type(headers: &HeaderMap, expected_content_type: &mime
     content_type.starts_with(expected_content_type.as_ref())
 }
 
+#[cfg(feature = "tokio")]
 #[cfg(test)]
 mod tests {
     use crate::{routing::get, test_helpers::*, Router};
diff --git a/axum/src/extract/multipart.rs b/axum/src/extract/multipart.rs
index 3827734..3ef05f8 100644
--- a/axum/src/extract/multipart.rs
+++ b/axum/src/extract/multipart.rs
@@ -305,6 +305,7 @@ define_rejection! {
     pub struct InvalidBoundary;
 }
 
+#[cfg(feature = "tokio")]
 #[cfg(test)]
 mod tests {
     use axum_core::extract::DefaultBodyLimit;
diff --git a/axum/src/extract/path/mod.rs b/axum/src/extract/path/mod.rs
index 189e476..16e16e5 100644
--- a/axum/src/extract/path/mod.rs
+++ b/axum/src/extract/path/mod.rs
@@ -539,6 +539,7 @@ impl IntoResponse for InvalidUtf8InPathParam {
     }
 }
 
+#[cfg(feature = "tokio")]
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/axum/src/extract/query.rs b/axum/src/extract/query.rs
index 6f8cb89..76c140b 100644
--- a/axum/src/extract/query.rs
+++ b/axum/src/extract/query.rs
@@ -94,6 +94,7 @@ where
 
 axum_core::__impl_deref!(Query);
 
+#[cfg(feature = "tokio")]
 #[cfg(test)]
 mod tests {
     use crate::{routing::get, test_helpers::TestClient, Router};
diff --git a/axum/src/extract/request_parts.rs b/axum/src/extract/request_parts.rs
index 9af618f..2536b69 100644
--- a/axum/src/extract/request_parts.rs
+++ b/axum/src/extract/request_parts.rs
@@ -226,6 +226,7 @@ where
 
 axum_core::__impl_deref!(RawBody);
 
+#[cfg(feature = "tokio")]
 #[cfg(test)]
 mod tests {
     use crate::{extract::Extension, routing::get, test_helpers::*, Router};
diff --git a/axum/src/form.rs b/axum/src/form.rs
index c690d48..906a873 100644
--- a/axum/src/form.rs
+++ b/axum/src/form.rs
@@ -116,6 +116,7 @@ where
 
 axum_core::__impl_deref!(Form);
 
+#[cfg(feature = "tokio")]
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/axum/src/handler/mod.rs b/axum/src/handler/mod.rs
index 5087ac7..fdf569e 100644
--- a/axum/src/handler/mod.rs
+++ b/axum/src/handler/mod.rs
@@ -393,6 +393,7 @@ where
     }
 }
 
+#[cfg(feature = "tokio")]
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/axum/src/middleware/from_extractor.rs b/axum/src/middleware/from_extractor.rs
index 8c9a248..b150cef 100644
--- a/axum/src/middleware/from_extractor.rs
+++ b/axum/src/middleware/from_extractor.rs
@@ -302,6 +302,7 @@ where
     }
 }
 
+#[cfg(feature = "tokio")]
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/axum/src/middleware/map_request.rs b/axum/src/middleware/map_request.rs
index 5d1801a..cafd94f 100644
--- a/axum/src/middleware/map_request.rs
+++ b/axum/src/middleware/map_request.rs
@@ -380,6 +380,7 @@ impl<B> IntoMapRequestResult<B> for Request<B> {
     }
 }
 
+#[cfg(feature = "tokio")]
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/axum/src/middleware/map_response.rs b/axum/src/middleware/map_response.rs
index 06f9825..80f14d0 100644
--- a/axum/src/middleware/map_response.rs
+++ b/axum/src/middleware/map_response.rs
@@ -341,6 +341,7 @@ impl fmt::Debug for ResponseFuture {
     }
 }
 
+#[cfg(feature = "tokio")]
 #[cfg(test)]
 mod tests {
     #[allow(unused_imports)]
diff --git a/axum/src/response/sse.rs b/axum/src/response/sse.rs
index 2e9e285..1550600 100644
--- a/axum/src/response/sse.rs
+++ b/axum/src/response/sse.rs
@@ -505,6 +505,7 @@ impl<'a> Iterator for MemchrSplit<'a> {
     }
 }
 
+#[cfg(feature = "json")]
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/axum/src/routing/method_routing.rs b/axum/src/routing/method_routing.rs
index cdc7a11..753b1c1 100644
--- a/axum/src/routing/method_routing.rs
+++ b/axum/src/routing/method_routing.rs
@@ -1272,6 +1272,7 @@ where
     }
 }
 
+#[cfg(feature = "tokio")]
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/axum/src/routing/tests/fallback.rs b/axum/src/routing/tests/fallback.rs
index 869b732..2a098d7 100644
--- a/axum/src/routing/tests/fallback.rs
+++ b/axum/src/routing/tests/fallback.rs
@@ -3,6 +3,7 @@ use tower::ServiceExt;
 use super::*;
 use crate::middleware::{map_request, map_response};
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn basic() {
     let app = Router::new()
@@ -18,6 +19,7 @@ async fn basic() {
     assert_eq!(res.text().await, "fallback");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn nest() {
     let app = Router::new()
@@ -33,6 +35,7 @@ async fn nest() {
     assert_eq!(res.text().await, "fallback");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn or() {
     let one = Router::new().route("/one", get(|| async {}));
@@ -50,6 +53,7 @@ async fn or() {
     assert_eq!(res.text().await, "fallback");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn fallback_accessing_state() {
     let app = Router::new()
@@ -71,6 +75,7 @@ async fn outer_fallback() -> impl IntoResponse {
     (StatusCode::NOT_FOUND, "outer")
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn nested_router_inherits_fallback() {
     let inner = Router::new();
@@ -83,6 +88,7 @@ async fn nested_router_inherits_fallback() {
     assert_eq!(res.text().await, "outer");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn doesnt_inherit_fallback_if_overriden() {
     let inner = Router::new().fallback(inner_fallback);
@@ -99,6 +105,7 @@ async fn doesnt_inherit_fallback_if_overriden() {
     assert_eq!(res.text().await, "outer");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn deeply_nested_inherit_from_top() {
     let app = Router::new()
@@ -112,6 +119,7 @@ async fn deeply_nested_inherit_from_top() {
     assert_eq!(res.text().await, "outer");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn deeply_nested_inherit_from_middle() {
     let app = Router::new().nest(
@@ -128,6 +136,7 @@ async fn deeply_nested_inherit_from_middle() {
     assert_eq!(res.text().await, "outer");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn with_middleware_on_inner_fallback() {
     async fn never_called<B>(_: Request<B>) -> Request<B> {
@@ -144,6 +153,7 @@ async fn with_middleware_on_inner_fallback() {
     assert_eq!(res.text().await, "outer");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn also_inherits_default_layered_fallback() {
     async fn set_header<B>(mut res: Response<B>) -> Response<B> {
@@ -166,6 +176,7 @@ async fn also_inherits_default_layered_fallback() {
     assert_eq!(res.text().await, "outer");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn fallback_inherited_into_nested_router_service() {
     let inner = Router::new()
@@ -186,6 +197,7 @@ async fn fallback_inherited_into_nested_router_service() {
     assert_eq!(res.text().await, "outer");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn fallback_inherited_into_nested_opaque_service() {
     let inner = Router::new()
@@ -208,6 +220,7 @@ async fn fallback_inherited_into_nested_opaque_service() {
     assert_eq!(res.text().await, "outer");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn nest_fallback_on_inner() {
     let app = Router::new()
@@ -227,6 +240,7 @@ async fn nest_fallback_on_inner() {
 }
 
 // https://github.com/tokio-rs/axum/issues/1931
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn doesnt_panic_if_used_with_nested_router() {
     async fn handler() {}
@@ -242,6 +256,7 @@ async fn doesnt_panic_if_used_with_nested_router() {
     assert_eq!(res.status(), StatusCode::OK);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn issue_2072() {
     let nested_routes = Router::new().fallback(inner_fallback);
@@ -261,6 +276,7 @@ async fn issue_2072() {
     assert_eq!(res.text().await, "");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn issue_2072_outer_fallback_before_merge() {
     let nested_routes = Router::new().fallback(inner_fallback);
@@ -281,6 +297,7 @@ async fn issue_2072_outer_fallback_before_merge() {
     assert_eq!(res.text().await, "outer");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn issue_2072_outer_fallback_after_merge() {
     let nested_routes = Router::new().fallback(inner_fallback);
@@ -301,6 +318,7 @@ async fn issue_2072_outer_fallback_after_merge() {
     assert_eq!(res.text().await, "outer");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn merge_router_with_fallback_into_nested_router_with_fallback() {
     let nested_routes = Router::new().fallback(inner_fallback);
@@ -320,6 +338,7 @@ async fn merge_router_with_fallback_into_nested_router_with_fallback() {
     assert_eq!(res.text().await, "outer");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn merging_nested_router_with_fallback_into_router_with_fallback() {
     let nested_routes = Router::new().fallback(inner_fallback);
@@ -339,6 +358,7 @@ async fn merging_nested_router_with_fallback_into_router_with_fallback() {
     assert_eq!(res.text().await, "outer");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn merge_empty_into_router_with_fallback() {
     let app = Router::new().fallback(outer_fallback).merge(Router::new());
@@ -350,6 +370,7 @@ async fn merge_empty_into_router_with_fallback() {
     assert_eq!(res.text().await, "outer");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn merge_router_with_fallback_into_empty() {
     let app = Router::new().merge(Router::new().fallback(outer_fallback));
diff --git a/axum/src/routing/tests/handle_error.rs b/axum/src/routing/tests/handle_error.rs
index 3781677..85575aa 100644
--- a/axum/src/routing/tests/handle_error.rs
+++ b/axum/src/routing/tests/handle_error.rs
@@ -29,6 +29,7 @@ impl<R> Service<R> for Svc {
     }
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn handler() {
     let app = Router::new().route(
@@ -48,6 +49,7 @@ async fn handler() {
     assert_eq!(res.status(), StatusCode::REQUEST_TIMEOUT);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn handler_multiple_methods_first() {
     let app = Router::new().route(
@@ -68,6 +70,7 @@ async fn handler_multiple_methods_first() {
     assert_eq!(res.status(), StatusCode::REQUEST_TIMEOUT);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn handler_multiple_methods_middle() {
     let app = Router::new().route(
@@ -91,6 +94,7 @@ async fn handler_multiple_methods_middle() {
     assert_eq!(res.status(), StatusCode::REQUEST_TIMEOUT);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn handler_multiple_methods_last() {
     let app = Router::new().route(
diff --git a/axum/src/routing/tests/merge.rs b/axum/src/routing/tests/merge.rs
index 0344a87..70f0acd 100644
--- a/axum/src/routing/tests/merge.rs
+++ b/axum/src/routing/tests/merge.rs
@@ -1,8 +1,11 @@
 use super::*;
-use crate::{error_handling::HandleErrorLayer, extract::OriginalUri, response::IntoResponse, Json};
+use crate::{error_handling::HandleErrorLayer, response::IntoResponse};
+#[cfg(feature = "json")]
+use crate::{extract::OriginalUri, Json};
 use serde_json::{json, Value};
 use tower::{limit::ConcurrencyLimitLayer, timeout::TimeoutLayer};
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn basic() {
     let one = Router::new()
@@ -26,6 +29,7 @@ async fn basic() {
     assert_eq!(res.status(), StatusCode::NOT_FOUND);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn multiple_ors_balanced_differently() {
     let one = Router::new().route("/one", get(|| async { "one" }));
@@ -71,6 +75,7 @@ async fn multiple_ors_balanced_differently() {
     }
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn nested_or() {
     let bar = Router::new().route("/bar", get(|| async { "bar" }));
@@ -87,6 +92,7 @@ async fn nested_or() {
     assert_eq!(client.get("/foo/baz").send().await.text().await, "baz");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn or_with_route_following() {
     let one = Router::new().route("/one", get(|| async { "one" }));
@@ -105,6 +111,7 @@ async fn or_with_route_following() {
     assert_eq!(res.status(), StatusCode::OK);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn layer() {
     let one = Router::new().route("/foo", get(|| async {}));
@@ -122,6 +129,7 @@ async fn layer() {
     assert_eq!(res.status(), StatusCode::OK);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn layer_and_handle_error() {
     let one = Router::new().route("/foo", get(|| async {}));
@@ -142,6 +150,7 @@ async fn layer_and_handle_error() {
     assert_eq!(res.status(), StatusCode::REQUEST_TIMEOUT);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn nesting() {
     let one = Router::new().route("/foo", get(|| async {}));
@@ -154,6 +163,7 @@ async fn nesting() {
     assert_eq!(res.status(), StatusCode::OK);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn boxed() {
     let one = Router::new().route("/foo", get(|| async {}));
@@ -166,6 +176,7 @@ async fn boxed() {
     assert_eq!(res.status(), StatusCode::OK);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn many_ors() {
     let app = Router::new()
@@ -188,6 +199,7 @@ async fn many_ors() {
     assert_eq!(res.status(), StatusCode::NOT_FOUND);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn services() {
     use crate::routing::get_service;
@@ -215,6 +227,7 @@ async fn services() {
     assert_eq!(res.status(), StatusCode::OK);
 }
 
+#[cfg(feature = "json")]
 async fn all_the_uris(
     uri: Uri,
     OriginalUri(original_uri): OriginalUri,
@@ -227,6 +240,8 @@ async fn all_the_uris(
     }))
 }
 
+#[cfg(feature = "tokio")]
+#[cfg(feature = "json")]
 #[crate::test]
 async fn nesting_and_seeing_the_right_uri() {
     let one = Router::new().nest("/foo/", Router::new().route("/bar", get(all_the_uris)));
@@ -257,6 +272,8 @@ async fn nesting_and_seeing_the_right_uri() {
     );
 }
 
+#[cfg(feature = "tokio")]
+#[cfg(feature = "json")]
 #[crate::test]
 async fn nesting_and_seeing_the_right_uri_at_more_levels_of_nesting() {
     let one = Router::new().nest(
@@ -290,6 +307,8 @@ async fn nesting_and_seeing_the_right_uri_at_more_levels_of_nesting() {
     );
 }
 
+#[cfg(feature = "tokio")]
+#[cfg(feature = "json")]
 #[crate::test]
 async fn nesting_and_seeing_the_right_uri_ors_with_nesting() {
     let one = Router::new().nest(
@@ -335,6 +354,8 @@ async fn nesting_and_seeing_the_right_uri_ors_with_nesting() {
     );
 }
 
+#[cfg(feature = "tokio")]
+#[cfg(feature = "json")]
 #[crate::test]
 async fn nesting_and_seeing_the_right_uri_ors_with_multi_segment_uris() {
     let one = Router::new().nest(
@@ -368,6 +389,7 @@ async fn nesting_and_seeing_the_right_uri_ors_with_multi_segment_uris() {
     );
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn middleware_that_return_early() {
     let private = Router::new()
diff --git a/axum/src/routing/tests/mod.rs b/axum/src/routing/tests/mod.rs
index 8d4d36b..225dbcf 100644
--- a/axum/src/routing/tests/mod.rs
+++ b/axum/src/routing/tests/mod.rs
@@ -12,8 +12,13 @@ use crate::{
         tracing_helpers::{capture_tracing, TracingEvent},
         *,
     },
-    BoxError, Extension, Json, Router,
+    BoxError, Extension, Router,
 };
+#[cfg(feature = "json")]
+use crate::{
+    Json,
+};
+
 use futures_util::stream::StreamExt;
 use http::{
     header::CONTENT_LENGTH,
@@ -42,6 +47,7 @@ mod handle_error;
 mod merge;
 mod nest;
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn hello_world() {
     async fn root(_: Request<Body>) -> &'static str {
@@ -75,6 +81,7 @@ async fn hello_world() {
     assert_eq!(body, "users#create");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn routing() {
     let app = Router::new()
@@ -111,6 +118,7 @@ async fn routing() {
     assert_eq!(res.text().await, "users#action");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn router_type_doesnt_change() {
     let app: Router = Router::new()
@@ -136,6 +144,7 @@ async fn router_type_doesnt_change() {
     assert_eq!(res.text().await, "hi from POST");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn routing_between_services() {
     use std::convert::Infallible;
@@ -182,6 +191,7 @@ async fn routing_between_services() {
     assert_eq!(res.text().await, "handler");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn middleware_on_single_route() {
     use tower::ServiceBuilder;
@@ -209,6 +219,7 @@ async fn middleware_on_single_route() {
     assert_eq!(body, "Hello, World!");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn service_in_bottom() {
     async fn handler(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
@@ -220,6 +231,7 @@ async fn service_in_bottom() {
     TestClient::new(app);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn wrong_method_handler() {
     let app = Router::new()
@@ -243,6 +255,7 @@ async fn wrong_method_handler() {
     assert_eq!(res.status(), StatusCode::NOT_FOUND);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn wrong_method_service() {
     #[derive(Clone)]
@@ -283,6 +296,7 @@ async fn wrong_method_service() {
     assert_eq!(res.status(), StatusCode::NOT_FOUND);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn multiple_methods_for_one_handler() {
     async fn root(_: Request<Body>) -> &'static str {
@@ -300,6 +314,7 @@ async fn multiple_methods_for_one_handler() {
     assert_eq!(res.status(), StatusCode::OK);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn wildcard_sees_whole_url() {
     let app = Router::new().route("/api/*rest", get(|uri: Uri| async move { uri.to_string() }));
@@ -310,6 +325,7 @@ async fn wildcard_sees_whole_url() {
     assert_eq!(res.text().await, "/api/foo/bar");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn middleware_applies_to_routes_above() {
     let app = Router::new()
@@ -332,6 +348,7 @@ async fn middleware_applies_to_routes_above() {
     assert_eq!(res.status(), StatusCode::OK);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn not_found_for_extra_trailing_slash() {
     let app = Router::new().route("/foo", get(|| async {}));
@@ -345,6 +362,7 @@ async fn not_found_for_extra_trailing_slash() {
     assert_eq!(res.status(), StatusCode::OK);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn not_found_for_missing_trailing_slash() {
     let app = Router::new().route("/foo/", get(|| async {}));
@@ -355,6 +373,7 @@ async fn not_found_for_missing_trailing_slash() {
     assert_eq!(res.status(), StatusCode::NOT_FOUND);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn with_and_without_trailing_slash() {
     let app = Router::new()
@@ -373,6 +392,7 @@ async fn with_and_without_trailing_slash() {
 }
 
 // for https://github.com/tokio-rs/axum/issues/420
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn wildcard_doesnt_match_just_trailing_slash() {
     let app = Router::new().route(
@@ -393,6 +413,7 @@ async fn wildcard_doesnt_match_just_trailing_slash() {
     assert_eq!(res.text().await, "foo/bar");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn what_matches_wildcard() {
     let app = Router::new()
@@ -421,6 +442,7 @@ async fn what_matches_wildcard() {
     assert_eq!(get("/x/a/b/").await, "x");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn static_and_dynamic_paths() {
     let app = Router::new()
@@ -439,6 +461,7 @@ async fn static_and_dynamic_paths() {
     assert_eq!(res.text().await, "static");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 #[should_panic(expected = "Paths must start with a `/`. Use \"/\" for root routes")]
 async fn empty_route() {
@@ -446,6 +469,7 @@ async fn empty_route() {
     TestClient::new(app);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn middleware_still_run_for_unmatched_requests() {
     #[derive(Clone)]
@@ -491,10 +515,12 @@ async fn middleware_still_run_for_unmatched_requests() {
     Invalid route: `Router::route_service` cannot be used with `Router`s. \
     Use `Router::nest` instead\
 ")]
+#[cfg(feature = "tokio")]
 async fn routing_to_router_panics() {
     TestClient::new(Router::new().route_service("/", Router::new()));
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn route_layer() {
     let app = Router::new()
@@ -523,6 +549,7 @@ async fn route_layer() {
     assert_eq!(res.status(), StatusCode::UNAUTHORIZED);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn different_methods_added_in_different_routes() {
     let app = Router::new()
@@ -540,6 +567,7 @@ async fn different_methods_added_in_different_routes() {
     assert_eq!(body, "POST");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 #[should_panic(expected = "Cannot merge two `Router`s that both have a fallback")]
 async fn merging_routers_with_fallbacks_panics() {
@@ -566,6 +594,7 @@ fn merging_with_overlapping_method_routes() {
     _ = app.clone().merge(app);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn merging_routers_with_same_paths_but_different_methods() {
     let one = Router::new().route("/", get(|| async { "GET" }));
@@ -582,6 +611,8 @@ async fn merging_routers_with_same_paths_but_different_methods() {
     assert_eq!(body, "POST");
 }
 
+#[cfg(feature = "json")]
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn head_content_length_through_hyper_server() {
     let app = Router::new()
@@ -599,6 +630,7 @@ async fn head_content_length_through_hyper_server() {
     assert!(res.text().await.is_empty());
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn head_content_length_through_hyper_server_that_hits_fallback() {
     let app = Router::new().fallback(|| async { "foo" });
@@ -609,6 +641,7 @@ async fn head_content_length_through_hyper_server_that_hits_fallback() {
     assert_eq!(res.headers()["content-length"], "3");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn head_with_middleware_applied() {
     use tower_http::compression::{predicate::SizeAbove, CompressionLayer};
@@ -645,6 +678,7 @@ async fn head_with_middleware_applied() {
     assert!(!res.headers().contains_key("content-length"));
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 #[should_panic(expected = "Paths must start with a `/`")]
 async fn routes_must_start_with_slash() {
@@ -652,6 +686,8 @@ async fn routes_must_start_with_slash() {
     TestClient::new(app);
 }
 
+#[cfg(feature = "json")]
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn body_limited_by_default() {
     let app = Router::new()
@@ -680,6 +716,7 @@ async fn body_limited_by_default() {
     }
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn disabling_the_default_limit() {
     let app = Router::new()
@@ -696,6 +733,7 @@ async fn disabling_the_default_limit() {
     assert_eq!(res.status(), StatusCode::OK);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn limited_body_with_content_length() {
     const LIMIT: usize = 3;
@@ -718,6 +756,7 @@ async fn limited_body_with_content_length() {
     assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn changing_the_default_limit() {
     let new_limit = 2;
@@ -743,6 +782,7 @@ async fn changing_the_default_limit() {
     assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn limited_body_with_streaming_body() {
     const LIMIT: usize = 3;
@@ -775,6 +815,7 @@ async fn limited_body_with_streaming_body() {
     assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn extract_state() {
     #[derive(Clone)]
@@ -811,6 +852,7 @@ async fn extract_state() {
     assert_eq!(res.status(), StatusCode::OK);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn explicitly_set_state() {
     let app = Router::new()
@@ -825,6 +867,7 @@ async fn explicitly_set_state() {
     assert_eq!(res.text().await, "foo");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn layer_response_into_response() {
     fn map_response<B>(_res: Response<B>) -> Result<Response<B>, impl IntoResponse> {
@@ -872,6 +915,7 @@ fn test_path_for_nested_route() {
     assert_eq!(path_for_nested_route("/a/", "/b/"), "/a/b/");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn state_isnt_cloned_too_much() {
     static SETUP_DONE: AtomicBool = AtomicBool::new(false);
@@ -925,6 +969,7 @@ async fn state_isnt_cloned_too_much() {
 }
 
 #[ignore]
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn logging_rejections() {
     #[derive(Deserialize, Eq, PartialEq, Debug)]
@@ -1028,6 +1073,7 @@ async fn connect_going_to_default_fallback() {
     assert!(body.is_empty());
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn impl_handler_for_into_response() {
     let app = Router::new().route("/things", post((StatusCode::CREATED, "thing created")));
diff --git a/axum/src/routing/tests/nest.rs b/axum/src/routing/tests/nest.rs
index 0544f8b..9bb7a21 100644
--- a/axum/src/routing/tests/nest.rs
+++ b/axum/src/routing/tests/nest.rs
@@ -3,6 +3,7 @@ use crate::{body::boxed, extract::Extension};
 use std::collections::HashMap;
 use tower_http::services::ServeDir;
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn nesting_apps() {
     let api_routes = Router::new()
@@ -58,6 +59,7 @@ async fn nesting_apps() {
     assert_eq!(res.text().await, "v0: games#show (123)");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn wrong_method_nest() {
     let nested_app = Router::new().route("/", get(|| async {}));
@@ -76,6 +78,7 @@ async fn wrong_method_nest() {
     assert_eq!(res.status(), StatusCode::NOT_FOUND);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn nesting_router_at_root() {
     let nested = Router::new().route("/foo", get(|uri: Uri| async move { uri.to_string() }));
@@ -94,6 +97,7 @@ async fn nesting_router_at_root() {
     assert_eq!(res.status(), StatusCode::NOT_FOUND);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn nesting_router_at_empty_path() {
     let nested = Router::new().route("/foo", get(|uri: Uri| async move { uri.to_string() }));
@@ -112,6 +116,7 @@ async fn nesting_router_at_empty_path() {
     assert_eq!(res.status(), StatusCode::NOT_FOUND);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn nesting_handler_at_root() {
     let app = Router::new().nest_service("/", get(|uri: Uri| async move { uri.to_string() }));
@@ -131,6 +136,7 @@ async fn nesting_handler_at_root() {
     assert_eq!(res.text().await, "/foo/bar");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn nested_url_extractor() {
     let app = Router::new().nest(
@@ -157,6 +163,8 @@ async fn nested_url_extractor() {
     assert_eq!(res.text().await, "/qux");
 }
 
+#[cfg(feature = "tokio")]
+#[cfg(feature = "json")]
 #[crate::test]
 async fn nested_url_original_extractor() {
     let app = Router::new().nest(
@@ -177,6 +185,7 @@ async fn nested_url_original_extractor() {
     assert_eq!(res.text().await, "/foo/bar/baz");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn nested_service_sees_stripped_uri() {
     let app = Router::new().nest(
@@ -200,6 +209,7 @@ async fn nested_service_sees_stripped_uri() {
     assert_eq!(res.text().await, "/baz");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn nest_static_file_server() {
     let app = Router::new().nest_service("/static", ServeDir::new("."));
@@ -210,6 +220,7 @@ async fn nest_static_file_server() {
     assert_eq!(res.status(), StatusCode::OK);
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn nested_multiple_routes() {
     let app = Router::new()
@@ -243,6 +254,7 @@ fn nested_at_root_with_other_routes() {
         .route("/", get(|| async {}));
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn multiple_top_level_nests() {
     let app = Router::new()
@@ -267,6 +279,7 @@ async fn nest_cannot_contain_wildcards() {
     _ = Router::<(), Body>::new().nest("/one/*rest", Router::new());
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn outer_middleware_still_see_whole_url() {
     #[derive(Clone)]
@@ -318,6 +331,7 @@ async fn outer_middleware_still_see_whole_url() {
     assert_eq!(client.get("/one/two").send().await.text().await, "/one/two");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn nest_at_capture() {
     let api_routes = Router::new().route(
@@ -334,6 +348,7 @@ async fn nest_at_capture() {
     assert_eq!(res.text().await, "a=foo b=bar");
 }
 
+#[cfg(feature = "tokio")]
 #[crate::test]
 async fn nest_with_and_without_trailing() {
     let app = Router::new().nest_service("/foo", get(|| async {}));
@@ -350,6 +365,7 @@ async fn nest_with_and_without_trailing() {
     assert_eq!(res.status(), StatusCode::OK);
 }
 
+#[cfg(feature = "tokio")]
 #[tokio::test]
 async fn nesting_with_root_inner_router() {
     let app = Router::new()
@@ -396,6 +412,7 @@ macro_rules! nested_route_test {
         // the route we expect to be able to call
         expected = $expected_path:literal $(,)?
     ) => {
+        #[cfg(feature = "tokio")]
         #[crate::test]
         async fn $name() {
             let inner = Router::new().route($route_path, get(|| async {}));
diff --git a/axum/src/test_helpers/test_client.rs b/axum/src/test_helpers/test_client.rs
index d1d73f6..9351305 100644
--- a/axum/src/test_helpers/test_client.rs
+++ b/axum/src/test_helpers/test_client.rs
@@ -4,16 +4,22 @@ use http::{
     header::{HeaderName, HeaderValue},
     Request, StatusCode,
 };
+#[cfg(feature = "tokio")]
 use hyper::{Body, Server};
+#[cfg(feature = "tokio")]
 use std::net::{SocketAddr, TcpListener};
+#[cfg(feature = "tokio")]
 use tower::make::Shared;
+#[cfg(feature = "tokio")]
 use tower_service::Service;
 
+#[cfg(feature = "tokio")]
 pub(crate) struct TestClient {
     client: reqwest::Client,
     addr: SocketAddr,
 }
 
+#[cfg(feature = "tokio")]
 impl TestClient {
     pub(crate) fn new<S, ResBody>(svc: S) -> Self
     where
diff --git a/axum/src/typed_header.rs b/axum/src/typed_header.rs
index 72b3d7e..4c451d9 100644
--- a/axum/src/typed_header.rs
+++ b/axum/src/typed_header.rs
@@ -162,6 +162,7 @@ impl std::error::Error for TypedHeaderRejection {
     }
 }
 
+#[cfg(feature = "tokio")]
 #[cfg(test)]
 mod tests {
     use super::*;
-rt

Reply via email to