use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use hyper::StatusCode;
use mini_serve::{RouteBuilder, handler, path_params};
use serde::Deserialize;
#[derive(Deserialize)]
struct IdParam {
id: String,
}
#[tokio::test]
async fn single_traversal_path_param_extraction() {
let call_count = Arc::new(AtomicUsize::new(0));
let count_extract = call_count.clone();
let count_assert = call_count.clone();
let app = RouteBuilder::stateless()
.get("/items/:id", handler(move |req, _state| {
let count = count_extract.clone();
async move {
count.fetch_add(1, Ordering::SeqCst);
let params: IdParam = path_params(&req)?;
let id = params.id;
mini_serve::json(StatusCode::OK, &serde_json::json!({"id": id}))
}
}))
.seal();
let port = app.bind_ephemeral().await.expect("failed to bind");
tokio::time::sleep(tokio::time::Duration::from_millis(50)).await;
let resp = reqwest::get(&format!("http://127.0.0.1:{}/items/42", port))
.await
.expect("request failed");
assert_eq!(resp.status(), StatusCode::OK);
assert_eq!(count_assert.load(Ordering::SeqCst), 1);
let body: serde_json::Value = resp.json().await.expect("failed to parse json");
assert_eq!(body.get("id").and_then(|v| v.as_str()), Some("42"));
}