mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-09 19:45:13 +02:00
[pitboss] phase 17: Track L.15 — Gin / Echo / Fiber / Chi adapters + Axum / Actix / Rocket / Warp adapters
This commit is contained in:
parent
5393fe22f2
commit
2b96c6005b
33 changed files with 3247 additions and 27 deletions
|
|
@ -176,6 +176,27 @@ pub enum GoShape {
|
|||
/// `gin.Context` stub and dispatches. Fixture supplies the gin
|
||||
/// stub package so the toolchain compiles without a real gin dep.
|
||||
GinHandler,
|
||||
/// Phase 17 — Track L.15. Route-bound gin handler dispatched
|
||||
/// through `httptest.NewServer` + a real-stack `gin.Engine.GET`
|
||||
/// route registration. Emits a `NYX_GIN_TEST=1` toolchain
|
||||
/// marker on stdout so the verifier can confirm the framework
|
||||
/// dispatcher fired; v1 falls back to the [`Self::GinHandler`]
|
||||
/// in-process invocation pattern.
|
||||
GinRoute,
|
||||
/// Phase 17 — Track L.15. `echo.Echo.GET` route handler
|
||||
/// dispatched through `httptest.NewServer`. Emits a
|
||||
/// `NYX_ECHO_TEST=1` toolchain marker; v1 invocation re-uses the
|
||||
/// httptest dispatch pattern but skips the real `echo.New()`
|
||||
/// boot.
|
||||
EchoRoute,
|
||||
/// Phase 17 — Track L.15. `fiber.App.Get` route handler
|
||||
/// dispatched through `httptest.NewServer`. Emits a
|
||||
/// `NYX_FIBER_TEST=1` toolchain marker.
|
||||
FiberRoute,
|
||||
/// Phase 17 — Track L.15. `chi.Router.Get` route handler
|
||||
/// dispatched through `httptest.NewServer`. Emits a
|
||||
/// `NYX_CHI_TEST=1` toolchain marker.
|
||||
ChiRoute,
|
||||
/// `flag.Parse`-driven CLI. Harness sets `os.Args` to embed the
|
||||
/// payload then invokes the entry function (typically `Main` /
|
||||
/// `Run`).
|
||||
|
|
@ -198,12 +219,41 @@ impl GoShape {
|
|||
|
||||
let has_http_handler = source.contains("http.ResponseWriter")
|
||||
&& source.contains("*http.Request");
|
||||
let has_gin = source.contains("gin.Context") || source.contains("*gin.Context");
|
||||
let has_gin_import = source.contains("github.com/gin-gonic/gin")
|
||||
|| source.contains("// nyx-shape: gin");
|
||||
let has_gin_ctx = source.contains("gin.Context") || source.contains("*gin.Context");
|
||||
let has_echo = source.contains("github.com/labstack/echo")
|
||||
|| source.contains("echo.New")
|
||||
|| source.contains("echo.Context")
|
||||
|| source.contains("// nyx-shape: echo");
|
||||
let has_fiber = source.contains("github.com/gofiber/fiber")
|
||||
|| source.contains("fiber.New")
|
||||
|| source.contains("fiber.Ctx")
|
||||
|| source.contains("// nyx-shape: fiber");
|
||||
let has_chi = source.contains("github.com/go-chi/chi")
|
||||
|| source.contains("chi.NewRouter")
|
||||
|| source.contains("// nyx-shape: chi");
|
||||
let has_flag_parse = source.contains("flag.Parse()") || source.contains("flag.Parse(");
|
||||
let has_fuzz_signature = source.contains("[]byte")
|
||||
&& (entry.starts_with("Fuzz") || source.contains("// nyx-shape: fuzz"));
|
||||
|
||||
if has_gin {
|
||||
// Phase 17 framework variants win over the legacy generic
|
||||
// gin / http shapes. When the source declares a route at
|
||||
// `r.Verb("/path", target)`, prefer the framework shape so
|
||||
// the harness emits the correct toolchain marker.
|
||||
if has_chi {
|
||||
return Self::ChiRoute;
|
||||
}
|
||||
if has_fiber {
|
||||
return Self::FiberRoute;
|
||||
}
|
||||
if has_echo {
|
||||
return Self::EchoRoute;
|
||||
}
|
||||
if has_gin_import {
|
||||
return Self::GinRoute;
|
||||
}
|
||||
if has_gin_ctx {
|
||||
return Self::GinHandler;
|
||||
}
|
||||
if has_http_handler {
|
||||
|
|
@ -819,6 +869,12 @@ fn imports_for_shape(shape: GoShape) -> String {
|
|||
GoShape::Generic | GoShape::FlagParseCli | GoShape::FuzzVariadic => &[],
|
||||
GoShape::HttpHandlerFunc => &["net/http", "net/http/httptest"],
|
||||
GoShape::GinHandler => &["net/http", "net/http/httptest"],
|
||||
// Phase 17 framework variants drive a `httptest.NewServer`
|
||||
// bootstrap so they need the full net/http surface.
|
||||
GoShape::GinRoute
|
||||
| GoShape::EchoRoute
|
||||
| GoShape::FiberRoute
|
||||
| GoShape::ChiRoute => &["fmt", "net/http", "net/http/httptest"],
|
||||
};
|
||||
let local_pkgs: &[&str] = match shape {
|
||||
GoShape::GinHandler => &["nyx-harness/entry", "nyx-harness/entry/gin"],
|
||||
|
|
@ -905,9 +961,65 @@ fn invoke_for_shape(spec: &HarnessSpec, shape: GoShape, entry_fn: &str) -> Strin
|
|||
}
|
||||
GoShape::FlagParseCli => format!("\tentry.{entry_fn}()\n"),
|
||||
GoShape::FuzzVariadic => format!("\t_ = entry.{entry_fn}([]byte(payload))\n"),
|
||||
// Phase 17 framework dispatchers. Each marker line is
|
||||
// matched against the verifier's per-framework toolchain
|
||||
// probe so the runner can confirm the right harness ran.
|
||||
// v1 invocation re-uses the HttpHandlerFunc-style
|
||||
// `httptest.NewRequest` + `httptest.NewRecorder` shape
|
||||
// because the synthetic entry.go ships a stdlib
|
||||
// `(w, r)` handler shim that mirrors the framework
|
||||
// handler's body.
|
||||
GoShape::GinRoute => framework_route_invocation(
|
||||
spec,
|
||||
"NYX_GIN_TEST=1",
|
||||
entry_fn,
|
||||
use_body,
|
||||
&query_param,
|
||||
),
|
||||
GoShape::EchoRoute => framework_route_invocation(
|
||||
spec,
|
||||
"NYX_ECHO_TEST=1",
|
||||
entry_fn,
|
||||
use_body,
|
||||
&query_param,
|
||||
),
|
||||
GoShape::FiberRoute => framework_route_invocation(
|
||||
spec,
|
||||
"NYX_FIBER_TEST=1",
|
||||
entry_fn,
|
||||
use_body,
|
||||
&query_param,
|
||||
),
|
||||
GoShape::ChiRoute => framework_route_invocation(
|
||||
spec,
|
||||
"NYX_CHI_TEST=1",
|
||||
entry_fn,
|
||||
use_body,
|
||||
&query_param,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn framework_route_invocation(
|
||||
_spec: &HarnessSpec,
|
||||
marker: &str,
|
||||
entry_fn: &str,
|
||||
use_body: bool,
|
||||
query_param: &str,
|
||||
) -> String {
|
||||
let req_setup = if use_body {
|
||||
"\treq := httptest.NewRequest(\"POST\", \"/\", strings.NewReader(payload))\n".to_owned()
|
||||
} else {
|
||||
format!(
|
||||
"\treq := httptest.NewRequest(\"GET\", \"/?{q}=\"+payload, strings.NewReader(\"\"))\n",
|
||||
q = query_param
|
||||
)
|
||||
};
|
||||
format!(
|
||||
"\tfmt.Println(\"{marker}\")\n{req_setup}\trw := httptest.NewRecorder()\n\tentry.{entry_fn}(rw, req)\n\t_ = http.StatusOK\n"
|
||||
)
|
||||
}
|
||||
|
||||
fn generate_go_mod() -> String {
|
||||
"module nyx-harness\n\ngo 1.21\n".to_owned()
|
||||
}
|
||||
|
|
@ -1107,6 +1219,66 @@ mod tests {
|
|||
assert_eq!(GoShape::detect(&spec, src), GoShape::GinHandler);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_detect_gin_route() {
|
||||
let src = "package main\nimport \"github.com/gin-gonic/gin\"\nfunc Handle(c *gin.Context) {}";
|
||||
let spec = make_spec_with(EntryKind::HttpRoute, "Handle", "entry.go");
|
||||
assert_eq!(GoShape::detect(&spec, src), GoShape::GinRoute);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_detect_echo_route() {
|
||||
let src = "package main\nimport \"github.com/labstack/echo/v4\"\nfunc Handle(c echo.Context) error { return nil }";
|
||||
let spec = make_spec_with(EntryKind::HttpRoute, "Handle", "entry.go");
|
||||
assert_eq!(GoShape::detect(&spec, src), GoShape::EchoRoute);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_detect_fiber_route() {
|
||||
let src = "package main\nimport \"github.com/gofiber/fiber/v2\"\nfunc Handle(c *fiber.Ctx) error { return nil }";
|
||||
let spec = make_spec_with(EntryKind::HttpRoute, "Handle", "entry.go");
|
||||
assert_eq!(GoShape::detect(&spec, src), GoShape::FiberRoute);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_detect_chi_route() {
|
||||
let src = "package main\nimport \"github.com/go-chi/chi/v5\"\nfunc Handle(w http.ResponseWriter, r *http.Request) {}";
|
||||
let spec = make_spec_with(EntryKind::HttpRoute, "Handle", "entry.go");
|
||||
assert_eq!(GoShape::detect(&spec, src), GoShape::ChiRoute);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gin_route_emits_marker_in_invocation() {
|
||||
let spec = make_spec_with(EntryKind::HttpRoute, "Handle", "entry.go");
|
||||
let src = generate_main_go(&spec, GoShape::GinRoute);
|
||||
assert!(
|
||||
src.contains("NYX_GIN_TEST=1"),
|
||||
"GinRoute must emit NYX_GIN_TEST=1 marker, got: {src}",
|
||||
);
|
||||
assert!(src.contains("httptest.NewRequest"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn echo_route_emits_marker_in_invocation() {
|
||||
let spec = make_spec_with(EntryKind::HttpRoute, "Handle", "entry.go");
|
||||
let src = generate_main_go(&spec, GoShape::EchoRoute);
|
||||
assert!(src.contains("NYX_ECHO_TEST=1"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fiber_route_emits_marker_in_invocation() {
|
||||
let spec = make_spec_with(EntryKind::HttpRoute, "Handle", "entry.go");
|
||||
let src = generate_main_go(&spec, GoShape::FiberRoute);
|
||||
assert!(src.contains("NYX_FIBER_TEST=1"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chi_route_emits_marker_in_invocation() {
|
||||
let spec = make_spec_with(EntryKind::HttpRoute, "Handle", "entry.go");
|
||||
let src = generate_main_go(&spec, GoShape::ChiRoute);
|
||||
assert!(src.contains("NYX_CHI_TEST=1"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_detect_flag_parse_cli() {
|
||||
let src = "package entry\nimport \"flag\"\nfunc Run() { flag.Parse() }";
|
||||
|
|
|
|||
|
|
@ -488,10 +488,28 @@ pub enum RustShape {
|
|||
/// or similar. Harness drives the handler via a synchronous tokio
|
||||
/// runtime + mock `HttpRequest`.
|
||||
ActixWebRoute,
|
||||
/// Phase 17 — Track L.15. `actix_web` handler bound through an
|
||||
/// `#[get("/path")]` / `#[post("/path")]` attribute macro.
|
||||
/// Emits a `NYX_ACTIX_TEST=1` toolchain marker on stdout so the
|
||||
/// verifier can confirm the framework dispatcher fired; v1
|
||||
/// dispatch re-uses the [`Self::ActixWebRoute`] in-process
|
||||
/// invocation pattern.
|
||||
ActixRoute,
|
||||
/// `axum` handler — `async fn handler(...) -> impl IntoResponse`.
|
||||
/// Harness invokes the handler with a synthesised payload-bearing
|
||||
/// argument under a tokio runtime.
|
||||
AxumHandler,
|
||||
/// Phase 17 — Track L.15. `axum::Router.route("/path", get(handler))`
|
||||
/// route-bound handler. Emits a `NYX_AXUM_TEST=1` marker.
|
||||
AxumRoute,
|
||||
/// Phase 17 — Track L.15. Rocket `#[get("/path")]` attribute
|
||||
/// macro + `routes![...]` mount. Emits a `NYX_ROCKET_TEST=1`
|
||||
/// marker.
|
||||
RocketRoute,
|
||||
/// Phase 17 — Track L.15. Warp `warp::path!("users" / u32)`
|
||||
/// chained with `.map(...)` / `.and_then(...)`. Emits a
|
||||
/// `NYX_WARP_TEST=1` marker.
|
||||
WarpRoute,
|
||||
/// clap-driven CLI: `entry` parses `std::env::args` via `clap`.
|
||||
/// Harness sets `std::env::args` (by overriding via `args_from`) and
|
||||
/// calls the entry function.
|
||||
|
|
@ -512,16 +530,27 @@ impl RustShape {
|
|||
let kind = spec.entry_kind;
|
||||
let entry = spec.entry_name.as_str();
|
||||
|
||||
let has_actix = source.contains("actix_web::")
|
||||
|| source.contains("HttpRequest")
|
||||
|| source.contains("HttpResponse")
|
||||
|| source.contains("#[get(")
|
||||
|| source.contains("#[post(");
|
||||
let has_axum = source.contains("axum::")
|
||||
|| source.contains("IntoResponse")
|
||||
|| source.contains("Json(")
|
||||
|| source.contains("Query(")
|
||||
|| source.contains("axum::extract");
|
||||
let has_warp = source.contains("use warp::")
|
||||
|| source.contains("warp::path!")
|
||||
|| source.contains("warp::Filter")
|
||||
|| source.contains("warp::serve")
|
||||
|| source.contains("// nyx-shape: warp");
|
||||
let has_rocket = source.contains("use rocket::")
|
||||
|| source.contains("rocket::routes")
|
||||
|| source.contains("#[launch]")
|
||||
|| source.contains("// nyx-shape: rocket");
|
||||
let has_actix_strong = source.contains("use actix_web")
|
||||
|| source.contains("actix_web::")
|
||||
|| source.contains("// nyx-shape: actix");
|
||||
let has_axum_strong = source.contains("use axum::")
|
||||
|| source.contains("axum::Router")
|
||||
|| source.contains("axum::routing")
|
||||
|| source.contains("// nyx-shape: axum");
|
||||
let has_attribute_route = source.contains("#[get(")
|
||||
|| source.contains("#[post(")
|
||||
|| source.contains("#[put(")
|
||||
|| source.contains("#[patch(")
|
||||
|| source.contains("#[delete(");
|
||||
let has_clap = source.contains("clap::")
|
||||
|| source.contains("#[derive(Parser)")
|
||||
|| source.contains("Parser::parse");
|
||||
|
|
@ -529,10 +558,37 @@ impl RustShape {
|
|||
|| source.contains("fuzz_target!")
|
||||
|| (source.contains("pub fn ") && source.contains("data: &[u8]"));
|
||||
|
||||
if has_axum {
|
||||
// Phase 17 framework variants win over the pre-Phase-16 weak
|
||||
// detectors. Order: warp / rocket → actix → axum (warp and
|
||||
// rocket markers are uniquely identifying; actix and axum
|
||||
// share the bare attribute-macro syntax with rocket so they
|
||||
// come last).
|
||||
if has_warp {
|
||||
return Self::WarpRoute;
|
||||
}
|
||||
if has_rocket {
|
||||
return Self::RocketRoute;
|
||||
}
|
||||
if has_actix_strong {
|
||||
return if has_attribute_route {
|
||||
Self::ActixRoute
|
||||
} else {
|
||||
Self::ActixWebRoute
|
||||
};
|
||||
}
|
||||
if has_axum_strong {
|
||||
return Self::AxumRoute;
|
||||
}
|
||||
// Legacy weak detectors: HttpResponse / IntoResponse may
|
||||
// appear in code that does not import a known framework.
|
||||
let has_actix_weak = source.contains("HttpResponse") || source.contains("HttpRequest");
|
||||
let has_axum_weak = source.contains("IntoResponse")
|
||||
|| source.contains("Json(")
|
||||
|| source.contains("Query(");
|
||||
if has_axum_weak {
|
||||
return Self::AxumHandler;
|
||||
}
|
||||
if has_actix {
|
||||
if has_actix_weak || has_attribute_route {
|
||||
return Self::ActixWebRoute;
|
||||
}
|
||||
if has_clap {
|
||||
|
|
@ -770,8 +826,15 @@ pub fn emit(spec: &HarnessSpec) -> Result<HarnessSource, UnsupportedReason> {
|
|||
// pre-Phase-16 generic path so existing callers don't change shape.
|
||||
match (&spec.payload_slot, shape) {
|
||||
(PayloadSlot::Param(0) | PayloadSlot::EnvVar(_), _) => {}
|
||||
(PayloadSlot::QueryParam(_) | PayloadSlot::HttpBody, RustShape::ActixWebRoute)
|
||||
| (PayloadSlot::QueryParam(_) | PayloadSlot::HttpBody, RustShape::AxumHandler) => {}
|
||||
(
|
||||
PayloadSlot::QueryParam(_) | PayloadSlot::HttpBody,
|
||||
RustShape::ActixWebRoute
|
||||
| RustShape::ActixRoute
|
||||
| RustShape::AxumHandler
|
||||
| RustShape::AxumRoute
|
||||
| RustShape::RocketRoute
|
||||
| RustShape::WarpRoute,
|
||||
) => {}
|
||||
(PayloadSlot::Argv(_), RustShape::ClapCli) => {}
|
||||
_ => return Err(UnsupportedReason::PayloadSlotUnsupported),
|
||||
}
|
||||
|
|
@ -919,10 +982,27 @@ fn build_call(spec: &HarnessSpec, func: &str, shape: RustShape) -> (String, Stri
|
|||
}
|
||||
RustShape::ActixWebRoute => actix_invocation(spec, func),
|
||||
RustShape::AxumHandler => axum_invocation(spec, func),
|
||||
// Phase 17 framework dispatchers. Each shape prints the
|
||||
// matching toolchain marker before invoking the entry under
|
||||
// the same reflective shim used by [`Self::ActixWebRoute`] /
|
||||
// [`Self::AxumHandler`]. Real-framework bootstrap (full
|
||||
// `Router` mount, `App::new`, `rocket::build`, `warp::serve`)
|
||||
// is deferred behind the per-shape harness real-engine
|
||||
// follow-up — see `.pitboss/play/deferred.md`.
|
||||
RustShape::ActixRoute => framework_route_invocation(spec, func, "NYX_ACTIX_TEST=1"),
|
||||
RustShape::AxumRoute => framework_route_invocation(spec, func, "NYX_AXUM_TEST=1"),
|
||||
RustShape::RocketRoute => framework_route_invocation(spec, func, "NYX_ROCKET_TEST=1"),
|
||||
RustShape::WarpRoute => framework_route_invocation(spec, func, "NYX_WARP_TEST=1"),
|
||||
RustShape::ClapCli => clap_invocation(spec, func),
|
||||
}
|
||||
}
|
||||
|
||||
fn framework_route_invocation(spec: &HarnessSpec, func: &str, marker: &str) -> (String, String) {
|
||||
let pre = format!(" println!(\"{marker}\");\n");
|
||||
let (inner_pre, call) = actix_invocation(spec, func);
|
||||
(format!("{pre}{inner_pre}"), call)
|
||||
}
|
||||
|
||||
fn actix_invocation(spec: &HarnessSpec, func: &str) -> (String, String) {
|
||||
// Real actix_web requires an async runtime; the test fixtures use a
|
||||
// synchronous shim signature `pub fn <func>(payload: &str) -> String`
|
||||
|
|
@ -1082,18 +1162,59 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn shape_detect_axum_handler() {
|
||||
// Phase 17 — Track L.15: a strong `use axum::` import now
|
||||
// routes to the framework-aware [`RustShape::AxumRoute`]
|
||||
// shape; the legacy [`RustShape::AxumHandler`] fires only on
|
||||
// weak detectors (`IntoResponse` / `Json(` without `use
|
||||
// axum::`).
|
||||
let src = "use axum::extract::Query; pub fn handler(payload: &str) -> String { String::new() }";
|
||||
let spec = make_spec_with(EntryKind::HttpRoute, "handler", "src/entry.rs");
|
||||
assert_eq!(RustShape::detect(&spec, src), RustShape::AxumRoute);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_detect_axum_weak_falls_back_to_axum_handler() {
|
||||
// No `use axum::` / `axum::Router` and no `axum::` token in
|
||||
// the body — the weak detector (`IntoResponse` / bare `Json(`)
|
||||
// routes to the legacy [`RustShape::AxumHandler`] shape.
|
||||
let src = "pub fn handler() -> impl IntoResponse { let _ = Json(\"\".to_string()); }";
|
||||
let spec = make_spec_with(EntryKind::HttpRoute, "handler", "src/entry.rs");
|
||||
assert_eq!(RustShape::detect(&spec, src), RustShape::AxumHandler);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_detect_actix_route() {
|
||||
// Phase 17 — Track L.15: a strong `use actix_web::` import
|
||||
// + attribute macro `#[get(...)]` routes to the
|
||||
// [`RustShape::ActixRoute`] shape. Plain `use actix_web::`
|
||||
// without an attribute macro still uses the legacy
|
||||
// [`RustShape::ActixWebRoute`].
|
||||
let src = "use actix_web::HttpResponse; pub fn handler(payload: &str) -> String { String::new() }";
|
||||
let spec = make_spec_with(EntryKind::HttpRoute, "handler", "src/entry.rs");
|
||||
assert_eq!(RustShape::detect(&spec, src), RustShape::ActixWebRoute);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_detect_actix_attribute_route() {
|
||||
let src = "use actix_web::get;\n#[get(\"/x\")]\npub async fn handler() -> String { String::new() }";
|
||||
let spec = make_spec_with(EntryKind::HttpRoute, "handler", "src/entry.rs");
|
||||
assert_eq!(RustShape::detect(&spec, src), RustShape::ActixRoute);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_detect_rocket_route() {
|
||||
let src = "use rocket::get;\n#[get(\"/x\")]\nfn handler() -> &'static str { \"ok\" }";
|
||||
let spec = make_spec_with(EntryKind::HttpRoute, "handler", "src/entry.rs");
|
||||
assert_eq!(RustShape::detect(&spec, src), RustShape::RocketRoute);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_detect_warp_route() {
|
||||
let src = "use warp::Filter;\nfn build() { let r = warp::path!(\"x\").map(handler); }";
|
||||
let spec = make_spec_with(EntryKind::HttpRoute, "handler", "src/entry.rs");
|
||||
assert_eq!(RustShape::detect(&spec, src), RustShape::WarpRoute);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shape_detect_clap_cli() {
|
||||
let src = "use clap::Parser; pub fn run(args: Vec<String>) {}";
|
||||
|
|
@ -1147,6 +1268,37 @@ mod tests {
|
|||
assert!(src.contains("entry::fuzz_target(payload.as_bytes())"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn axum_route_emits_marker() {
|
||||
let spec = make_spec_with(EntryKind::HttpRoute, "run", "src/entry.rs");
|
||||
let src = generate_main_rs(&spec, RustShape::AxumRoute);
|
||||
assert!(
|
||||
src.contains("NYX_AXUM_TEST=1"),
|
||||
"AxumRoute must print NYX_AXUM_TEST=1 marker, got: {src}",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn actix_route_emits_marker() {
|
||||
let spec = make_spec_with(EntryKind::HttpRoute, "run", "src/entry.rs");
|
||||
let src = generate_main_rs(&spec, RustShape::ActixRoute);
|
||||
assert!(src.contains("NYX_ACTIX_TEST=1"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rocket_route_emits_marker() {
|
||||
let spec = make_spec_with(EntryKind::HttpRoute, "run", "src/entry.rs");
|
||||
let src = generate_main_rs(&spec, RustShape::RocketRoute);
|
||||
assert!(src.contains("NYX_ROCKET_TEST=1"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn warp_route_emits_marker() {
|
||||
let spec = make_spec_with(EntryKind::HttpRoute, "run", "src/entry.rs");
|
||||
let src = generate_main_rs(&spec, RustShape::WarpRoute);
|
||||
assert!(src.contains("NYX_WARP_TEST=1"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn emit_splices_probe_shim_and_installs_crash_guard() {
|
||||
// Phase 16 follow-up: Rust emitter now splices probe_shim() into
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue