From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../rust/xml-rs/tests/documents/sample_1.xml | 34 ++ .../rust/xml-rs/tests/documents/sample_1_full.txt | 58 ++ .../rust/xml-rs/tests/documents/sample_1_short.txt | 37 ++ .../rust/xml-rs/tests/documents/sample_2.xml | 15 + .../rust/xml-rs/tests/documents/sample_2_full.txt | 41 ++ .../rust/xml-rs/tests/documents/sample_2_short.txt | 30 ++ .../rust/xml-rs/tests/documents/sample_3.xml | 13 + .../rust/xml-rs/tests/documents/sample_3_full.txt | 23 + .../rust/xml-rs/tests/documents/sample_3_short.txt | 14 + .../rust/xml-rs/tests/documents/sample_4.xml | 15 + .../rust/xml-rs/tests/documents/sample_4_full.txt | 23 + .../rust/xml-rs/tests/documents/sample_4_short.txt | 14 + .../rust/xml-rs/tests/documents/sample_5.xml | 7 + .../rust/xml-rs/tests/documents/sample_5_short.txt | 7 + .../rust/xml-rs/tests/documents/sample_6.xml | 4 + .../rust/xml-rs/tests/documents/sample_6_full.txt | 8 + third_party/rust/xml-rs/tests/event_reader.rs | 587 +++++++++++++++++++++ third_party/rust/xml-rs/tests/event_writer.rs | 269 ++++++++++ third_party/rust/xml-rs/tests/streaming.rs | 103 ++++ 19 files changed, 1302 insertions(+) create mode 100644 third_party/rust/xml-rs/tests/documents/sample_1.xml create mode 100644 third_party/rust/xml-rs/tests/documents/sample_1_full.txt create mode 100644 third_party/rust/xml-rs/tests/documents/sample_1_short.txt create mode 100644 third_party/rust/xml-rs/tests/documents/sample_2.xml create mode 100644 third_party/rust/xml-rs/tests/documents/sample_2_full.txt create mode 100644 third_party/rust/xml-rs/tests/documents/sample_2_short.txt create mode 100644 third_party/rust/xml-rs/tests/documents/sample_3.xml create mode 100644 third_party/rust/xml-rs/tests/documents/sample_3_full.txt create mode 100644 third_party/rust/xml-rs/tests/documents/sample_3_short.txt create mode 100644 third_party/rust/xml-rs/tests/documents/sample_4.xml create mode 100644 third_party/rust/xml-rs/tests/documents/sample_4_full.txt create mode 100644 third_party/rust/xml-rs/tests/documents/sample_4_short.txt create mode 100644 third_party/rust/xml-rs/tests/documents/sample_5.xml create mode 100644 third_party/rust/xml-rs/tests/documents/sample_5_short.txt create mode 100644 third_party/rust/xml-rs/tests/documents/sample_6.xml create mode 100644 third_party/rust/xml-rs/tests/documents/sample_6_full.txt create mode 100644 third_party/rust/xml-rs/tests/event_reader.rs create mode 100644 third_party/rust/xml-rs/tests/event_writer.rs create mode 100644 third_party/rust/xml-rs/tests/streaming.rs (limited to 'third_party/rust/xml-rs/tests') diff --git a/third_party/rust/xml-rs/tests/documents/sample_1.xml b/third_party/rust/xml-rs/tests/documents/sample_1.xml new file mode 100644 index 0000000000..4d1cbc0564 --- /dev/null +++ b/third_party/rust/xml-rs/tests/documents/sample_1.xml @@ -0,0 +1,34 @@ + + + + + + + + + + Some <java> class + + + Another "java" class + + + Weird 'XML' config + + + + + + + + + + JavaScript & program + + + Cascading style sheet: © - ҉ + + + + + diff --git a/third_party/rust/xml-rs/tests/documents/sample_1_full.txt b/third_party/rust/xml-rs/tests/documents/sample_1_full.txt new file mode 100644 index 0000000000..a8d64d01b3 --- /dev/null +++ b/third_party/rust/xml-rs/tests/documents/sample_1_full.txt @@ -0,0 +1,58 @@ +StartDocument(1.0, utf-8) +StartElement(project [name="project-name"]) +Whitespace("\n ") +StartElement(libraries) +Whitespace("\n ") +StartElement(library [groupId="org.example", artifactId="", version="0.1"]) +EndElement(library) +Whitespace("\n ") +StartElement(library [groupId="com.example", artifactId="\"cool-lib&", version="999"]) +EndElement(library) +Whitespace("\n ") +EndElement(libraries) +Whitespace("\n ") +StartElement(module [name="module-1"]) +Whitespace("\n ") +StartElement(files) +Whitespace("\n ") +StartElement(file [name="somefile.java", type="java"]) +Characters("\n Some class\n ") +EndElement(file) +Whitespace("\n ") +StartElement(file [name="another_file.java", type="java"]) +Characters("\n Another \"java\" class\n ") +EndElement(file) +Whitespace("\n ") +StartElement(file [name="config.xml", type="xml"]) +Characters("\n Weird \'XML\' config\n ") +EndElement(file) +Whitespace("\n ") +EndElement(files) +Whitespace("\n ") +StartElement(libraries) +Whitespace("\n ") +StartElement(library [groupId="junit", artifactId="junit", version="1.9.5"]) +EndElement(library) +Whitespace("\n ") +EndElement(libraries) +Whitespace("\n ") +EndElement(module) +Whitespace("\n ") +StartElement(module [name="module-2"]) +Whitespace("\n ") +StartElement(files) +Whitespace("\n ") +StartElement(file [name="program.js", type="javascript"]) +Characters("\n JavaScript & program\n ") +EndElement(file) +Whitespace("\n ") +StartElement(file [name="style.css", type="css"]) +Characters("\n Cascading style sheet: © - ҉\n ") +EndElement(file) +Whitespace("\n ") +EndElement(files) +Whitespace("\n ") +EndElement(module) +Whitespace("\n") +EndElement(project) +EndDocument diff --git a/third_party/rust/xml-rs/tests/documents/sample_1_short.txt b/third_party/rust/xml-rs/tests/documents/sample_1_short.txt new file mode 100644 index 0000000000..4dbe285b95 --- /dev/null +++ b/third_party/rust/xml-rs/tests/documents/sample_1_short.txt @@ -0,0 +1,37 @@ +StartDocument(1.0, utf-8) +StartElement(project [name="project-name"]) +StartElement(libraries) +StartElement(library [groupId="org.example", artifactId="", version="0.1"]) +EndElement(library) +StartElement(library [groupId="com.example", artifactId="\"cool-lib&", version="999"]) +EndElement(library) +EndElement(libraries) +StartElement(module [name="module-1"]) +StartElement(files) +StartElement(file [name="somefile.java", type="java"]) +Characters("Some class") +EndElement(file) +StartElement(file [name="another_file.java", type="java"]) +Characters("Another \"java\" class") +EndElement(file) +StartElement(file [name="config.xml", type="xml"]) +Characters("Weird \'XML\' config") +EndElement(file) +EndElement(files) +StartElement(libraries) +StartElement(library [groupId="junit", artifactId="junit", version="1.9.5"]) +EndElement(library) +EndElement(libraries) +EndElement(module) +StartElement(module [name="module-2"]) +StartElement(files) +StartElement(file [name="program.js", type="javascript"]) +Characters("JavaScript & program") +EndElement(file) +StartElement(file [name="style.css", type="css"]) +Characters("Cascading style sheet: © - ҉") +EndElement(file) +EndElement(files) +EndElement(module) +EndElement(project) +EndDocument diff --git a/third_party/rust/xml-rs/tests/documents/sample_2.xml b/third_party/rust/xml-rs/tests/documents/sample_2.xml new file mode 100644 index 0000000000..f9543acab3 --- /dev/null +++ b/third_party/rust/xml-rs/tests/documents/sample_2.xml @@ -0,0 +1,15 @@ + + + + Name + Another name + 0.3 + 0.2 + 0.1 + 0.01 + header 1 value + + Some bigger value + + + diff --git a/third_party/rust/xml-rs/tests/documents/sample_2_full.txt b/third_party/rust/xml-rs/tests/documents/sample_2_full.txt new file mode 100644 index 0000000000..75075cd661 --- /dev/null +++ b/third_party/rust/xml-rs/tests/documents/sample_2_full.txt @@ -0,0 +1,41 @@ +StartDocument(1.0, utf-8) +StartElement({urn:example:namespace}p:data) +Whitespace("\n ") +StartElement({urn:example:namespace}p:datum [id="34"]) +Whitespace("\n ") +StartElement({urn:example:namespace}p:name) +Characters("Name") +EndElement({urn:example:namespace}p:name) +Whitespace("\n ") +StartElement({urn:example:double}d:name) +Characters("Another name") +EndElement({urn:example:double}d:name) +Whitespace("\n ") +StartElement({urn:example:double}d:arg) +Characters("0.3") +EndElement({urn:example:double}d:arg) +Whitespace("\n ") +StartElement({urn:example:double}d:arg) +Characters("0.2") +EndElement({urn:example:double}d:arg) +Whitespace("\n ") +StartElement({urn:example:namespace}p:arg) +Characters("0.1") +EndElement({urn:example:namespace}p:arg) +Whitespace("\n ") +StartElement({urn:example:namespace}p:arg) +Characters("0.01") +EndElement({urn:example:namespace}p:arg) +Whitespace("\n ") +StartElement({urn:example:header}h:header [name="Header-1"]) +Characters("header 1 value") +EndElement({urn:example:header}h:header) +Whitespace("\n ") +StartElement({urn:example:header}h:header [name="Header-2"]) +Characters("\n Some bigger value\n ") +EndElement({urn:example:header}h:header) +Whitespace("\n ") +EndElement({urn:example:namespace}p:datum) +Whitespace("\n") +EndElement({urn:example:namespace}p:data) +EndDocument diff --git a/third_party/rust/xml-rs/tests/documents/sample_2_short.txt b/third_party/rust/xml-rs/tests/documents/sample_2_short.txt new file mode 100644 index 0000000000..23680255a4 --- /dev/null +++ b/third_party/rust/xml-rs/tests/documents/sample_2_short.txt @@ -0,0 +1,30 @@ +StartDocument(1.0, utf-8) +StartElement({urn:example:namespace}p:data) +StartElement({urn:example:namespace}p:datum [id="34"]) +StartElement({urn:example:namespace}p:name) +Characters("Name") +EndElement({urn:example:namespace}p:name) +StartElement({urn:example:double}d:name) +Characters("Another name") +EndElement({urn:example:double}d:name) +StartElement({urn:example:double}d:arg) +Characters("0.3") +EndElement({urn:example:double}d:arg) +StartElement({urn:example:double}d:arg) +Characters("0.2") +EndElement({urn:example:double}d:arg) +StartElement({urn:example:namespace}p:arg) +Characters("0.1") +EndElement({urn:example:namespace}p:arg) +StartElement({urn:example:namespace}p:arg) +Characters("0.01") +EndElement({urn:example:namespace}p:arg) +StartElement({urn:example:header}h:header [name="Header-1"]) +Characters("header 1 value") +EndElement({urn:example:header}h:header) +StartElement({urn:example:header}h:header [name="Header-2"]) +Characters("Some bigger value") +EndElement({urn:example:header}h:header) +EndElement({urn:example:namespace}p:datum) +EndElement({urn:example:namespace}p:data) +EndDocument diff --git a/third_party/rust/xml-rs/tests/documents/sample_3.xml b/third_party/rust/xml-rs/tests/documents/sample_3.xml new file mode 100644 index 0000000000..657e37d1a5 --- /dev/null +++ b/third_party/rust/xml-rs/tests/documents/sample_3.xml @@ -0,0 +1,13 @@ + + + + test + kkss" = ddd' > + ddddd!e3--> + test + kkss" = ddd' > + ddddd!e3-->"#, + br#" + |1:14 Unexpected token '--' before ' ' + "#, + ParserConfig::new(), + false + ); + + test( + br#""#, + br#" + |1:14 Unexpected token '--' before '-' + "#, + ParserConfig::new(), + false + ); +} + +#[test] +fn tabs_1() { + test( + b"\t\t", + br#" + |1:2 StartDocument(1.0, UTF-8) + |1:2 StartElement(a) + |1:6 StartElement(b) + |1:6 EndElement(b) + |1:10 EndElement(a) + |1:14 EndDocument + "#, + ParserConfig::new() + .trim_whitespace(true), + true + ); +} + +#[test] +fn issue_32_unescaped_cdata_end() { + test( + br#"]]>"#, + br#" + |StartDocument(1.0, UTF-8) + |StartElement(hello) + |Characters("]]>") + |EndElement(hello) + |EndDocument + "#, + ParserConfig::new(), + false + ); +} + +#[test] +fn issue_unescaped_processing_instruction_end() { + test( + br#"?>"#, + br#" + |StartDocument(1.0, UTF-8) + |StartElement(hello) + |Characters("?>") + |EndElement(hello) + |EndDocument + "#, + ParserConfig::new(), + false + ); +} + +#[test] +fn issue_unescaped_empty_tag_end() { + test( + br#"/>"#, + br#" + |StartDocument(1.0, UTF-8) + |StartElement(hello) + |Characters("/>") + |EndElement(hello) + |EndDocument + "#, + ParserConfig::new(), + false + ); +} + +#[test] +fn issue_83_duplicate_attributes() { + test( + br#""#, + br#" + |StartDocument(1.0, UTF-8) + |StartElement(hello) + |1:30 Attribute 'a' is redefined + "#, + ParserConfig::new(), + false + ); +} + +#[test] +fn issue_93_large_characters_in_entity_references() { + test( + r#"&𤶼;"#.as_bytes(), + r#" + |StartDocument(1.0, UTF-8) + |StartElement(hello) + |1:10 Unexpected entity: 𤶼 + "#.as_bytes(), // FIXME: it shouldn't be 10, looks like indices are off slightly + ParserConfig::new(), + false + ) +} + +#[test] +fn issue_98_cdata_ending_with_right_bracket() { + test( + br#""#, + br#" + |StartDocument(1.0, UTF-8) + |StartElement(hello) + |CData("Foo [Bar]") + |EndElement(hello) + |EndDocument + "#, + ParserConfig::new(), + false + ) +} + +#[test] +fn issue_105_unexpected_double_dash() { + test( + br#"-- "#, + br#" + |StartDocument(1.0, UTF-8) + |StartElement(hello) + |Characters("-- ") + |EndElement(hello) + |EndDocument + "#, + ParserConfig::new(), + false + ); + + test( + br#"--"#, + br#" + |StartDocument(1.0, UTF-8) + |StartElement(hello) + |Characters("--") + |EndElement(hello) + |EndDocument + "#, + ParserConfig::new(), + false + ); + + test( + br#"-->"#, + br#" + |StartDocument(1.0, UTF-8) + |StartElement(hello) + |Characters("-->") + |EndElement(hello) + |EndDocument + "#, + ParserConfig::new(), + false + ); + + test( + br#""#, + br#" + |StartDocument(1.0, UTF-8) + |StartElement(hello) + |CData("--") + |EndElement(hello) + |EndDocument + "#, + ParserConfig::new(), + false + ); +} + +#[test] +fn issue_attribues_have_no_default_namespace () { + test( + br#""#, + br#" + |StartDocument(1.0, UTF-8) + |StartElement({urn:foo}hello [x="y"]) + |EndElement({urn:foo}hello) + |EndDocument + "#, + ParserConfig::new(), + false + ); +} + +#[test] +fn issue_replacement_character_entity_reference() { + test( + br#"��"#, + br#" + |StartDocument(1.0, UTF-8) + |StartElement(doc) + |1:13 Invalid decimal character number in an entity: #55357 + "#, + ParserConfig::new(), + false, + ); + + test( + br#"��"#, + br#" + |StartDocument(1.0, UTF-8) + |StartElement(doc) + |1:13 Invalid hexadecimal character number in an entity: #xd83d + "#, + ParserConfig::new(), + false, + ); + + test( + br#"��"#, + format!( + r#" + |StartDocument(1.0, UTF-8) + |StartElement(doc) + |Characters("{replacement_character}{replacement_character}") + |EndElement(doc) + |EndDocument + "#, + replacement_character = "\u{fffd}" + ) + .as_bytes(), + ParserConfig::new() + .replace_unknown_entity_references(true), + false, + ); + + test( + br#"��"#, + format!( + r#" + |StartDocument(1.0, UTF-8) + |StartElement(doc) + |Characters("{replacement_character}{replacement_character}") + |EndElement(doc) + |EndDocument + "#, + replacement_character = "\u{fffd}" + ) + .as_bytes(), + ParserConfig::new() + .replace_unknown_entity_references(true), + false, + ); +} + +lazy_static! { + // If PRINT_SPEC env variable is set, print the lines + // to stderr instead of comparing with the output + // it can be used like this: + // PRINT_SPEC=1 cargo test --test event_reader sample_1_full 2> sample_1_full.txt + static ref PRINT: bool = { + for (key, value) in env::vars() { + if key == "PRINT_SPEC" && value == "1" { + return true; + } + } + false + }; +} + +// clones a lot but that's fine +fn trim_until_bar(s: String) -> String { + match s.trim() { + ts if ts.starts_with('|') => return ts[1..].to_owned(), + _ => {} + } + s +} + +fn test(input: &[u8], output: &[u8], config: ParserConfig, test_position: bool) { + let mut reader = config.create_reader(input); + let mut spec_lines = BufReader::new(output).lines() + .map(|line| line.unwrap()) + .enumerate() + .map(|(i, line)| (i, trim_until_bar(line))) + .filter(|&(_, ref line)| !line.trim().is_empty()); + + loop { + let e = reader.next(); + let line = + if test_position { + format!("{} {}", reader.position(), Event(&e)) + } else { + format!("{}", Event(&e)) + }; + + if *PRINT { + writeln!(&mut stderr(), "{}", line).unwrap(); + } else { + if let Some((n, spec)) = spec_lines.next() { + if line != spec { + const SPLITTER: &'static str = "-------------------"; + panic!("\n{}\nUnexpected event at line {}:\nExpected: {}\nFound: {}\n{}\n", + SPLITTER, n + 1, spec, line, std::str::from_utf8(output).unwrap()); + } + } else { + panic!("Unexpected event: {}", line); + } + } + + match e { + Ok(XmlEvent::EndDocument) | Err(_) => break, + _ => {}, + } + } +} + +// Here we define our own string representation of events so we don't depend +// on the specifics of Display implementation for XmlEvent and OwnedName. + +struct Name<'a>(&'a OwnedName); + +impl <'a> fmt::Display for Name<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if let Some(ref namespace) = self.0.namespace { + try! { write!(f, "{{{}}}", namespace) } + } + + if let Some(ref prefix) = self.0.prefix { + try! { write!(f, "{}:", prefix) } + } + + write!(f, "{}", self.0.local_name) + } +} + +struct Event<'a>(&'a Result); + +impl<'a> fmt::Display for Event<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let empty = String::new(); + match *self.0 { + Ok(ref e) => match *e { + XmlEvent::StartDocument { ref version, ref encoding, .. } => + write!(f, "StartDocument({}, {})", version, encoding), + XmlEvent::EndDocument => + write!(f, "EndDocument"), + XmlEvent::ProcessingInstruction { ref name, ref data } => + write!(f, "ProcessingInstruction({}={:?})", name, + data.as_ref().unwrap_or(&empty)), + XmlEvent::StartElement { ref name, ref attributes, .. } => { + if attributes.is_empty() { + write!(f, "StartElement({})", Name(name)) + } + else { + let attrs: Vec<_> = attributes.iter() + .map(|a| format!("{}={:?}", Name(&a.name), a.value)) .collect(); + write!(f, "StartElement({} [{}])", Name(name), attrs.join(", ")) + } + }, + XmlEvent::EndElement { ref name } => + write!(f, "EndElement({})", Name(name)), + XmlEvent::Comment(ref data) => + write!(f, r#"Comment("{}")"#, data.escape_debug()), + XmlEvent::CData(ref data) => + write!(f, r#"CData("{}")"#, data.escape_debug()), + XmlEvent::Characters(ref data) => + write!(f, r#"Characters("{}")"#, data.escape_debug()), + XmlEvent::Whitespace(ref data) => + write!(f, r#"Whitespace("{}")"#, data.escape_debug()), + }, + Err(ref e) => e.fmt(f), + } + } +} diff --git a/third_party/rust/xml-rs/tests/event_writer.rs b/third_party/rust/xml-rs/tests/event_writer.rs new file mode 100644 index 0000000000..dd64a4392e --- /dev/null +++ b/third_party/rust/xml-rs/tests/event_writer.rs @@ -0,0 +1,269 @@ +#![forbid(unsafe_code)] + +extern crate xml; + +use std::io::{BufReader, SeekFrom}; +use std::io::prelude::*; +use std::fs::File; +use std::str; + +use xml::reader::EventReader; +use xml::writer::EmitterConfig; + +macro_rules! unwrap_all { + ($($e:expr);+) => {{ + $($e.unwrap();)+ + }} +} + +#[test] +fn reading_writing_equal_with_namespaces() { + let mut f = File::open("tests/documents/sample_2.xml").unwrap(); + let mut b = Vec::new(); + + { + let r = EventReader::new(BufReader::new(&mut f)); + let mut w = EmitterConfig::default().perform_indent(true).create_writer(&mut b); + + for e in r { + match e { + Ok(e) => if let Some(e) = e.as_writer_event() { + match w.write(e) { + Ok(_) => {}, + Err(e) => panic!("Writer error: {:?}", e) + } + }, + Err(e) => panic!("Error: {}", e) + } + } + } + + f.seek(SeekFrom::Start(0)).unwrap(); + let mut fs = String::new(); + f.read_to_string(&mut fs).unwrap(); + + let bs = String::from_utf8(b).unwrap(); + + assert_eq!(fs.trim(), bs.trim()); +} + +#[test] +fn writing_simple() { + use xml::writer::XmlEvent; + + let mut b = Vec::new(); + + { + let mut w = EmitterConfig::new().write_document_declaration(false).create_writer(&mut b); + + w.write(XmlEvent::start_element("h:hello").ns("h", "urn:hello-world")).unwrap(); + w.write("hello world").unwrap(); + w.write(XmlEvent::end_element()).unwrap(); + } + + assert_eq!( + str::from_utf8(&b).unwrap(), + r#"hello world"# + ); +} + +#[test] +fn writing_empty_elements_with_normalizing() { + use xml::writer::XmlEvent; + + let mut b = Vec::new(); + + { + let mut w = EmitterConfig::new().write_document_declaration(false).create_writer(&mut b); + + unwrap_all! { + w.write(XmlEvent::start_element("hello")); + w.write(XmlEvent::start_element("world")); + w.write(XmlEvent::end_element()); + w.write(XmlEvent::end_element()) + } + } + + assert_eq!(str::from_utf8(&b).unwrap(), r#""#); +} + +#[test] +fn writing_empty_elements_without_normalizing() { + use xml::writer::XmlEvent; + + let mut b = Vec::new(); + + { + let mut w = EmitterConfig::new() + .write_document_declaration(false) + .normalize_empty_elements(false) + .create_writer(&mut b); + + unwrap_all! { + w.write(XmlEvent::start_element("hello")); + w.write(XmlEvent::start_element("world")); + w.write(XmlEvent::end_element()); + w.write(XmlEvent::end_element()) + } + } + + assert_eq!(str::from_utf8(&b).unwrap(), r#""#); +} + +#[test] +fn writing_empty_elements_without_pad_self_closing() { + use xml::writer::XmlEvent; + + let mut b = Vec::new(); + + { + let mut w = EmitterConfig::new() + .write_document_declaration(false) + .pad_self_closing(false) + .create_writer(&mut b); + + unwrap_all! { + w.write(XmlEvent::start_element("hello")); + w.write(XmlEvent::start_element("world")); + w.write(XmlEvent::end_element()); + w.write(XmlEvent::end_element()) + } + } + + assert_eq!(str::from_utf8(&b).unwrap(), r#""#); +} +#[test] +fn writing_empty_elements_pad_self_closing_explicit() { + use xml::writer::XmlEvent; + + let mut b = Vec::new(); + + { + let mut w = EmitterConfig::new() + .write_document_declaration(false) + .pad_self_closing(true) + .create_writer(&mut b); + + unwrap_all! { + w.write(XmlEvent::start_element("hello")); + w.write(XmlEvent::start_element("world")); + w.write(XmlEvent::end_element()); + w.write(XmlEvent::end_element()) + } + } + + assert_eq!(str::from_utf8(&b).unwrap(), r#""#); +} + +#[test] +fn writing_comments_with_indentation() { + use xml::writer::XmlEvent; + + let mut b = Vec::new(); + + { + let mut w = EmitterConfig::new() + .write_document_declaration(false) + .perform_indent(true) + .create_writer(&mut b); + + unwrap_all! { + w.write(XmlEvent::start_element("hello")); + w.write(XmlEvent::start_element("world")); + w.write(XmlEvent::comment(" this is a manually padded comment\t")); + w.write(XmlEvent::comment("this is an unpadded comment")); + w.write(XmlEvent::end_element()); + w.write(XmlEvent::end_element()) + } + } + + assert_eq!( + str::from_utf8(&b).unwrap(), + " + + + + +"); +} + +#[test] +fn issue_112_overriding_namepace_prefix() { + use xml::writer::XmlEvent; + + let mut b = Vec::new(); + + { + let mut w = EmitterConfig::new() + .write_document_declaration(false) + .create_writer(&mut b); + + unwrap_all! { + w.write(XmlEvent::start_element("iq").ns("", "jabber:client").ns("a", "urn:A")); + w.write(XmlEvent::start_element("bind").ns("", "urn:ietf:params:xml:ns:xmpp-bind")); + w.write(XmlEvent::end_element()); + w.write(XmlEvent::start_element("whatever").ns("a", "urn:X")); + w.write(XmlEvent::end_element()); + w.write(XmlEvent::end_element()) + } + } + + assert_eq!( + str::from_utf8(&b).unwrap(), + r#""# + ) +} + +#[test] +fn attribute_escaping() { + use xml::writer::XmlEvent; + + let mut b = Vec::new(); + + { + let mut w = EmitterConfig::new() + .write_document_declaration(false) + .perform_indent(true) + .create_writer(&mut b); + + unwrap_all! { + w.write( + XmlEvent::start_element("hello") + .attr("testLt", "<") + .attr("testGt", ">") + ); + w.write(XmlEvent::end_element()); + w.write( + XmlEvent::start_element("hello") + .attr("testQuot", "\"") + .attr("testApos", "\'") + ); + w.write(XmlEvent::end_element()); + w.write( + XmlEvent::start_element("hello") + .attr("testAmp", "&") + ); + w.write(XmlEvent::end_element()); + w.write( + XmlEvent::start_element("hello") + .attr("testNl", "\n") + .attr("testCr", "\r") + ); + w.write(XmlEvent::end_element()); + w.write( + XmlEvent::start_element("hello") + .attr("testNl", "\\n") + .attr("testCr", "\\r") + ); + w.write(XmlEvent::end_element()) + } + } + assert_eq!( + str::from_utf8(&b).unwrap(), + " + + + +" + ); +} \ No newline at end of file diff --git a/third_party/rust/xml-rs/tests/streaming.rs b/third_party/rust/xml-rs/tests/streaming.rs new file mode 100644 index 0000000000..a577a00e6a --- /dev/null +++ b/third_party/rust/xml-rs/tests/streaming.rs @@ -0,0 +1,103 @@ +#![forbid(unsafe_code)] + +extern crate xml; + +use std::io::{Cursor, Write}; + +use xml::EventReader; +use xml::reader::ParserConfig; +use xml::reader::XmlEvent; + +macro_rules! assert_match { + ($actual:expr, $expected:pat) => { + match $actual { + $expected => {}, + _ => panic!("assertion failed: `(left matches right)` \ + (left: `{:?}`, right: `{}`", $actual, stringify!($expected)) + } + }; + ($actual:expr, $expected:pat if $guard:expr) => { + match $actual { + $expected if $guard => {}, + _ => panic!("assertion failed: `(left matches right)` \ + (left: `{:?}`, right: `{} if {}`", + $actual, stringify!($expected), stringify!($guard)) + } + } +} + +fn write_and_reset_position(c: &mut Cursor, data: &[u8]) where Cursor: Write { + let p = c.position(); + c.write_all(data).unwrap(); + c.set_position(p); +} + +#[test] +fn reading_streamed_content() { + let buf = Cursor::new(b"".to_vec()); + let reader = EventReader::new(buf); + + let mut it = reader.into_iter(); + + assert_match!(it.next(), Some(Ok(XmlEvent::StartDocument { .. }))); + assert_match!(it.next(), Some(Ok(XmlEvent::StartElement { ref name, .. })) if name.local_name == "root"); + + write_and_reset_position(it.source_mut(), b"content"); + assert_match!(it.next(), Some(Ok(XmlEvent::StartElement { ref name, .. })) if name.local_name == "child-1"); + assert_match!(it.next(), Some(Ok(XmlEvent::Characters(ref c))) if c == "content"); + assert_match!(it.next(), Some(Ok(XmlEvent::EndElement { ref name })) if name.local_name == "child-1"); + + write_and_reset_position(it.source_mut(), b""); + assert_match!(it.next(), Some(Ok(XmlEvent::StartElement { ref name, .. })) if name.local_name == "child-2"); + assert_match!(it.next(), Some(Ok(XmlEvent::EndElement { ref name })) if name.local_name == "child-2"); + + write_and_reset_position(it.source_mut(), b""); + assert_match!(it.next(), Some(Ok(XmlEvent::StartElement { ref name, .. })) if name.local_name == "child-3"); + assert_match!(it.next(), Some(Ok(XmlEvent::EndElement { ref name })) if name.local_name == "child-3"); + // doesn't seem to work because of how tags parsing is done +// write_and_reset_position(it.source_mut(), b"some text"); + // assert_match!(it.next(), Some(Ok(XmlEvent::Characters(ref c))) if c == "some text"); + + write_and_reset_position(it.source_mut(), b""); + assert_match!(it.next(), Some(Ok(XmlEvent::EndElement { ref name })) if name.local_name == "root"); + assert_match!(it.next(), Some(Ok(XmlEvent::EndDocument))); + assert_match!(it.next(), None); +} + +#[test] +fn reading_streamed_content2() { + let buf = Cursor::new(b"".to_vec()); + let mut config = ParserConfig::new(); + config.ignore_end_of_stream = true; + let readerb = EventReader::new_with_config(buf, config); + + let mut reader = readerb.into_iter(); + + assert_match!(reader.next(), Some(Ok(XmlEvent::StartDocument { .. }))); + assert_match!(reader.next(), Some(Ok(XmlEvent::StartElement { ref name, .. })) if name.local_name == "root"); + + write_and_reset_position(reader.source_mut(), b"content"); + assert_match!(reader.next(), Some(Ok(XmlEvent::StartElement { ref name, .. })) if name.local_name == "child-1"); + assert_match!(reader.next(), Some(Ok(XmlEvent::Characters(ref c))) if c == "content"); + assert_match!(reader.next(), Some(Ok(XmlEvent::EndElement { ref name })) if name.local_name == "child-1"); + + write_and_reset_position(reader.source_mut(), b"content"); + + assert_match!(reader.next(), Some(Ok(XmlEvent::StartElement { ref name, .. })) if name.local_name == "child-2"); + assert_match!(reader.next(), Some(Ok(XmlEvent::Characters(ref c))) if c == "content"); + assert_match!(reader.next(), Some(Ok(XmlEvent::EndElement { ref name })) if name.local_name == "child-2"); + assert_match!(reader.next(), Some(Err(_))); + write_and_reset_position(reader.source_mut(), b""); + assert_match!(reader.next(), Some(Ok(XmlEvent::StartElement { ref name, .. })) if name.local_name == "child-3"); + write_and_reset_position(reader.source_mut(), b" { + panic!("At this point, parser must not detect something."); + }, + Some(Err(_)) => {} + }; + write_and_reset_position(reader.source_mut(), b" />"); + assert_match!(reader.next(), Some(Ok(XmlEvent::StartElement { ref name, .. })) if name.local_name == "child-4"); +} + -- cgit v1.2.3