use base64::Engine;
use base64::engine::general_purpose::STANDARD as BASE64;
use std::eprintln;
use std::string::String;
use std::vec::Vec;
use crate::core::matter::code::DigestCode;
use crate::serder::deserialize::deserialize_event;
use crate::serder::primitives::to_qb64_string;
use crate::serder::serialize::{SerializedEvent, serialize};
use super::{SaidCodeVector, load_said_codes};
const TRACKED: &[(&str, &str, &str)] = &[
("incept", "digest_Blake2b_256", "#160"),
("incept", "digest_Blake2b_512", "#160"),
("incept", "digest_Blake2s_256", "#160"),
("incept", "digest_Blake3_512", "#160"),
("incept", "digest_SHA2_256", "#160"),
("incept", "digest_SHA2_512", "#160"),
("incept", "digest_SHA3_256", "#160"),
("incept", "digest_SHA3_512", "#160"),
("delcept", "digest_SHA3_256", "#160"),
];
fn tracked_issue(v: &SaidCodeVector) -> Option<&'static str> {
TRACKED
.iter()
.find(|(factory, case, _)| *factory == v.factory && *case == v.case)
.map(|(_, _, issue)| *issue)
}
#[allow(
clippy::panic,
reason = "test-only corpus loader: panics with context on malformed fixtures"
)]
fn decode_raw(v: &SaidCodeVector) -> Vec<u8> {
BASE64
.decode(&v.raw_b64)
.unwrap_or_else(|e| panic!("decode raw_b64 for {}/{}: {e}", v.factory, v.case))
}
fn round_trip(raw: &[u8]) -> Result<SerializedEvent, String> {
let event = deserialize_event(raw).map_err(|e| alloc::format!("read: {e}"))?;
let reser = serialize(&event).map_err(|e| alloc::format!("write: {e}"))?;
if reser.as_bytes() == raw {
Ok(reser)
} else {
Err(alloc::format!(
"re-serialized bytes differ: {} vs {}",
String::from_utf8_lossy(reser.as_bytes()),
String::from_utf8_lossy(raw),
))
}
}
#[test]
#[allow(
clippy::panic,
clippy::print_stderr,
reason = "test-only sweep: failed round trips panic with context; tracked skips logged"
)]
fn representable_vectors_round_trip_byte_identically() {
let mut asserted = 0usize;
let mut skipped = 0usize;
for v in load_said_codes() {
if let Some(issue) = tracked_issue(&v) {
eprintln!("TRACKED {}/{}: {issue}", v.factory, v.case);
skipped += 1;
continue;
}
let raw = decode_raw(&v);
let reser =
round_trip(&raw).unwrap_or_else(|e| panic!("round trip {}/{}: {e}", v.factory, v.case));
assert_eq!(
to_qb64_string(reser.said()),
v.said,
"{}/{}: cesr must reproduce keripy's said",
v.factory,
v.case
);
asserted += 1;
}
eprintln!("said_codes: {asserted} asserted, {skipped} tracked (#160)");
assert_eq!(
asserted, 3,
"expected the basic + two Blake3-256 control rows to assert"
);
}
#[test]
fn keripy_keeps_d_at_blake3_when_overriding_i() {
let blake3_qb64_code = "E";
for v in load_said_codes() {
if v.code.is_empty() {
continue; }
assert!(
v.said.starts_with(blake3_qb64_code),
"{}/{}: keripy computes d under the Blake3-256 default, got {}",
v.factory,
v.case,
v.said
);
assert!(
v.pre.starts_with(&v.code),
"{}/{}: keripy derives i under the override code {}, got {}",
v.factory,
v.case,
v.code,
v.pre
);
assert_eq!(
v.said == v.pre,
v.code == "E",
"{}/{}: i == d exactly when the override is Blake3-256",
v.factory,
v.case
);
}
}
#[test]
fn builder_said_code_output_verifies_per_field() {
use crate::core::matter::builder::MatterBuilder;
use crate::core::matter::code::VerKeyCode;
use crate::serder::builder::InceptionBuilder;
use crate::serder::said::verify_said;
let verfer = MatterBuilder::new()
.with_code(VerKeyCode::Ed25519)
.with_raw(alloc::vec![7u8; 32])
.unwrap()
.build()
.unwrap();
let icp = InceptionBuilder::new()
.keys(alloc::vec![verfer])
.said_code(DigestCode::SHA3_256)
.build()
.unwrap();
verify_said(icp.as_bytes(), DigestCode::SHA3_256)
.expect("builder SHA3-256 double-SAID must verify");
}
#[test]
fn tracked_entries_are_not_stale() {
for v in load_said_codes() {
if tracked_issue(&v).is_none() {
continue;
}
let raw = decode_raw(&v);
assert!(
round_trip(&raw).is_err(),
"{}/{}: tracked as unreadable but now round-trips — remove it from TRACKED",
v.factory,
v.case
);
}
}
#[test]
#[ignore = "bug-probe for #160: read path rejects keripy mixed-code (i-code != d-code) inceptions"]
#[allow(
clippy::panic,
reason = "test-only bug-probe: failed round trips panic with context"
)]
fn mixed_code_vectors_round_trip_byte_identically() {
for v in load_said_codes() {
if tracked_issue(&v).is_none() {
continue;
}
let raw = decode_raw(&v);
round_trip(&raw).unwrap_or_else(|e| panic!("round trip {}/{}: {e}", v.factory, v.case));
}
}