use super::{split_schema_identifier, AdmittedSchemaIdentifier};
#[derive(Debug, PartialEq, Eq)]
enum Admitted {
Rejected,
Valid,
OutOfRange(String, String),
}
fn admitted(identifier: &str) -> Admitted {
let Some(admitted) = AdmittedSchemaIdentifier::admit(identifier.to_owned()) else {
return Admitted::Rejected;
};
assert_eq!(
admitted.text(),
identifier,
"the admission keeps the source text"
);
match admitted.out_of_range() {
None => Admitted::Valid,
Some((name, component)) => Admitted::OutOfRange(name.to_owned(), component.to_owned()),
}
}
#[test]
fn classifier_reports_the_first_out_of_range_component_in_source_order() {
let cases = [
("AP242 { -1 40 }", "-1"),
("AP242 { 1 40 }", "40"),
("AP242 { 0 40 }", "40"),
("AP242 { iso 40 }", "40"),
("AP242 { 1 part(214) }", "part(214)"),
("AP242 { 3 1 }", "3"),
("AP242 { foo 40 }", "foo"),
("AP242 { iSo 40 }", "iSo"),
("AP242 { iso(standard) 40 }", "iso(standard)"),
];
for (identifier, component) in cases {
assert_eq!(
admitted(identifier),
Admitted::OutOfRange("AP242".to_owned(), component.to_owned()),
"{identifier}"
);
}
}
#[test]
fn classifier_admits_in_range_object_identifiers() {
let cases = [
"AP242 { 1 39 }",
"AP242 { 2 40 }",
"AP242 { iso 39 }",
"AP242 { itu-t 39 }",
"AP242 { ccitt 39 }",
"AP242 { joint-iso-itu-t 40 }",
"AP242 { joint-iso-ccitt 40 }",
"AP242 { iso standard 10303 part(214) version(1) }",
"AP242 { iso(1) 39 }",
"AP242",
];
for identifier in cases {
assert_eq!(admitted(identifier), Admitted::Valid, "{identifier}");
}
}
#[test]
fn admitted_identifiers_keep_numeric_components_with_named_roots() {
let admitted = AdmittedSchemaIdentifier::admit("AP242 { iso 0 10303 442 4 1 4 }".to_owned())
.expect("named ISO root is admitted");
assert_eq!(
admitted.numeric_object_identifier().as_deref(),
Some([1, 0, 10303, 442, 4, 1, 4].as_slice())
);
}
#[test]
fn classifier_rejects_identifiers_that_do_not_parse() {
let cases = [
"AP242 { 1 0 10303 442 -01 1 4 }",
"AP242 { 1 0 10303 442 invalid_ 1 4 }",
"AP242 { ISO 40 }",
"AP242 { Iso 40 }",
"AP242 { 01 0 }",
"AP242 { 1 }",
"AP242 { 1 40",
"9AP242",
"_AP242",
"",
];
for identifier in cases {
assert_eq!(admitted(identifier), Admitted::Rejected, "{identifier}");
}
}
#[test]
fn split_separates_the_schema_name_from_the_object_identifier() {
let cases = [
("AP242", Some(("AP242", None))),
(" AP242 ", Some(("AP242", None))),
("AP242 { 1 40 }", Some(("AP242", Some(" 1 40 ")))),
(" AP242{1 40} ", Some(("AP242", Some("1 40")))),
("AP242 {}", Some(("AP242", Some("")))),
("{ 1 40 }", Some(("", Some(" 1 40 ")))),
("A{B{1 2}", Some(("A", Some("B{1 2")))),
("AP242 { 1 40", None),
("A{1 2", None),
("AP242 { 1 40 } x", None),
];
for (identifier, expected) in cases {
assert_eq!(
split_schema_identifier(identifier),
expected,
"{identifier}"
);
}
}
#[test]
fn admitted_schema_identifiers_expose_only_proved_text_and_diagnostics() {
assert!(AdmittedSchemaIdentifier::admit("!".to_owned()).is_none());
let identifier =
AdmittedSchemaIdentifier::admit("AP242 { 1 40 }".to_owned()).expect("recoverable OID");
assert_eq!(identifier.text(), "AP242 { 1 40 }");
assert_eq!(identifier.out_of_range(), Some(("AP242", "40")));
let valid = AdmittedSchemaIdentifier::admit("AP242 { 1 39 }".to_owned()).expect("valid OID");
assert_eq!(valid.out_of_range(), None);
}