tests.rs

  1// Copyright (c) 2020 lumi <lumi@pew.im>
  2// Copyright (c) 2020 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
  3// Copyright (c) 2020 Bastien Orivel <eijebong+minidom@bananium.fr>
  4// Copyright (c) 2020 Astro <astro@spaceboyz.net>
  5// Copyright (c) 2020 Maxime “pep” Buquet <pep@bouah.net>
  6// Copyright (c) 2020 Yue Liu <amznyue@amazon.com>
  7// Copyright (c) 2020 Matt Bilker <me@mbilker.us>
  8//
  9// This Source Code Form is subject to the terms of the Mozilla Public
 10// License, v. 2.0. If a copy of the MPL was not distributed with this
 11// file, You can obtain one at http://mozilla.org/MPL/2.0/.
 12
 13use crate::element::Element;
 14
 15use quick_xml::Reader;
 16
 17const TEST_STRING: &'static str = r#"<root xmlns="root_ns" a="b" xml:lang="en">meow<child c="d"/><child xmlns="child_ns" d="e" xml:lang="fr"/>nya</root>"#;
 18
 19fn build_test_tree() -> Element {
 20    let mut root = Element::builder("root")
 21        .ns("root_ns")
 22        .attr("xml:lang", "en")
 23        .attr("a", "b")
 24        .build();
 25    root.append_text_node("meow");
 26    let child = Element::builder("child").attr("c", "d").build();
 27    root.append_child(child);
 28    let other_child = Element::builder("child")
 29        .ns("child_ns")
 30        .attr("d", "e")
 31        .attr("xml:lang", "fr")
 32        .build();
 33    root.append_child(other_child);
 34    root.append_text_node("nya");
 35    root
 36}
 37
 38#[cfg(feature = "comments")]
 39const COMMENT_TEST_STRING: &'static str = r#"<root><!--This is a child.--><child attr="val"><!--This is a grandchild.--><grandchild/></child></root>"#;
 40
 41#[cfg(feature = "comments")]
 42fn build_comment_test_tree() -> Element {
 43    let mut root = Element::builder("root").build();
 44    root.append_comment_node("This is a child.");
 45    let mut child = Element::builder("child").attr("attr", "val").build();
 46    child.append_comment_node("This is a grandchild.");
 47    let grand_child = Element::builder("grandchild").build();
 48    child.append_child(grand_child);
 49    root.append_child(child);
 50    root
 51}
 52
 53#[test]
 54fn reader_works() {
 55    let mut reader = Reader::from_str(TEST_STRING);
 56    assert_eq!(
 57        Element::from_reader(&mut reader).unwrap(),
 58        build_test_tree()
 59    );
 60}
 61
 62#[test]
 63fn writer_works() {
 64    let root = build_test_tree();
 65    let mut writer = Vec::new();
 66    {
 67        root.write_to(&mut writer).unwrap();
 68    }
 69    assert_eq!(String::from_utf8(writer).unwrap(), TEST_STRING);
 70}
 71
 72#[test]
 73fn writer_with_decl_works() {
 74    let root = build_test_tree();
 75    let mut writer = Vec::new();
 76    {
 77        root.write_to_decl(&mut writer).unwrap();
 78    }
 79    let result = format!(r#"<?xml version="1.0" encoding="utf-8"?>{}"#, TEST_STRING);
 80    assert_eq!(String::from_utf8(writer).unwrap(), result);
 81}
 82
 83#[test]
 84fn writer_escapes_attributes() {
 85    let root = Element::builder("root").attr("a", "\"Air\" quotes").build();
 86    let mut writer = Vec::new();
 87    {
 88        root.write_to(&mut writer).unwrap();
 89    }
 90    assert_eq!(
 91        String::from_utf8(writer).unwrap(),
 92        r#"<root a="&quot;Air&quot; quotes"/>"#
 93    );
 94}
 95
 96#[test]
 97fn writer_escapes_text() {
 98    let root = Element::builder("root").append("<3").build();
 99    let mut writer = Vec::new();
100    {
101        root.write_to(&mut writer).unwrap();
102    }
103    assert_eq!(String::from_utf8(writer).unwrap(), r#"<root>&lt;3</root>"#);
104}
105
106#[test]
107fn builder_works() {
108    let elem = Element::builder("a")
109        .ns("b")
110        .attr("c", "d")
111        .append(Element::builder("child"))
112        .append("e")
113        .build();
114    assert_eq!(elem.name(), "a");
115    assert_eq!(elem.ns(), Some("b".to_owned()));
116    assert_eq!(elem.attr("c"), Some("d"));
117    assert_eq!(elem.attr("x"), None);
118    assert_eq!(elem.text(), "e");
119    assert!(elem.has_child("child", "b"));
120    assert!(elem.is("a", "b"));
121}
122
123#[test]
124fn children_iter_works() {
125    let root = build_test_tree();
126    let mut iter = root.children();
127    assert!(iter.next().unwrap().is("child", "root_ns"));
128    assert!(iter.next().unwrap().is("child", "child_ns"));
129    assert_eq!(iter.next(), None);
130}
131
132#[test]
133fn get_child_works() {
134    let root = build_test_tree();
135    assert_eq!(root.get_child("child", "inexistent_ns"), None);
136    assert_eq!(root.get_child("not_a_child", "root_ns"), None);
137    assert!(root
138        .get_child("child", "root_ns")
139        .unwrap()
140        .is("child", "root_ns"));
141    assert!(root
142        .get_child("child", "child_ns")
143        .unwrap()
144        .is("child", "child_ns"));
145    assert_eq!(
146        root.get_child("child", "root_ns").unwrap().attr("c"),
147        Some("d")
148    );
149    assert_eq!(
150        root.get_child("child", "child_ns").unwrap().attr("d"),
151        Some("e")
152    );
153}
154
155#[test]
156fn namespace_propagation_works() {
157    let mut root = Element::builder("root").ns("root_ns").build();
158    let mut child = Element::bare("child");
159    let grandchild = Element::bare("grandchild");
160    child.append_child(grandchild);
161    root.append_child(child);
162
163    assert_eq!(root.get_child("child", "root_ns").unwrap().ns(), root.ns());
164    assert_eq!(
165        root.get_child("child", "root_ns")
166            .unwrap()
167            .get_child("grandchild", "root_ns")
168            .unwrap()
169            .ns(),
170        root.ns()
171    );
172}
173
174#[test]
175fn two_elements_with_same_arguments_different_order_are_equal() {
176    let elem1: Element = "<a b='a' c=''/>".parse().unwrap();
177    let elem2: Element = "<a c='' b='a'/>".parse().unwrap();
178    assert_eq!(elem1, elem2);
179
180    let elem1: Element = "<a b='a' c=''/>".parse().unwrap();
181    let elem2: Element = "<a c='d' b='a'/>".parse().unwrap();
182    assert_ne!(elem1, elem2);
183}
184
185#[test]
186fn namespace_attributes_works() {
187    let mut reader = Reader::from_str(TEST_STRING);
188    let root = Element::from_reader(&mut reader).unwrap();
189    assert_eq!("en", root.attr("xml:lang").unwrap());
190    assert_eq!(
191        "fr",
192        root.get_child("child", "child_ns")
193            .unwrap()
194            .attr("xml:lang")
195            .unwrap()
196    );
197}
198
199#[test]
200fn wrongly_closed_elements_error() {
201    let elem1 = "<a></b>".parse::<Element>();
202    assert!(elem1.is_err());
203    let elem1 = "<a></c></a>".parse::<Element>();
204    assert!(elem1.is_err());
205    let elem1 = "<a><c><d/></c></a>".parse::<Element>();
206    assert!(elem1.is_ok());
207}
208
209#[test]
210fn namespace_simple() {
211    let elem: Element = "<message xmlns='jabber:client'/>".parse().unwrap();
212    assert_eq!(elem.name(), "message");
213    assert_eq!(elem.ns(), Some("jabber:client".to_owned()));
214}
215
216#[test]
217fn namespace_prefixed() {
218    let elem: Element = "<stream:features xmlns:stream='http://etherx.jabber.org/streams'/>"
219        .parse()
220        .unwrap();
221    assert_eq!(elem.name(), "features");
222    assert_eq!(
223        elem.ns(),
224        Some("http://etherx.jabber.org/streams".to_owned())
225    );
226}
227
228#[test]
229fn namespace_inherited_simple() {
230    let elem: Element = "<stream xmlns='jabber:client'><message/></stream>"
231        .parse()
232        .unwrap();
233    assert_eq!(elem.name(), "stream");
234    assert_eq!(elem.ns(), Some("jabber:client".to_owned()));
235    let child = elem.children().next().unwrap();
236    assert_eq!(child.name(), "message");
237    assert_eq!(child.ns(), Some("jabber:client".to_owned()));
238}
239
240#[test]
241fn namespace_inherited_prefixed1() {
242    let elem: Element = "<stream:features xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client'><message/></stream:features>"
243        .parse().unwrap();
244    assert_eq!(elem.name(), "features");
245    assert_eq!(
246        elem.ns(),
247        Some("http://etherx.jabber.org/streams".to_owned())
248    );
249    let child = elem.children().next().unwrap();
250    assert_eq!(child.name(), "message");
251    assert_eq!(child.ns(), Some("jabber:client".to_owned()));
252}
253
254#[test]
255fn namespace_inherited_prefixed2() {
256    let elem: Element = "<stream xmlns='http://etherx.jabber.org/streams' xmlns:jabber='jabber:client'><jabber:message/></stream>"
257        .parse().unwrap();
258    assert_eq!(elem.name(), "stream");
259    assert_eq!(
260        elem.ns(),
261        Some("http://etherx.jabber.org/streams".to_owned())
262    );
263    let child = elem.children().next().unwrap();
264    assert_eq!(child.name(), "message");
265    assert_eq!(child.ns(), Some("jabber:client".to_owned()));
266}
267
268#[cfg(feature = "comments")]
269#[test]
270fn read_comments() {
271    let mut reader = Reader::from_str(COMMENT_TEST_STRING);
272    assert_eq!(
273        Element::from_reader(&mut reader).unwrap(),
274        build_comment_test_tree()
275    );
276}
277
278#[cfg(feature = "comments")]
279#[test]
280fn write_comments() {
281    let root = build_comment_test_tree();
282    let mut writer = Vec::new();
283    {
284        root.write_to(&mut writer).unwrap();
285    }
286    assert_eq!(String::from_utf8(writer).unwrap(), COMMENT_TEST_STRING);
287}
288
289#[test]
290fn xml_error() {
291    match "<a></b>".parse::<Element>() {
292        Err(crate::error::Error::XmlError(_)) => (),
293        err => panic!("No or wrong error: {:?}", err),
294    }
295
296    match "<a></".parse::<Element>() {
297        Err(crate::error::Error::XmlError(_)) => (),
298        err => panic!("No or wrong error: {:?}", err),
299    }
300}
301
302#[test]
303fn invalid_element_error() {
304    match "<a:b:c>".parse::<Element>() {
305        Err(crate::error::Error::InvalidElement) => (),
306        err => panic!("No or wrong error: {:?}", err),
307    }
308}