1 #![allow(unused_variables)]
2 
3 extern crate select;
4 pub use select::document::Document;
5 pub use select::node;
6 pub use select::predicate::*;
7 
8 extern crate speculate;
9 use speculate::speculate;
10 
11 speculate! {
12     describe "predicate" {
13         before {
14             let document = Document::from("<html><head></head><body>\
15 <article id='post-0' class='post category-foo tag-bar'>foo</article>\
16 <!--A Comment-->\
17 <div class='a'><div class='b'><div class='c'><div class='d'></div></div></div></div>
18 </body></html>");
19             let html = document.nth(0).unwrap();
20             let head = document.nth(1).unwrap();
21             let body = document.nth(2).unwrap();
22             let article = document.nth(3).unwrap();
23             let foo = document.nth(4).unwrap();
24             let comment = document.nth(5).unwrap();
25             let a = document.nth(6).unwrap();
26             let b = document.nth(7).unwrap();
27             let c = document.nth(8).unwrap();
28             let d = document.nth(9).unwrap();
29         }
30 
31         test "Any" {
32             assert_eq!(super::Any.matches(&html), true);
33             assert_eq!(super::Any.matches(&head), true);
34             assert_eq!(super::Any.matches(&body), true);
35             assert_eq!(super::Any.matches(&article), true);
36         }
37 
38         test "Name()" {
39             assert_eq!(Name("html").matches(&html), true);
40             assert_eq!(Name("head").matches(&html), false);
41             assert_eq!(Name("body").matches(&html), false);
42             assert_eq!(Name("html").matches(&head), false);
43             assert_eq!(Name("head").matches(&head), true);
44             assert_eq!(Name("body").matches(&head), false);
45             assert_eq!(Name("html").matches(&body), false);
46             assert_eq!(Name("head").matches(&body), false);
47             assert_eq!(Name("body").matches(&body), true);
48         }
49 
50         test "Class()" {
51             assert_eq!(Class("post").matches(&html), false);
52             assert_eq!(Class("post").matches(&article), true);
53             assert_eq!(Class("category-foo").matches(&article), true);
54             assert_eq!(Class("tag-bar").matches(&article), true);
55             assert_eq!(Class("foo").matches(&article), false);
56             assert_eq!(Class("bar").matches(&article), false);
57         }
58 
59         test "Not()" {
60             assert_eq!(Not(Name("html")).matches(&html), false);
61             assert_eq!(Not(Name("html")).matches(&head), true);
62             assert_eq!(Not(Name("head")).matches(&html), true);
63             assert_eq!(Not(Name("head")).matches(&head), false);
64         }
65 
66         test "Attr()" {
67             assert_eq!(Attr("id", "post-0").matches(&html), false);
68             assert_eq!(Attr("id", "post-0").matches(&article), true);
69             assert_eq!(Attr("id", ()).matches(&html), false);
70             assert_eq!(Attr("id", ()).matches(&article), true);
71         }
72 
73         test "Fn(&Node) -> bool" {
74             let f = |node: &node::Node| node.name() == Some("html");
75             assert_eq!(f.matches(&html), true);
76             assert_eq!(f.matches(&head), false);
77             assert_eq!(f.matches(&body), false);
78         }
79 
80         test "Element" {
81             assert_eq!(super::Element.matches(&html), true);
82             assert_eq!(super::Element.matches(&head), true);
83             assert_eq!(super::Element.matches(&body), true);
84             assert_eq!(super::Element.matches(&article), true);
85             assert_eq!(super::Element.matches(&foo), false);
86         }
87 
88         test "Text" {
89             assert_eq!(super::Text.matches(&html), false);
90             assert_eq!(super::Text.matches(&head), false);
91             assert_eq!(super::Text.matches(&body), false);
92             assert_eq!(super::Text.matches(&article), false);
93             assert_eq!(super::Text.matches(&foo), true);
94             assert_eq!(super::Text.matches(&comment), false);
95         }
96 
97         test "Comment" {
98             assert_eq!(super::Comment.matches(&html), false);
99             assert_eq!(super::Comment.matches(&head), false);
100             assert_eq!(super::Comment.matches(&body), false);
101             assert_eq!(super::Comment.matches(&article), false);
102             assert_eq!(super::Comment.matches(&foo), false);
103             assert_eq!(super::Comment.matches(&comment), true);
104         }
105 
106         test "Or()" {
107             let html_or_head = Or(Name("html"), Name("head"));
108             assert_eq!(html_or_head.matches(&html), true);
109             assert_eq!(html_or_head.matches(&head), true);
110             assert_eq!(html_or_head.matches(&body), false);
111             assert_eq!(html_or_head.matches(&article), false);
112             assert_eq!(html_or_head.matches(&foo), false);
113         }
114 
115         test "And()" {
116             let article_and_post_0 = And(Name("article"), Attr("id", "post-0"));
117             assert_eq!(article_and_post_0.matches(&html), false);
118             assert_eq!(article_and_post_0.matches(&head), false);
119             assert_eq!(article_and_post_0.matches(&body), false);
120             assert_eq!(article_and_post_0.matches(&article), true);
121             assert_eq!(article_and_post_0.matches(&foo), false);
122         }
123 
124         test "Child()" {
125             let html_article = Child(Name("html"), Name("article"));
126             assert_eq!(html_article.matches(&html), false);
127             assert_eq!(html_article.matches(&article), false);
128 
129             let body_article = Child(Name("body"), Name("article"));
130             assert_eq!(body_article.matches(&html), false);
131             assert_eq!(body_article.matches(&article), true);
132         }
133 
134         test "Descendant()" {
135             let check = |parent: &str, child: &str, matching: Option<usize>| {
136                 let selector = Descendant(Class(parent), Class(child));
137                 for node in &[a, b, c, d] {
138                     let expected = matching.map_or(false, |index| node.index() == index);
139                     assert_eq!(selector.matches(node), expected);
140                 }
141             };
142 
143             check("a", "a", None);
144             check("a", "b", Some(b.index()));
145             check("a", "c", Some(c.index()));
146             check("a", "d", Some(d.index()));
147             check("b", "a", None);
148             check("b", "b", None);
149             check("b", "c", Some(c.index()));
150             check("b", "d", Some(d.index()));
151             check("c", "a", None);
152             check("c", "b", None);
153             check("c", "c", None);
154             check("c", "d", Some(d.index()));
155             check("d", "a", None);
156             check("d", "b", None);
157             check("d", "c", None);
158             check("d", "d", None);
159         }
160 
161         // https://github.com/utkarshkukreti/select.rs/issues/35
162         test "Box<Predicate>" {
163             let post_0: Box<Predicate> = Box::new(Attr("id", "post-0"));
164             assert_eq!(post_0.matches(&html), false);
165             assert_eq!(post_0.matches(&head), false);
166             assert_eq!(post_0.matches(&article), true);
167             let not_html: Box<Predicate> = Box::new(Not(Name("html")));
168             assert_eq!(not_html.matches(&html), false);
169             assert_eq!(not_html.matches(&head), true);
170             assert_eq!(not_html.matches(&article), true);
171         }
172     }
173 }
174