use multi_codec::Codec;
use multi_hash::{Builder, Error, Multihash, HASH_CODECS, SAFE_HASH_CODECS};
use multi_trait::{Null, TryDecodeFrom};
use multi_util::CodecInfo;
#[test]
fn test_all_algorithms_empty_input() {
for &codec in HASH_CODECS.iter() {
let result = Builder::new_from_bytes(codec, []);
assert!(result.is_ok(), "Failed for {:?}", codec);
let mh = result.unwrap().try_build().unwrap();
assert_eq!(mh.codec(), codec);
}
}
#[test]
fn test_all_algorithms_single_byte() {
for &codec in HASH_CODECS.iter() {
let mh = Builder::new_from_bytes(codec, [0x42])
.unwrap()
.try_build()
.unwrap();
assert_eq!(mh.codec(), codec);
assert!(!mh.as_ref().is_empty());
}
}
#[test]
fn test_null_multihash() {
let null_mh = Multihash::null();
assert!(null_mh.is_null());
assert_eq!(null_mh, Multihash::default());
assert_eq!(null_mh.codec(), Codec::Identity);
assert_eq!(null_mh.as_ref(), &[] as &[u8]);
}
#[test]
fn test_builder_missing_hash() {
let result = Builder::new(Codec::Sha2256).try_build();
assert!(result.is_err());
assert!(matches!(result.unwrap_err(), Error::MissingHash));
}
#[test]
fn test_unsupported_algorithm() {
let result = Builder::new_from_bytes(Codec::Identity, b"data");
assert!(result.is_err());
assert!(matches!(result.unwrap_err(), Error::UnsupportedHash { .. }));
}
#[test]
fn test_large_data() {
let large_data = vec![0u8; 1024 * 1024]; let mh = Builder::new_from_bytes(Codec::Sha2256, &large_data)
.unwrap()
.try_build()
.unwrap();
assert_eq!(mh.codec(), Codec::Sha2256);
assert_eq!(mh.as_ref().len(), 32); }
#[test]
fn test_binary_roundtrip_all_algorithms() {
let data = b"test data";
for &codec in HASH_CODECS.iter() {
let mh1 = Builder::new_from_bytes(codec, data)
.unwrap()
.try_build()
.unwrap();
let bytes: Vec<u8> = mh1.clone().into();
let mh2 = Multihash::try_from(bytes.as_ref()).unwrap();
assert_eq!(mh1, mh2);
assert_eq!(mh1.codec(), mh2.codec());
}
}
#[test]
fn test_safe_codecs_subset() {
for &safe_codec in SAFE_HASH_CODECS.iter() {
assert!(
HASH_CODECS.contains(&safe_codec),
"{:?} not in HASH_CODECS",
safe_codec
);
}
}
#[test]
fn test_multihash_equality() {
let mh1 = Builder::new_from_bytes(Codec::Sha2256, b"data")
.unwrap()
.try_build()
.unwrap();
let mh2 = mh1.clone();
assert_eq!(mh1, mh2);
assert_eq!(mh1, mh1);
}
#[test]
fn test_multihash_ordering() {
let mh1 = Builder::new_from_bytes(Codec::Sha2256, b"aaa")
.unwrap()
.try_build()
.unwrap();
let mh2 = Builder::new_from_bytes(Codec::Sha2256, b"bbb")
.unwrap()
.try_build()
.unwrap();
assert_ne!(mh1, mh2);
}
#[test]
fn test_as_ref() {
let mh = Builder::new_from_bytes(Codec::Sha2256, b"test")
.unwrap()
.try_build()
.unwrap();
let bytes: &[u8] = mh.as_ref();
assert_eq!(bytes.len(), 32); }
#[test]
fn test_debug_format() {
let mh = Builder::new_from_bytes(Codec::Sha2256, b"test")
.unwrap()
.try_build()
.unwrap();
let debug_str = format!("{:?}", mh);
assert!(!debug_str.is_empty());
assert!(debug_str.len() > 10);
}
#[test]
fn test_builder_with_hash() {
let hash_bytes = vec![0u8; 32];
let mh = Builder::new(Codec::Sha2256)
.with_hash(hash_bytes.clone())
.try_build()
.unwrap();
assert_eq!(mh.codec(), Codec::Sha2256);
assert_eq!(mh.as_ref(), hash_bytes.as_slice());
}
#[test]
fn test_clone() {
let mh1 = Builder::new_from_bytes(Codec::Sha3256, b"clone test")
.unwrap()
.try_build()
.unwrap();
let mh2 = mh1.clone();
assert_eq!(mh1, mh2);
assert_eq!(mh1.codec(), mh2.codec());
assert_eq!(mh1.as_ref(), mh2.as_ref());
}
#[test]
fn test_decode_with_trailing_data() {
let mh1 = Builder::new_from_bytes(Codec::Sha2256, b"test")
.unwrap()
.try_build()
.unwrap();
let mut bytes: Vec<u8> = mh1.clone().into();
bytes.extend_from_slice(&[0xAA, 0xBB, 0xCC]);
let (mh2, remaining) = Multihash::try_decode_from(&bytes).unwrap();
assert_eq!(mh1, mh2);
assert_eq!(remaining, &[0xAA, 0xBB, 0xCC]);
}
#[test]
fn test_truncated_data() {
let mh = Builder::new_from_bytes(Codec::Sha2256, b"test")
.unwrap()
.try_build()
.unwrap();
let bytes: Vec<u8> = mh.into();
if !bytes.is_empty() {
let truncated = &bytes[..1];
let result = Multihash::try_from(truncated);
assert!(result.is_err());
}
}
#[test]
fn test_send_sync() {
fn assert_send<T: Send>() {}
fn assert_sync<T: Sync>() {}
assert_send::<Multihash>();
assert_sync::<Multihash>();
assert_send::<Builder>();
assert_sync::<Builder>();
}