]> git.proxmox.com Git - rustc.git/blame - vendor/markup5ever_rcdom/tests/xml-tree-builder.rs
New upstream version 1.61.0+dfsg1
[rustc.git] / vendor / markup5ever_rcdom / tests / xml-tree-builder.rs
CommitLineData
83c7162d
XL
1// Copyright 2014-2017 The html5ever Project Developers. See the
2// COPYRIGHT file at the top-level directory of this distribution.
3//
4// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7// option. This file may not be copied, modified, or distributed
8// except according to those terms.
9
3dfed10e
XL
10use markup5ever::{namespace_url, ns};
11use markup5ever_rcdom::*;
12use rustc_test::{DynTestFn, DynTestName, TestDesc, TestDescAndFn};
dc9dc135 13use std::collections::{HashMap, HashSet};
83c7162d 14use std::ffi::OsStr;
dc9dc135 15use std::io::BufRead;
83c7162d
XL
16use std::iter::repeat;
17use std::mem::replace;
83c7162d 18use std::path::Path;
dc9dc135 19use std::{env, fs, io};
3dfed10e
XL
20use util::find_tests::foreach_xml5lib_test;
21use xml5ever::driver::parse_document;
22use xml5ever::tendril::TendrilSink;
83c7162d 23
3dfed10e
XL
24mod util {
25 pub mod find_tests;
26}
83c7162d 27
dc9dc135
XL
28fn parse_tests<It: Iterator<Item = String>>(mut lines: It) -> Vec<HashMap<String, String>> {
29 let mut tests = vec![];
83c7162d
XL
30 let mut test = HashMap::new();
31 let mut key: Option<String> = None;
32 let mut val = String::new();
33
34 macro_rules! finish_val ( () => (
35 match key.take() {
36 None => (),
37 Some(key) => {
38 assert!(test.insert(key, replace(&mut val, String::new())).is_none());
39 }
40 }
41 ));
42
43 macro_rules! finish_test ( () => (
44 if !test.is_empty() {
45 tests.push(replace(&mut test, HashMap::new()));
46 }
47 ));
48
49 loop {
50 match lines.next() {
51 None => break,
52 Some(line) => {
53 if line.starts_with("#") {
54 finish_val!();
55 if line == "#data" {
56 finish_test!();
57 }
58 key = Some(line[1..].to_string());
59 } else {
60 val.push_str(&line);
61 val.push('\n');
62 }
dc9dc135 63 },
83c7162d
XL
64 }
65 }
66
67 finish_val!();
68 finish_test!();
69 tests
70}
71
72fn serialize(buf: &mut String, indent: usize, handle: Handle) {
73 buf.push_str("|");
74 buf.push_str(&repeat(" ").take(indent).collect::<String>());
75
76 let node = handle;
77 match node.data {
78 NodeData::Document => panic!("should not reach Document"),
79
dc9dc135
XL
80 NodeData::Doctype {
81 ref name,
82 ref public_id,
83 ref system_id,
84 } => {
83c7162d
XL
85 buf.push_str("<!DOCTYPE ");
86 buf.push_str(&name);
87 if !public_id.is_empty() || !system_id.is_empty() {
88 buf.push_str(&format!(" \"{}\" \"{}\"", public_id, system_id));
89 }
90 buf.push_str(">\n");
dc9dc135 91 },
83c7162d
XL
92
93 NodeData::Text { ref contents } => {
94 buf.push_str("\"");
95 buf.push_str(&contents.borrow());
96 buf.push_str("\"\n");
dc9dc135 97 },
83c7162d 98
3dfed10e
XL
99 NodeData::ProcessingInstruction {
100 ref target,
101 ref contents,
102 } => {
103 buf.push_str("<?");
104 buf.push_str(&target);
105 buf.push_str(" ");
106 buf.push_str(&contents);
107 buf.push_str("?>\n");
108 },
109
83c7162d
XL
110 NodeData::Comment { ref contents } => {
111 buf.push_str("<!-- ");
112 buf.push_str(&contents);
113 buf.push_str(" -->\n");
dc9dc135 114 },
83c7162d 115
dc9dc135
XL
116 NodeData::Element {
117 ref name,
118 ref attrs,
119 ..
120 } => {
83c7162d 121 buf.push_str("<");
3dfed10e
XL
122
123 if name.ns != ns!() {
124 buf.push_str("{");
125 buf.push_str(&*name.ns);
126 buf.push_str("}");
127 };
128
129 if let Some(ref prefix) = name.prefix {
130 buf.push_str(&*prefix);
131 buf.push_str(":");
83c7162d 132 }
3dfed10e 133
83c7162d
XL
134 buf.push_str(&*name.local);
135 buf.push_str(">\n");
136
137 let mut attrs = attrs.borrow().clone();
138 attrs.sort_by(|x, y| x.name.local.cmp(&y.name.local));
139 // FIXME: sort by UTF-16 code unit
140
141 for attr in attrs.into_iter() {
142 buf.push_str("|");
dc9dc135 143 buf.push_str(&repeat(" ").take(indent + 2).collect::<String>());
3dfed10e
XL
144
145 if &*attr.name.ns != "" {
146 buf.push_str("{");
147 buf.push_str(&*attr.name.ns);
148 buf.push_str("}");
83c7162d 149 }
3dfed10e
XL
150
151 if let Some(attr_prefix) = attr.name.prefix {
152 buf.push_str(&*attr_prefix);
153 buf.push_str(":");
154 }
155
dc9dc135 156 buf.push_str(&format!("{}=\"{}\"\n", attr.name.local, attr.value));
83c7162d 157 }
dc9dc135 158 },
83c7162d
XL
159 }
160
161 for child in node.children.borrow().iter() {
dc9dc135 162 serialize(buf, indent + 2, child.clone());
83c7162d 163 }
83c7162d
XL
164}
165
3dfed10e
XL
166// Ignore tests containing these strings; we don't support these features yet.
167static IGNORE_SUBSTRS: &'static [&'static str] = &["<template"];
168
169fn make_xml_test(
dc9dc135
XL
170 tests: &mut Vec<TestDescAndFn>,
171 ignores: &HashSet<String>,
172 filename: &str,
173 idx: usize,
174 fields: HashMap<String, String>,
175) {
83c7162d
XL
176 let get_field = |key| {
177 let field = fields.get(key).expect("missing field");
e74abb32 178 field.trim_end_matches('\n').to_string()
83c7162d
XL
179 };
180
3dfed10e 181 let data = get_field("data");
83c7162d 182 let expected = get_field("document");
3dfed10e
XL
183 let name = format!("tb: {}-{}", filename, idx);
184 let ignore = ignores.contains(&name) || IGNORE_SUBSTRS.iter().any(|&ig| data.contains(ig));
83c7162d 185
3dfed10e 186 tests.push(TestDescAndFn {
83c7162d
XL
187 desc: TestDesc {
188 ignore: ignore,
dc9dc135 189 ..TestDesc::new(DynTestName(name))
83c7162d 190 },
3dfed10e 191 testfn: DynTestFn(Box::new(move || {
83c7162d 192 let mut result = String::new();
3dfed10e
XL
193
194 let dom = parse_document(RcDom::default(), Default::default()).one(data.clone());
195 for child in dom.document.children.borrow().iter() {
196 serialize(&mut result, 1, child.clone());
197 }
198
83c7162d 199 let len = result.len();
dc9dc135 200 result.truncate(len - 1); // drop the trailing newline
83c7162d
XL
201
202 if result != expected {
dc9dc135
XL
203 panic!(
204 "\ninput: {}\ngot:\n{}\nexpected:\n{}\n",
205 data, result, expected
206 );
83c7162d 207 }
3dfed10e
XL
208 })),
209 });
83c7162d
XL
210}
211
212fn tests(src_dir: &Path, ignores: &HashSet<String>) -> Vec<TestDescAndFn> {
dc9dc135
XL
213 let mut tests = vec![];
214
3dfed10e 215 foreach_xml5lib_test(
dc9dc135
XL
216 src_dir,
217 "tree-construction",
218 OsStr::new("dat"),
219 |path, file| {
220 let buf = io::BufReader::new(file);
221 let lines = buf.lines().map(|res| res.ok().expect("couldn't read"));
222 let data = parse_tests(lines);
223
224 for (i, test) in data.into_iter().enumerate() {
3dfed10e 225 make_xml_test(
dc9dc135
XL
226 &mut tests,
227 ignores,
228 path.file_name().unwrap().to_str().unwrap(),
229 i,
230 test,
231 );
232 }
233 },
234 );
83c7162d
XL
235
236 tests
237}
238
239fn main() {
240 let args: Vec<_> = env::args().collect();
241 let src_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
242 let mut ignores = HashSet::new();
3dfed10e 243 if let Ok(f) = fs::File::open(&src_dir.join("data/test/ignore")) {
83c7162d
XL
244 let r = io::BufReader::new(f);
245 for ln in r.lines() {
e74abb32 246 ignores.insert(ln.unwrap().trim_end().to_string());
83c7162d
XL
247 }
248 }
249
3dfed10e 250 rustc_test::test_main(&args, tests(src_dir, &ignores));
83c7162d 251}