techne-sdk 0.3.8

TechneSDK's logic written once: version ranking (eventState) and offline record verification over the published check, shipped to TypeScript as WebAssembly; with opt-in atproto plumbing (service auth, DID resolution, signed labels, proven record fetches, PDS password sessions) behind the `crypto` and `net` features.
Documentation
//! P13.4: the shared fixtures (`fixtures/cases.json`) answer the same in Rust as in the TypeScript
//! package (`sdk/src/wasm/wasm.test.mjs` runs the same file through the WebAssembly and its wasm2js
//! translation). Every case goes through `call`, the one boundary the WebAssembly exports.

use serde_json::Value;

#[test]
fn every_shared_fixture_answers_its_expectation_in_rust() {
    let fixtures: Value = serde_json::from_str(include_str!("../fixtures/cases.json")).expect("cases.json is JSON");
    let cases = fixtures["cases"].as_array().expect("cases");
    assert!(cases.len() >= 20, "the fixture set is all there");
    for case in cases {
        let (function, name) = (case["fn"].as_str().unwrap(), case["name"].as_str().unwrap());
        let got = techne_sdk::call(function, &case["args"]).unwrap_or_else(|e| panic!("{function} {name}: {e}"));
        assert_eq!(got, case["expect"], "{function}: {name}");
    }
}

#[test]
fn an_unknown_function_is_an_error() {
    assert!(techne_sdk::call("nope", &serde_json::json!({})).is_err());
}

/// The WebAssembly has no clock, so `put` and `putPlan` through `call` take the caller's `now` (unix
/// seconds) and refuse without one. Answering as of 0 would treat every old name as still renamed,
/// and so as having a lexicon, long after its last day.
#[test]
fn put_and_put_plan_refuse_without_now() {
    let fixtures: Value = serde_json::from_str(include_str!("../fixtures/cases.json")).expect("cases.json is JSON");
    for function in ["put", "putPlan"] {
        let case = fixtures["cases"].as_array().unwrap().iter().find(|c| c["fn"] == function).expect("a fixture");
        let mut args = case["args"].clone();
        assert!(args.as_object_mut().unwrap().remove("now").is_some(), "{function}: the fixture passes now");
        let err = techne_sdk::call(function, &args).expect_err("refused without now");
        assert!(err.contains("now"), "{function}: names what is missing: {err}");
    }
}