1 use simplecss::*;
2 
3 struct XmlNode<'a, 'input: 'a>(roxmltree::Node<'a, 'input>);
4 
5 impl<'a, 'input: 'a> XmlNode<'a, 'input> {
select(&self, text: &str) -> Vec<roxmltree::Node<'a, 'input>>6     fn select(&self, text: &str) -> Vec<roxmltree::Node<'a, 'input>> {
7         let selectors = Selector::parse(text).unwrap();
8         let mut nodes = Vec::new();
9         for node in self.0.descendants().filter(|n| n.is_element()) {
10             if selectors.matches(&XmlNode(node)) {
11                 nodes.push(node);
12             }
13         }
14 
15         nodes
16     }
17 }
18 
19 impl simplecss::Element for XmlNode<'_, '_> {
parent_element(&self) -> Option<Self>20     fn parent_element(&self) -> Option<Self> {
21         self.0.parent_element().map(XmlNode)
22     }
23 
prev_sibling_element(&self) -> Option<Self>24     fn prev_sibling_element(&self) -> Option<Self> {
25         self.0.prev_siblings().filter(|n| n.is_element()).nth(0).map(XmlNode)
26     }
27 
has_local_name(&self, local_name: &str) -> bool28     fn has_local_name(&self, local_name: &str) -> bool {
29         self.0.tag_name().name() == local_name
30     }
31 
attribute_matches(&self, local_name: &str, operator: AttributeOperator) -> bool32     fn attribute_matches(&self, local_name: &str, operator: AttributeOperator) -> bool {
33         match self.0.attribute(local_name) {
34             Some(value) => operator.matches(value),
35             None => false,
36         }
37     }
38 
pseudo_class_matches(&self, class: PseudoClass) -> bool39     fn pseudo_class_matches(&self, class: PseudoClass) -> bool {
40         match class {
41             PseudoClass::FirstChild => self.prev_sibling_element().is_none(),
42             _ => false,
43         }
44     }
45 }
46 
47 macro_rules! match_single {
48     ($doc:expr, $selector:expr) => {{
49         let nodes = XmlNode($doc.root_element()).select($selector);
50         assert_eq!(nodes.len(), 1);
51         nodes[0].attribute("id").unwrap()
52     }};
53 }
54 
55 macro_rules! match_none {
56     ($doc:expr, $selector:expr) => {{
57         assert_eq!(XmlNode($doc.root_element()).select($selector).len(), 0);
58     }};
59 }
60 
61 #[test]
select_01()62 fn select_01() {
63     let doc = roxmltree::Document::parse("<div id='div1'/>").unwrap();
64     assert_eq!(match_single!(doc, "*"), "div1");
65 }
66 
67 #[test]
select_02()68 fn select_02() {
69     let doc = roxmltree::Document::parse("<div id='div1'/>").unwrap();
70     assert_eq!(match_single!(doc, "div"), "div1");
71     match_none!(doc, "p");
72 }
73 
74 #[test]
select_03()75 fn select_03() {
76     let doc = roxmltree::Document::parse("<div id='div1'/>").unwrap();
77     assert_eq!(match_single!(doc, "#div1"), "div1");
78     match_none!(doc, "#d1");
79 }
80 
81 #[test]
select_04()82 fn select_04() {
83     let doc = roxmltree::Document::parse("<div id='div1'/>").unwrap();
84     match_none!(doc, "p#div1");
85 }
86 
87 #[test]
select_05()88 fn select_05() {
89     let doc = roxmltree::Document::parse("\
90 <div id='div1'>
91     <p id='p1'/>
92 </div>
93 ").unwrap();
94 
95     assert_eq!(match_single!(doc, "div p"), "p1");
96 }
97 
98 #[test]
select_06()99 fn select_06() {
100     let doc = roxmltree::Document::parse("\
101 <div id='div1'>
102     <g id='g1'>
103         <p id='p1'/>
104     </g>
105 </div>
106 ").unwrap();
107 
108     assert_eq!(match_single!(doc, "div p"), "p1");
109 }
110 
111 #[test]
select_07()112 fn select_07() {
113     let doc = roxmltree::Document::parse("\
114 <div id='div1'>
115     <div id='div2'>
116         <g id='g1'>
117             <p id='p1'/>
118         </g>
119     </div>
120 </div>
121 ").unwrap();
122 
123     assert_eq!(match_single!(doc, "div p"), "p1");
124 }
125 
126 #[test]
select_08()127 fn select_08() {
128     let doc = roxmltree::Document::parse("\
129 <div id='div1'>
130     <g id='g1'>
131         <p id='p1'>
132             <div/>
133         </p>
134     </g>
135 </div>
136 ").unwrap();
137 
138     assert_eq!(match_single!(doc, "div p"), "p1");
139 }
140 
141 #[test]
select_09()142 fn select_09() {
143     let doc = roxmltree::Document::parse("\
144 <div id='div1'>
145     <g id='g1'>
146         <p id='p1'/>
147     </g>
148 </div>
149 ").unwrap();
150 
151     assert_eq!(match_single!(doc, "div g p"), "p1");
152 }
153 
154 #[test]
select_10()155 fn select_10() {
156     let doc = roxmltree::Document::parse("\
157 <div id='div1'>
158     <q id='g1'>
159         <p id='p1'/>
160     </q>
161 </div>
162 ").unwrap();
163 
164     match_none!(doc, "div g p");
165 }
166 
167 #[test]
select_11()168 fn select_11() {
169     let doc = roxmltree::Document::parse("\
170 <div id='div1'>
171     <g id='g1'>
172         <p id='p1'/>
173     </g>
174 </div>
175 ").unwrap();
176 
177     assert_eq!(match_single!(doc, "div * p"), "p1");
178 }
179 
180 #[test]
select_12()181 fn select_12() {
182     let doc = roxmltree::Document::parse("\
183 <div id='div1'>
184     <p id='p1'>
185         <rect id='rect1'/>
186         <rect id='rect2' color='green'/>
187     </p>
188 </div>
189 ").unwrap();
190 
191     assert_eq!(match_single!(doc, "div p *[color]"), "rect2");
192     assert_eq!(match_single!(doc, "div p [color]"), "rect2");
193 }
194 
195 #[test]
select_13()196 fn select_13() {
197     let doc = roxmltree::Document::parse("\
198 <div id='div1'>
199     <p id='p1'/>
200 </div>
201 ").unwrap();
202 
203     assert_eq!(match_single!(doc, "div > p"), "p1");
204 }
205 
206 #[test]
select_14()207 fn select_14() {
208     let doc = roxmltree::Document::parse("\
209 <p id='p1'/>
210 ").unwrap();
211 
212     match_none!(doc, "div > p");
213 }
214 
215 #[test]
select_15()216 fn select_15() {
217     let doc = roxmltree::Document::parse("\
218 <div id='div1'>
219     <g id='g1'>
220         <p id='p1'/>
221     </g>
222 </div>
223 ").unwrap();
224 
225     match_none!(doc, "div > p");
226 }
227 
228 #[test]
select_16()229 fn select_16() {
230     let doc = roxmltree::Document::parse("\
231 <div id='div1'>
232     <p>
233         <ol>
234             <li>
235                 <g>
236                     <p id='p1'/>
237                 </g>
238             </li>
239         </ol>
240     </p>
241 </div>
242 ").unwrap();
243 
244     assert_eq!(match_single!(doc, "div ol>li p"), "p1");
245 }
246 
247 #[test]
select_17()248 fn select_17() {
249     let doc = roxmltree::Document::parse("\
250 <div id='div1'>
251     <p>
252         <ol>
253             <g>
254                 <li>
255                     <g>
256                         <p id='p1'/>
257                     </g>
258                 </li>
259             </g>
260         </ol>
261     </p>
262 </div>
263 ").unwrap();
264 
265     match_none!(doc, "div ol>li p");
266 }
267 
268 #[test]
select_18()269 fn select_18() {
270     let doc = roxmltree::Document::parse("\
271 <div id='div1'>
272     <g/>
273     <p id='p1'/>
274 </div>
275 ").unwrap();
276 
277     assert_eq!(match_single!(doc, "g + p"), "p1");
278 }
279 
280 #[test]
select_19()281 fn select_19() {
282     let doc = roxmltree::Document::parse("\
283 <div id='div1'>
284     <test/>
285     <g/>
286     <p id='p1'/>
287 </div>
288 ").unwrap();
289 
290     assert_eq!(match_single!(doc, "g + p"), "p1");
291 }
292 
293 #[test]
select_20()294 fn select_20() {
295     let doc = roxmltree::Document::parse("\
296 <div id='div1'>
297     <p id='p1'/>
298     <g/>
299 </div>
300 ").unwrap();
301 
302     match_none!(doc, "g + p");
303 }
304 
305 #[test]
select_21()306 fn select_21() {
307     let doc = roxmltree::Document::parse("\
308 <div id='div1'>
309     <p id='p1'/>
310 </div>
311 ").unwrap();
312 
313     match_none!(doc, "div + p");
314 }
315 
316 #[test]
select_22()317 fn select_22() {
318     let doc = roxmltree::Document::parse("\
319 <div id='div1'>
320     <p id='p1'/>
321 </div>
322 ").unwrap();
323 
324     assert_eq!(match_single!(doc, "[id=p1]"), "p1");
325 }
326 
327 #[test]
select_23()328 fn select_23() {
329     let doc = roxmltree::Document::parse("\
330 <div id='div1'>
331     <p id='p1' class='test warn'/>
332 </div>
333 ").unwrap();
334 
335     assert_eq!(match_single!(doc, "[class~=warn]"), "p1");
336 }
337 
338 #[test]
select_24()339 fn select_24() {
340     let doc = roxmltree::Document::parse("\
341 <div id='div1'>
342     <p id='p1' class='test warn'/>
343 </div>
344 ").unwrap();
345 
346     match_none!(doc, "[class~='test warn']");
347 }
348 
349 #[test]
select_25()350 fn select_25() {
351     let doc = roxmltree::Document::parse("\
352 <div id='div1'>
353     <p id='p1' lang='en'/>
354 </div>
355 ").unwrap();
356 
357     assert_eq!(match_single!(doc, "[lang=en]"), "p1");
358     assert_eq!(match_single!(doc, "[lang|=en]"), "p1");
359 }
360 
361 #[test]
select_26()362 fn select_26() {
363     let doc = roxmltree::Document::parse("\
364 <div id='div1'>
365     <p id='p1' lang='en-US'/>
366 </div>
367 ").unwrap();
368 
369     assert_eq!(match_single!(doc, "[lang='en-US']"), "p1");
370     assert_eq!(match_single!(doc, "[lang|=en]"), "p1");
371 }
372 
373 #[test]
select_27()374 fn select_27() {
375     let doc = roxmltree::Document::parse("\
376 <div id='div1'>
377     <p id='p1' class='pastoral blue aqua marine'/>
378 </div>
379 ").unwrap();
380 
381     assert_eq!(match_single!(doc, ".marine.pastoral"), "p1");
382 }
383 
384 #[test]
select_28()385 fn select_28() {
386     let doc = roxmltree::Document::parse("\
387 <div id='div1'>
388     <p id='p1'/>
389 </div>
390 ").unwrap();
391 
392     assert_eq!(match_single!(doc, "p:first-child"), "p1");
393 }
394 
395 #[test]
select_29()396 fn select_29() {
397     let doc = roxmltree::Document::parse("\
398 <div id='div1'>
399     <rect/>
400     <p id='p1'/>
401 </div>
402 ").unwrap();
403 
404     match_none!(doc, "p:first-child");
405 }
406 
407 #[test]
select_30()408 fn select_30() {
409     let doc = roxmltree::Document::parse("\
410 <div id='div1'>
411     <p id='p1'/>
412     <p id='p2'/>
413 </div>
414 ").unwrap();
415 
416     let nodes = XmlNode(doc.root_element()).select(":first-child");
417     assert_eq!(nodes.len(), 2);
418     assert_eq!(nodes[0].attribute("id").unwrap(), "div1");
419     assert_eq!(nodes[1].attribute("id").unwrap(), "p1");
420 }
421 
422 #[test]
to_string()423 fn to_string() {
424     let selectors = Selector::parse("a > b").unwrap();
425     assert_eq!(selectors.to_string(), "a > b");
426 }
427