atagen

jelq

public

an http based roguelike rpg about jelqing

Star0
Watch0
8ab6a1382c4c997e5e0544c2af62018ca376c78b
1
ssh://brewery@pls.lobotomise.me:33/atagen/jelq.git

Blame: src/tests/mod.rs

8b8e83329a1datagen2026-10-12 12:01 UTC1
mod body;
8b8e83329a1datagen2026-10-12 12:01 UTC2
mod floors;
8b8e83329a1datagen2026-10-12 12:01 UTC3
mod household;
8b8e83329a1datagen2026-10-12 12:01 UTC4
mod meta;
8b8e83329a1datagen2026-10-12 12:01 UTC5
mod methods;
8b8e83329a1datagen2026-10-12 12:01 UTC6
mod rolls;
8b8e83329a1datagen2026-10-12 12:01 UTC7
mod turns;
8b8e83329a1datagen2026-10-12 12:01 UTC8
8b8e83329a1datagen2026-10-12 12:01 UTC9
pub use std::{sync::Arc, time::Duration};
8b8e83329a1datagen2026-10-12 12:01 UTC10
8b8e83329a1datagen2026-10-12 12:01 UTC11
pub use axum::{
8b8e83329a1datagen2026-10-12 12:01 UTC12
    Router,
8b8e83329a1datagen2026-10-12 12:01 UTC13
    body::{Body, to_bytes},
8b8e83329a1datagen2026-10-12 12:01 UTC14
    http::{Method, Request, StatusCode, Version, header},
8b8e83329a1datagen2026-10-12 12:01 UTC15
    response::Response,
8b8e83329a1datagen2026-10-12 12:01 UTC16
};
8b8e83329a1datagen2026-10-12 12:01 UTC17
pub use serde_json::Value;
8b8e83329a1datagen2026-10-12 12:01 UTC18
use tower::ServiceExt;
8b8e83329a1datagen2026-10-12 12:01 UTC19
8b8e83329a1datagen2026-10-12 12:01 UTC20
pub use crate::{
8b8e83329a1datagen2026-10-12 12:01 UTC21
    AppState, Config,
8b8e83329a1datagen2026-10-12 12:01 UTC22
    game::{
8b8e83329a1datagen2026-10-12 12:01 UTC23
        Excuse, Floor, MumVisit, Run, Story,
8b8e83329a1datagen2026-10-12 12:01 UTC24
        balance::{BRANCH_TURN, SUSPICION_LIMIT},
8b8e83329a1datagen2026-10-12 12:01 UTC25
    },
8b8e83329a1datagen2026-10-12 12:01 UTC26
    router,
8b8e83329a1datagen2026-10-12 12:01 UTC27
};
8b8e83329a1datagen2026-10-12 12:01 UTC28
880b29a0c11eatagen2026-10-13 09:27 UTC29
pub const SEED: u64 = 420;
8b8e83329a1datagen2026-10-12 12:01 UTC30
8b8e83329a1datagen2026-10-12 12:01 UTC31
pub async fn send(
8b8e83329a1datagen2026-10-12 12:01 UTC32
    app: &Router,
8b8e83329a1datagen2026-10-12 12:01 UTC33
    method: &str,
8b8e83329a1datagen2026-10-12 12:01 UTC34
    uri: &str,
8b8e83329a1datagen2026-10-12 12:01 UTC35
    headers: &[(&str, &str)],
8b8e83329a1datagen2026-10-12 12:01 UTC36
    body: &str,
8b8e83329a1datagen2026-10-12 12:01 UTC37
) -> Response {
8b8e83329a1datagen2026-10-12 12:01 UTC38
    let mut request = Request::builder()
8b8e83329a1datagen2026-10-12 12:01 UTC39
        .method(Method::from_bytes(method.as_bytes()).unwrap())
8b8e83329a1datagen2026-10-12 12:01 UTC40
        .uri(uri);
8b8e83329a1datagen2026-10-12 12:01 UTC41
    for (name, value) in headers {
8b8e83329a1datagen2026-10-12 12:01 UTC42
        request = request.header(*name, *value);
8b8e83329a1datagen2026-10-12 12:01 UTC43
    }
8b8e83329a1datagen2026-10-12 12:01 UTC44
    app.clone()
8b8e83329a1datagen2026-10-12 12:01 UTC45
        .oneshot(request.body(Body::from(body.to_owned())).unwrap())
8b8e83329a1datagen2026-10-12 12:01 UTC46
        .await
8b8e83329a1datagen2026-10-12 12:01 UTC47
        .unwrap()
8b8e83329a1datagen2026-10-12 12:01 UTC48
}
8b8e83329a1datagen2026-10-12 12:01 UTC49
8b8e83329a1datagen2026-10-12 12:01 UTC50
pub async fn json(response: Response) -> Value {
8b8e83329a1datagen2026-10-12 12:01 UTC51
    serde_json::from_slice(&to_bytes(response.into_body(), usize::MAX).await.unwrap()).unwrap()
8b8e83329a1datagen2026-10-12 12:01 UTC52
}
8b8e83329a1datagen2026-10-12 12:01 UTC53
8b8e83329a1datagen2026-10-12 12:01 UTC54
pub async fn text(response: Response) -> String {
8b8e83329a1datagen2026-10-12 12:01 UTC55
    String::from_utf8(
8b8e83329a1datagen2026-10-12 12:01 UTC56
        to_bytes(response.into_body(), usize::MAX)
8b8e83329a1datagen2026-10-12 12:01 UTC57
            .await
8b8e83329a1datagen2026-10-12 12:01 UTC58
            .unwrap()
8b8e83329a1datagen2026-10-12 12:01 UTC59
            .to_vec(),
8b8e83329a1datagen2026-10-12 12:01 UTC60
    )
8b8e83329a1datagen2026-10-12 12:01 UTC61
    .unwrap()
8b8e83329a1datagen2026-10-12 12:01 UTC62
}
8b8e83329a1datagen2026-10-12 12:01 UTC63
8b8e83329a1datagen2026-10-12 12:01 UTC64
pub fn header<'a>(response: &'a Response, name: &str) -> &'a str {
8b8e83329a1datagen2026-10-12 12:01 UTC65
    response.headers()[name].to_str().unwrap()
8b8e83329a1datagen2026-10-12 12:01 UTC66
}
8b8e83329a1datagen2026-10-12 12:01 UTC67
8b8e83329a1datagen2026-10-12 12:01 UTC68
/// Every `Warning` on a response, since a turn can carry several.
8b8e83329a1datagen2026-10-12 12:01 UTC69
pub fn warnings(response: &Response) -> Vec<String> {
8b8e83329a1datagen2026-10-12 12:01 UTC70
    response
8b8e83329a1datagen2026-10-12 12:01 UTC71
        .headers()
8b8e83329a1datagen2026-10-12 12:01 UTC72
        .get_all("warning")
8b8e83329a1datagen2026-10-12 12:01 UTC73
        .iter()
8b8e83329a1datagen2026-10-12 12:01 UTC74
        .map(|value| value.to_str().unwrap().to_owned())
8b8e83329a1datagen2026-10-12 12:01 UTC75
        .collect()
8b8e83329a1datagen2026-10-12 12:01 UTC76
}
8b8e83329a1datagen2026-10-12 12:01 UTC77
8b8e83329a1datagen2026-10-12 12:01 UTC78
/// A server holding one run, `cafebabe`, set up by `setup` before anyone can reach it.
8b8e83329a1datagen2026-10-12 12:01 UTC79
pub struct Harness {
8b8e83329a1datagen2026-10-12 12:01 UTC80
    pub app: Router,
8b8e83329a1datagen2026-10-12 12:01 UTC81
    pub origin: String,
8b8e83329a1datagen2026-10-12 12:01 UTC82
}
8b8e83329a1datagen2026-10-12 12:01 UTC83
8b8e83329a1datagen2026-10-12 12:01 UTC84
pub fn harness(floor: Floor, seed: u64, setup: impl FnOnce(&mut Run)) -> Harness {
8b8e83329a1datagen2026-10-12 12:01 UTC85
    let state = Arc::new(AppState::default());
8b8e83329a1datagen2026-10-12 12:01 UTC86
    let mut run = Run::new("cafebabe".into(), "cafe".into(), seed);
8b8e83329a1datagen2026-10-12 12:01 UTC87
    run.floor = floor;
8b8e83329a1datagen2026-10-12 12:01 UTC88
    setup(&mut run);
8b8e83329a1datagen2026-10-12 12:01 UTC89
    let origin = run.origin_etag();
8b8e83329a1datagen2026-10-12 12:01 UTC90
    state.insert(run);
8b8e83329a1datagen2026-10-12 12:01 UTC91
    Harness {
8b8e83329a1datagen2026-10-12 12:01 UTC92
        app: router(state),
8b8e83329a1datagen2026-10-12 12:01 UTC93
        origin,
8b8e83329a1datagen2026-10-12 12:01 UTC94
    }
8b8e83329a1datagen2026-10-12 12:01 UTC95
}
8b8e83329a1datagen2026-10-12 12:01 UTC96
8b8e83329a1datagen2026-10-12 12:01 UTC97
pub fn seeded_with(floor: Floor, setup: impl FnOnce(&mut Run)) -> Router {
8b8e83329a1datagen2026-10-12 12:01 UTC98
    harness(floor, SEED, setup).app
8b8e83329a1datagen2026-10-12 12:01 UTC99
}
8b8e83329a1datagen2026-10-12 12:01 UTC100
8b8e83329a1datagen2026-10-12 12:01 UTC101
pub fn app_with(floor: Floor, seed: u64, setup: impl FnOnce(&mut Run)) -> Router {
8b8e83329a1datagen2026-10-12 12:01 UTC102
    harness(floor, seed, setup).app
8b8e83329a1datagen2026-10-12 12:01 UTC103
}
8b8e83329a1datagen2026-10-12 12:01 UTC104
8b8e83329a1datagen2026-10-12 12:01 UTC105
pub fn app() -> Router {
8b8e83329a1datagen2026-10-12 12:01 UTC106
    crate::app(Config::default()).unwrap()
8b8e83329a1datagen2026-10-12 12:01 UTC107
}
8b8e83329a1datagen2026-10-12 12:01 UTC108
8b8e83329a1datagen2026-10-12 12:01 UTC109
pub fn mum_at_the_door(run: &mut Run) {
8b8e83329a1datagen2026-10-12 12:01 UTC110
    run.household.mum = Some(MumVisit {
8b8e83329a1datagen2026-10-12 12:01 UTC111
        errand: "She heard a noise.",
8b8e83329a1datagen2026-10-12 12:01 UTC112
        nonce: "abc".into(),
8b8e83329a1datagen2026-10-12 12:01 UTC113
        strikes: 0,
8b8e83329a1datagen2026-10-12 12:01 UTC114
        knocked: false,
8b8e83329a1datagen2026-10-12 12:01 UTC115
    });
8b8e83329a1datagen2026-10-12 12:01 UTC116
}
8b8e83329a1datagen2026-10-12 12:01 UTC117
8b8e83329a1datagen2026-10-12 12:01 UTC118
/// The `Link` entries on a response, as `(rel, title)` with the rel base stripped.
8b8e83329a1datagen2026-10-12 12:01 UTC119
pub fn links(response: &Response) -> Vec<(String, Option<String>)> {
8b8e83329a1datagen2026-10-12 12:01 UTC120
    header(response, "link")
8b8e83329a1datagen2026-10-12 12:01 UTC121
        .split(", <")
8b8e83329a1datagen2026-10-12 12:01 UTC122
        .filter_map(|entry| {
8b8e83329a1datagen2026-10-12 12:01 UTC123
            let rel = entry.split("rels/").nth(1)?.split('"').next()?.to_owned();
8b8e83329a1datagen2026-10-12 12:01 UTC124
            let title = entry
8b8e83329a1datagen2026-10-12 12:01 UTC125
                .split("title=\"")
8b8e83329a1datagen2026-10-12 12:01 UTC126
                .nth(1)
8b8e83329a1datagen2026-10-12 12:01 UTC127
                .and_then(|t| t.split('"').next())
8b8e83329a1datagen2026-10-12 12:01 UTC128
                .map(str::to_owned);
8b8e83329a1datagen2026-10-12 12:01 UTC129
            Some((rel, title))
8b8e83329a1datagen2026-10-12 12:01 UTC130
        })
8b8e83329a1datagen2026-10-12 12:01 UTC131
        .collect()
8b8e83329a1datagen2026-10-12 12:01 UTC132
}
8b8e83329a1datagen2026-10-12 12:01 UTC133
8b8e83329a1datagen2026-10-12 12:01 UTC134
pub fn advertised(response: &Response) -> Vec<String> {
8b8e83329a1datagen2026-10-12 12:01 UTC135
    links(response)
8b8e83329a1datagen2026-10-12 12:01 UTC136
        .into_iter()
8b8e83329a1datagen2026-10-12 12:01 UTC137
        .filter(|(rel, _)| rel == "technique")
8b8e83329a1datagen2026-10-12 12:01 UTC138
        .filter_map(|(_, title)| title)
8b8e83329a1datagen2026-10-12 12:01 UTC139
        .collect()
8b8e83329a1datagen2026-10-12 12:01 UTC140
}
8b8e83329a1datagen2026-10-12 12:01 UTC141
8b8e83329a1datagen2026-10-12 12:01 UTC142
pub fn linked_rels(response: &Response) -> Vec<String> {
8b8e83329a1datagen2026-10-12 12:01 UTC143
    links(response)
8b8e83329a1datagen2026-10-12 12:01 UTC144
        .into_iter()
8b8e83329a1datagen2026-10-12 12:01 UTC145
        .map(|(rel, _)| rel)
8b8e83329a1datagen2026-10-12 12:01 UTC146
        .filter(|rel| rel != "technique")
8b8e83329a1datagen2026-10-12 12:01 UTC147
        .collect()
8b8e83329a1datagen2026-10-12 12:01 UTC148
}