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 }