use super::{Name, NameError};
#[test]
fn empty_input_accepted() {
let n = Name::try_from_str("").unwrap();
assert!(n.is_empty());
assert_eq!(n.as_str(), "");
}
#[test]
fn canonical_lowercase_normalization() {
let n = Name::try_from_str("My.Local.").unwrap();
assert_eq!(n.as_str(), "my.local.");
}
#[test]
fn from_wire_labels_preserves_utf8_and_folds_ascii() {
let labels: [Result<&[u8], core::convert::Infallible>; 2] = [Ok(b"Caf\xc3\xa9"), Ok(b"local")];
let n = Name::from_wire_labels(labels).unwrap();
assert_eq!(n.as_str(), "café.local.");
}
#[test]
fn from_wire_labels_rejects_non_utf8() {
let labels: [Result<&[u8], core::convert::Infallible>; 1] = [Ok(b"\xff\xfe")];
assert!(Name::from_wire_labels(labels).is_none());
}
#[test]
fn from_wire_labels_rejects_malformed_label() {
let labels: [Result<&[u8], &str>; 2] = [Ok(b"ok"), Err("truncated")];
assert!(Name::from_wire_labels(labels).is_none());
}
#[test]
fn from_wire_labels_rejects_dot_bearing_label_so_no_cache_aliasing() {
let dotted: [Result<&[u8], core::convert::Infallible>; 2] = [Ok(b"a.b"), Ok(b"local")];
assert!(Name::from_wire_labels(dotted).is_none());
let split: [Result<&[u8], core::convert::Infallible>; 3] = [Ok(b"a"), Ok(b"b"), Ok(b"local")];
assert_eq!(
Name::from_wire_labels(split).unwrap().as_str(),
"a.b.local."
);
}
#[test]
fn from_wire_labels_bounds_allocation_before_validation() {
let long = [b'a'; 64];
let one: [Result<&[u8], core::convert::Infallible>; 1] = [Ok(&long[..])];
assert!(Name::from_wire_labels(one).is_none());
let label = [b'a'; 63];
let many: [Result<&[u8], core::convert::Infallible>; 10] = [Ok(&label[..]); 10];
assert!(Name::from_wire_labels(many).is_none());
}
#[test]
fn accepts_trailing_dot() {
let n = Name::try_from_str("foo.local.").unwrap();
assert_eq!(n.as_str(), "foo.local.");
}
#[test]
fn rejects_label_over_63_bytes() {
let long = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; let err = Name::try_from_str(long).unwrap_err();
assert!(matches!(err, NameError::LabelTooLong(_)));
}
#[test]
fn rejects_empty_label() {
let err = Name::try_from_str("foo..bar").unwrap_err();
assert!(matches!(err, NameError::EmptyLabel));
}
#[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn enforces_wire_length_not_string_length() {
let at_limit = std::format!(
"{}.{}.{}.{}",
"a".repeat(63),
"a".repeat(63),
"a".repeat(63),
"a".repeat(61)
);
assert_eq!(at_limit.len(), 253);
assert!(
Name::try_from_str(&at_limit).is_ok(),
"a name whose wire form is exactly 255 octets must be accepted"
);
let over_limit = std::format!(
"{}.{}.{}.{}",
"a".repeat(63),
"a".repeat(63),
"a".repeat(63),
"a".repeat(62)
);
assert_eq!(over_limit.len(), 254);
let err = Name::try_from_str(&over_limit).unwrap_err();
assert!(
matches!(err, NameError::NameTooLong(_)),
"a name whose wire form exceeds 255 octets must be rejected despite a string length <= 255"
);
}
#[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn rejects_string_longer_than_max_name_bytes() {
let over = "a".repeat(256);
let err = Name::try_from_str(&over).unwrap_err();
match err {
NameError::NameTooLong(detail) => assert_eq!(detail.len(), 256),
other => panic!("expected NameTooLong, got {other:?}"),
}
}
#[test]
fn name_len_reports_byte_length() {
let n = Name::try_from_str("foo.local.").unwrap();
assert_eq!(n.len(), 10);
assert_eq!(n.len(), n.as_str().len());
let empty = Name::try_from_str("").unwrap();
assert_eq!(empty.len(), 0);
}
#[test]
fn label_too_long_detail_accessors() {
let long = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; assert_eq!(long.len(), 64);
let err = Name::try_from_str(long).unwrap_err();
match err {
NameError::LabelTooLong(detail) => {
assert_eq!(detail.len(), long.len());
assert!(!detail.is_empty());
}
other => panic!("expected LabelTooLong, got {other:?}"),
}
}
#[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn name_too_long_detail_accessors() {
let over_limit = std::format!(
"{}.{}.{}.{}",
"a".repeat(63),
"a".repeat(63),
"a".repeat(63),
"a".repeat(62)
);
let err = Name::try_from_str(&over_limit).unwrap_err();
match err {
NameError::NameTooLong(detail) => {
assert_eq!(detail.len(), 256);
assert!(!detail.is_empty());
}
other => panic!("expected NameTooLong, got {other:?}"),
}
}