CodeBench: code-rs.md — spawn_server-esimerkki, {id} vahvistus, init_db yksinkertaistus
- Eksplisiittinen spawn_server()-koodi testien promptiin (async move wrappaus)
- {param} reittiohje vahvistettu kahdesti, chaining-ohje
- init_db: .expect() ei Result
- "You MUST generate ALL 6 files"
This commit is contained in:
@@ -36,7 +36,8 @@ DOCUMENTATION — every file starts with //! one-line module doc. Structs get //
|
|||||||
RULES:
|
RULES:
|
||||||
- Follow the REFERENCE IMPLEMENTATION patterns exactly
|
- Follow the REFERENCE IMPLEMENTATION patterns exactly
|
||||||
- Use axum 0.8 API: Router, Json, Path, State, StatusCode
|
- Use axum 0.8 API: Router, Json, Path, State, StatusCode
|
||||||
- Route paths use {param} syntax: "/items/{id}" — NOT /:id
|
- ROUTING: use {param} NOT :param — e.g. .route("/items/{id}", get(get_item))
|
||||||
|
- ROUTING: one .route() call per path, chain methods: .route("/items", post(create).get(list))
|
||||||
- State is SqlitePool wrapped in axum::extract::State
|
- State is SqlitePool wrapped in axum::extract::State
|
||||||
- app() takes SqlitePool as argument and calls .with_state(pool) on the Router
|
- app() takes SqlitePool as argument and calls .with_state(pool) on the Router
|
||||||
- Handlers return Result<(StatusCode, Json<T>), StatusCode> or Result<StatusCode, StatusCode>
|
- Handlers return Result<(StatusCode, Json<T>), StatusCode> or Result<StatusCode, StatusCode>
|
||||||
@@ -45,8 +46,28 @@ RULES:
|
|||||||
- Use sqlx::query("SQL") for writes (DELETE, etc.), sqlx::query_as::<_, T>("SQL") for reads
|
- Use sqlx::query("SQL") for writes (DELETE, etc.), sqlx::query_as::<_, T>("SQL") for reads
|
||||||
- Use RETURNING clause in INSERT/UPDATE queries to get the created/updated row back
|
- Use RETURNING clause in INSERT/UPDATE queries to get the created/updated row back
|
||||||
- DateTime fields: store as TEXT, use String type in Rust structs
|
- DateTime fields: store as TEXT, use String type in Rust structs
|
||||||
- Tests: each test spawns isolated server with in-memory SQLite ("sqlite::memory:") on random port (127.0.0.1:0)
|
- init_db: use .expect("msg") not Result return — keep it simple
|
||||||
- Tests: unique descriptive data in Finnish, NOT generic "test" strings
|
|
||||||
- Tests: use reqwest::Client and serde_json::json!() for request bodies
|
|
||||||
- NO markdown fences inside file content — just raw code
|
- NO markdown fences inside file content — just raw code
|
||||||
- Edition 2024 in Cargo.toml
|
- Edition 2024 in Cargo.toml
|
||||||
|
- You MUST generate ALL 6 files. Do not stop early.
|
||||||
|
|
||||||
|
TESTS — follow this exact spawn_server pattern:
|
||||||
|
|
||||||
|
async fn spawn_server() -> (reqwest::Client, String) {
|
||||||
|
let pool = sqlx::sqlite::SqlitePoolOptions::new()
|
||||||
|
.max_connections(1)
|
||||||
|
.connect("sqlite::memory:")
|
||||||
|
.await
|
||||||
|
.expect("DB failed");
|
||||||
|
init_db(&pool).await;
|
||||||
|
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.expect("Bind failed");
|
||||||
|
let addr = listener.local_addr().unwrap();
|
||||||
|
let base_url = format!("http://{addr}");
|
||||||
|
let router = app(pool);
|
||||||
|
tokio::spawn(async move { axum::serve(listener, router).await.unwrap() });
|
||||||
|
(reqwest::Client::new(), base_url)
|
||||||
|
}
|
||||||
|
|
||||||
|
- Each #[tokio::test] calls spawn_server() to get (client, url)
|
||||||
|
- Unique descriptive data in Finnish, NOT generic "test" strings
|
||||||
|
- Use serde_json::json!() for request bodies
|
||||||
|
|||||||
Reference in New Issue
Block a user