use oxml::parse;
#[test]
fn only_a_non_cdata_type_is_collapsed() {
let doc = r#"<!DOCTYPE r [
<!ELEMENT r EMPTY>
<!ATTLIST r keep CDATA #IMPLIED
trim NMTOKEN #IMPLIED>
]>
<r keep=" a b " trim=" a b "/>"#;
let d = parse(doc).expect("well-formed");
let root = d.root_element().expect("a root");
assert_eq!(
d.attribute(root, "keep"),
Some(" a b "),
"CDATA keeps every space"
);
assert_eq!(
d.attribute(root, "trim"),
Some("a b"),
"a tokenized value is stripped and collapsed"
);
}
#[test]
fn every_tokenized_type_is_collapsed() {
for ty in [
"ID", "IDREF", "IDREFS", "ENTITY", "ENTITIES", "NMTOKEN", "NMTOKENS",
"(a|b)",
] {
let doc = format!(
"<!DOCTYPE r [<!ELEMENT r EMPTY><!ATTLIST r v {ty} #IMPLIED>]>\
<r v=\" a \"/>"
);
let d = parse(&doc).unwrap_or_else(|e| panic!("{ty}: {e}"));
let root = d.root_element().expect("a root");
assert_eq!(d.attribute(root, "v"), Some("a"), "type {ty}");
}
}
#[test]
fn the_two_passes_compose() {
let doc = "<!DOCTYPE r [<!ELEMENT r EMPTY>\
<!ATTLIST r v NMTOKENS #IMPLIED>]>\
<r v=\"\ta\n\nb\t\"/>";
let d = parse(doc).expect("well-formed");
let root = d.root_element().expect("a root");
assert_eq!(d.attribute(root, "v"), Some("a b"));
}
#[test]
fn an_undeclared_attribute_keeps_its_spaces() {
let d = parse("<r v=\" a b \"/>").expect("well-formed");
let root = d.root_element().expect("a root");
assert_eq!(d.attribute(root, "v"), Some(" a b "));
}
#[test]
fn normalisation_can_make_two_prefixes_one_namespace() {
let doc = r#"<!DOCTYPE foo [
<!ELEMENT foo ANY>
<!ATTLIST foo xmlns:a CDATA #IMPLIED
xmlns:b NMTOKEN #IMPLIED>
<!ELEMENT bar ANY>
<!ATTLIST bar a:attr CDATA #IMPLIED
b:attr CDATA #IMPLIED>
]>
<foo xmlns:a="urn:xyzzy" xmlns:b=" urn:xyzzy ">
<bar a:attr="1" b:attr="2"/>
</foo>"#;
assert!(
parse(doc).is_err(),
"the two prefixes name one namespace, so `bar` declares the \
same attribute twice"
);
let cdata = doc.replace("xmlns:b NMTOKEN", "xmlns:b CDATA");
assert!(
parse(&cdata).is_ok(),
"as CDATA the spaces are kept and the URIs are different"
);
}