#![allow(
clippy::arithmetic_side_effects,
clippy::expect_used,
clippy::indexing_slicing,
clippy::panic,
clippy::unwrap_used
)]
use super::*;
const MOD_10_OR_11_CHECK_DIGIT_CASES: [(&str, Option<&[char]>); 6] = [
("0-306-40615-2", Some(&['2'])),
("0-8044-2957-X", Some(&['X'])),
("978-0-306-40627-0", Some(&['0'])),
("978-3-16-148410-0", Some(&['0'])),
("978-3-16-A48410-0", None),
("invalid", None),
];
const MOD_11_2_CHECK_DIGIT_CASES: [(&str, Option<&[char]>); 4] = [
("000000031415926", Some(&['9'])),
("0000000492299539", Some(&['9'])),
("0000 0004 9229 9539", Some(&['9'])),
("0000-0002-2816-415X", Some(&['X'])),
];
const MOD_97_10_CHECK_DIGIT_CASES: [(&str, Option<&[char]>); 5] = [
("0q6v6102", Some(&['0', '2'])),
("1qz5mb", Some(&['5', '6'])),
("1wass4", Some(&['8', '0'])),
("2xn1ny", Some(&['0', '6'])),
("******", None),
];
const NOID_CHECK_DIGIT_CASES: [(&str, Option<&[char]>); 2] = [("13030/xf93gt2", Some(&['q'])), ("c8131/g3js3", Some(&['v']))];
#[test]
fn test_betanumeric() {
assert!('9'.is_betanumeric());
assert!(!'a'.is_betanumeric());
assert!(!'/'.is_betanumeric());
assert_eq!('0'.to_betanumeric_ordinal(), Some(0));
assert_eq!('z'.to_betanumeric_ordinal(), Some(28));
}
#[test]
fn test_identifier_normalize_uses_declared_kind() {
let doi = Identifier {
kind: PID::DOI,
value: "https://doi.org/10.1234/ABC".to_string(),
};
let kind: &str = (&doi).into();
assert_eq!(kind, "doi");
assert_eq!(doi.normalized().unwrap().value, "10.1234/ABC");
let mismatched = Identifier {
kind: PID::ISBN,
value: "https://doi.org/10.1234/ABC".to_string(),
};
assert!(mismatched.normalized().is_none());
}
#[test]
fn test_idutils_url_cases() {
[
(
"http://nbn-resolving.org/urn:nbn:de:bvb:19-146642",
"http://nbn-resolving.org/urn:nbn:de:bvb:19-146642",
),
("http://pubmed.ncbi.nlm.nih.gov/12082125/", "http://pubmed.ncbi.nlm.nih.gov/12082125"),
("https://viaf.org/viaf/75121530", "https://viaf.org/viaf/75121530"),
]
.into_iter()
.for_each(|(value, expected)| {
let normalized = Identifier::new(value).normalized().expect("expected valid URL");
assert_eq!(normalized.kind, PID::URL, "{value}");
assert_eq!(normalized.value, expected, "{value}");
});
}
#[test]
fn test_mod_10_or_11_check_digit() {
MOD_10_OR_11_CHECK_DIGIT_CASES.into_iter().for_each(|(value, expected)| {
assert_eq!(mod_10_or_11_check_digit(value).as_deref(), expected, "unexpected check digit for {value}");
});
}
#[test]
fn test_mod_11_2_check_digit() {
MOD_11_2_CHECK_DIGIT_CASES.into_iter().for_each(|(value, expected)| {
assert_eq!(mod_11_2_check_digit(value).as_deref(), expected, "unexpected check digit for {value}");
});
}
#[test]
fn test_mod_97_10_check_digit() {
MOD_97_10_CHECK_DIGIT_CASES.into_iter().for_each(|(value, expected)| {
assert_eq!(mod_97_10_check_digit(value).as_deref(), expected, "unexpected check digit for {value}");
});
}
#[test]
fn test_noid_check_digit() {
NOID_CHECK_DIGIT_CASES.into_iter().for_each(|(value, expected)| {
assert_eq!(noid_check_digit(value).as_deref(), expected, "unexpected check digit for {value}");
});
}
#[test]
fn test_normalize_discovery_identifiers() {
assert_eq!(Identifier::new("https://doi.org/10.1234/ABC").normalized().unwrap().value, "10.1234/ABC");
assert_eq!(Identifier::new("ISBN 978-0-306-40627-0").normalized().unwrap().kind, PID::ISBN);
assert_eq!(Identifier::new("ark:/12345/abc").normalized().unwrap().kind, PID::ARK);
assert_eq!(Identifier::new("RAID:10.12345/xyz").normalized().unwrap().kind, PID::RAID);
assert_eq!(Identifier::new("hdl:10013/epic.10033").normalized().unwrap().kind, PID::Handle);
assert_eq!(Identifier::new("10013/epic.10033").normalized().unwrap().kind, PID::Handle);
assert_eq!(Identifier::new("US-123456-A1").normalized().unwrap().kind, PID::Patent);
assert_eq!(
Identifier::new("swh:1:cnt:ce013625030ba8dba906f756967f9e9ca394464a")
.normalized()
.unwrap()
.kind,
PID::SWHID
);
}
#[test]
fn test_normalize_discovery_url_preserves_case_sensitive_components() {
let normalized = Identifier::new("https://Example.org/Data/Artifact?Key=Value").normalized().unwrap();
assert_eq!(normalized.kind, PID::URL);
assert_eq!(normalized.value, "https://Example.org/Data/Artifact?Key=Value");
}
#[test]
fn test_pid_display_and_serialization_use_lowercase_wire_names() {
assert_eq!(PID::Arxiv.to_string(), "arxiv");
assert_eq!(serde_json::to_string(&PID::DOI).unwrap(), r#""doi""#);
assert_eq!(serde_json::from_str::<PID>(r#""doi""#).unwrap(), PID::DOI);
assert_eq!(serde_json::from_str::<PID>(r#""DOI""#).unwrap(), PID::DOI);
}
#[test]
fn test_pid_from_str() {
assert_eq!(PID::from("doi"), PID::DOI);
assert_eq!(PID::from("ORCID"), PID::ORCID);
assert_eq!(PID::from(" pidinst "), PID::PIDINST);
assert_eq!(PID::from("SWHID"), PID::SWHID);
assert_eq!(PID::from("unsupported"), PID::Unknown);
}
#[test]
fn test_swhid_identity_ignores_qualifiers() {
let core = Identifier::new("swh:1:cnt:ce013625030ba8dba906f756967f9e9ca394464a")
.normalized()
.unwrap();
let qualified = Identifier::new("swh:1:cnt:ce013625030ba8dba906f756967f9e9ca394464a;origin=https://example.org/source;lines=1-2")
.normalized()
.unwrap();
assert_eq!(core.identity_key(), qualified.identity_key());
}