lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

conformance.rs (3225B)


      1 #![cfg(feature = "serde")]
      2 
      3 use std::collections::BTreeSet;
      4 
      5 use radroots_identity::{
      6     AccountId, IdentityId, Profile, PublicIdentity, PublicKey, Username,
      7     account::{Record, Status},
      8 };
      9 use serde_json::Value;
     10 
     11 const PUBLIC_VALUE_VECTORS: &str = include_str!("fixtures/public_values.v1.json");
     12 
     13 #[test]
     14 fn public_value_vectors_are_unique_complete_and_executable() {
     15     let suite: Value = serde_json::from_str(PUBLIC_VALUE_VECTORS).expect("valid vector suite");
     16     assert_eq!(suite["suite"], "identity_public_values");
     17     assert_eq!(suite["contract_version"], "1.0.0");
     18 
     19     let vectors = suite["vectors"].as_array().expect("vector array");
     20     let mut ids = BTreeSet::new();
     21     for vector in vectors {
     22         let id = vector["id"].as_str().expect("vector id");
     23         assert!(ids.insert(id), "duplicate vector id {id}");
     24         let kind = vector["kind"].as_str().expect("vector kind");
     25         let input = vector["input"].clone();
     26         if let Some(expected) = vector.get("expected") {
     27             let actual = execute_valid(kind, input);
     28             assert_eq!(&actual, expected, "vector {id}");
     29         } else {
     30             let expected = vector["expected_error_contains"]
     31                 .as_str()
     32                 .expect("invalid vector error fragment");
     33             let error = execute_invalid(kind, input);
     34             assert!(
     35                 error.contains(expected),
     36                 "vector {id} expected error containing {expected:?}, got {error:?}"
     37             );
     38         }
     39     }
     40     assert_eq!(ids.len(), 14);
     41 }
     42 
     43 fn execute_valid(kind: &str, input: Value) -> Value {
     44     match kind {
     45         "identity.public_key.serde" => round_trip::<PublicKey>(input),
     46         "identity.identity_id.serde" => round_trip::<IdentityId>(input),
     47         "identity.account_id.serde" => round_trip::<AccountId>(input),
     48         "identity.username.serde" => round_trip::<Username>(input),
     49         "identity.profile.serde" => round_trip::<Profile>(input),
     50         "identity.public_identity.serde" => round_trip::<PublicIdentity>(input),
     51         "identity.account_record.serde" => round_trip::<Record>(input),
     52         "identity.account_status.serde" => round_trip::<Status>(input),
     53         unsupported => panic!("unsupported valid identity vector kind {unsupported}"),
     54     }
     55 }
     56 
     57 fn execute_invalid(kind: &str, input: Value) -> String {
     58     match kind {
     59         "identity.public_key.invalid" => decode_error::<PublicKey>(input),
     60         "identity.public_identity.invalid" => decode_error::<PublicIdentity>(input),
     61         "identity.account_record.invalid" => decode_error::<Record>(input),
     62         "identity.username.invalid" => decode_error::<Username>(input),
     63         unsupported => panic!("unsupported invalid identity vector kind {unsupported}"),
     64     }
     65 }
     66 
     67 fn round_trip<T>(input: Value) -> Value
     68 where
     69     T: serde::de::DeserializeOwned + serde::Serialize,
     70 {
     71     serde_json::to_value(serde_json::from_value::<T>(input).expect("valid vector input"))
     72         .expect("serialize canonical value")
     73 }
     74 
     75 fn decode_error<T>(input: Value) -> String
     76 where
     77     T: serde::de::DeserializeOwned + core::fmt::Debug,
     78 {
     79     serde_json::from_value::<T>(input)
     80         .expect_err("invalid vector must be rejected")
     81         .to_string()
     82 }