1 package cascadia
2
3 import (
4 "fmt"
5 "strings"
6 "testing"
7
8 "golang.org/x/net/html"
9 )
10
11 type testSpec struct {
12
13 HTML, selector string
14
15 spec Specificity
16 }
17
18 var testsSpecificity = []testSpec{
19 {
20 HTML: `<html><body><div><div><a href="http://www.foo.com"></a></div></div></body></html>`,
21 selector: ":not(em, strong#foo)",
22 spec: Specificity{1, 0, 1},
23 },
24 {
25 HTML: `<html><body><div><div><a href="http://www.foo.com"></a></div></div></body></html>`,
26 selector: "*",
27 spec: Specificity{0, 0, 0},
28 },
29 {
30 HTML: `<html><body><div><div><ul></ul></div></div></body></html>`,
31 selector: "ul",
32 spec: Specificity{0, 0, 1},
33 },
34 {
35 HTML: `<html><body><div><ul><li></li></ul></div></body></html>`,
36 selector: "ul li",
37 spec: Specificity{0, 0, 2},
38 },
39 {
40 HTML: `<html><body><div><ul><ol></ol><li></li></ul></div></body></html>`,
41 selector: "ul ol+li",
42 spec: Specificity{0, 0, 3},
43 },
44 {
45 HTML: `<html><body><div><ul><h1></h1><li rel="up"></li></ul></div></body></html>`,
46 selector: "H1 + *[REL=up] ",
47 spec: Specificity{0, 1, 1},
48 },
49 {
50 HTML: `<html><body><ul><ol><li class="red"></li></ol></ul></body></html>`,
51 selector: "UL OL LI.red",
52 spec: Specificity{0, 1, 3},
53 },
54 {
55 HTML: `<html><body><ul><ol><li class="red level"></li></ol></ul></body></html>`,
56 selector: "LI.red.level",
57 spec: Specificity{0, 2, 1},
58 },
59 {
60 HTML: `<html><body><ul><ol><li id="x34y"></li></ol></ul></body></html>`,
61 selector: "#x34y",
62 spec: Specificity{1, 0, 0},
63 },
64 {
65 HTML: `<html><body><ul><ol><li id="s12"></li></ol></ul></body></html>`,
66 selector: "#s12:not(FOO)",
67 spec: Specificity{1, 0, 1},
68 },
69 {
70 HTML: `<html><body><ul><ol><li id="s12"></li></ol></ul></body></html>`,
71 selector: "#s12:not(FOO)",
72 spec: Specificity{1, 0, 1},
73 },
74 {
75 HTML: `<html><body><ul><ol><li id="s12"></li></ol></ul></body></html>`,
76 selector: "#s12:empty",
77 spec: Specificity{1, 1, 0},
78 },
79 {
80 HTML: `<html><body><ul><ol><li id="s12"></li></ol></ul></body></html>`,
81 selector: "#s12:only-child",
82 spec: Specificity{1, 1, 0},
83 },
84 }
85
86 func setupSel(selector, HTML string) (Sel, *html.Node, error) {
87 s, err := Parse(selector)
88 if err != nil {
89 return nil, nil, fmt.Errorf("error compiling %q: %s", selector, err)
90 }
91
92 doc, err := html.Parse(strings.NewReader(HTML))
93 if err != nil {
94 return nil, nil, fmt.Errorf("error parsing %q: %s", HTML, err)
95 }
96 return s, doc, nil
97 }
98
99 func TestSpecificity(t *testing.T) {
100 for _, test := range testsSpecificity {
101 s, doc, err := setupSel(test.selector, test.HTML)
102 if err != nil {
103 t.Fatal(err)
104 }
105 body := doc.FirstChild.LastChild
106 testNode := body.FirstChild.FirstChild.LastChild
107 if !s.Match(testNode) {
108 t.Errorf("%s didn't match (html tree : \n %s) \n", test.selector, nodeString(doc))
109 continue
110 }
111 gotSpec := s.Specificity()
112 if gotSpec != test.spec {
113 t.Errorf("wrong specificity : expected %v, got %v", test.spec, gotSpec)
114 }
115 }
116 }
117
118 func TestCompareSpecificity(t *testing.T) {
119 s1, s2 := Specificity{1, 1, 0}, Specificity{1, 0, 0}
120 if s1.Less(s2) {
121 t.Fatal()
122 }
123
124 if s1.Less(s1) {
125 t.Fatal()
126 }
127 }
128
View as plain text