1
2
3
4
5 package html
6
7 import (
8 "bytes"
9 "fmt"
10 "strings"
11 "testing"
12 )
13
14 func TestRenderer(t *testing.T) {
15 nodes := [...]*Node{
16 0: {
17 Type: ElementNode,
18 Data: "html",
19 },
20 1: {
21 Type: ElementNode,
22 Data: "head",
23 },
24 2: {
25 Type: ElementNode,
26 Data: "body",
27 },
28 3: {
29 Type: TextNode,
30 Data: "0<1",
31 },
32 4: {
33 Type: ElementNode,
34 Data: "p",
35 Attr: []Attribute{
36 {
37 Key: "id",
38 Val: "A",
39 },
40 {
41 Key: "foo",
42 Val: `abc"def`,
43 },
44 },
45 },
46 5: {
47 Type: TextNode,
48 Data: "2",
49 },
50 6: {
51 Type: ElementNode,
52 Data: "b",
53 Attr: []Attribute{
54 {
55 Key: "empty",
56 Val: "",
57 },
58 },
59 },
60 7: {
61 Type: TextNode,
62 Data: "3",
63 },
64 8: {
65 Type: ElementNode,
66 Data: "i",
67 Attr: []Attribute{
68 {
69 Key: "backslash",
70 Val: `\`,
71 },
72 },
73 },
74 9: {
75 Type: TextNode,
76 Data: "&4",
77 },
78 10: {
79 Type: TextNode,
80 Data: "5",
81 },
82 11: {
83 Type: ElementNode,
84 Data: "blockquote",
85 },
86 12: {
87 Type: ElementNode,
88 Data: "br",
89 },
90 13: {
91 Type: TextNode,
92 Data: "6",
93 },
94 14: {
95 Type: CommentNode,
96 Data: "comm",
97 },
98 15: {
99 Type: CommentNode,
100 Data: "x-->y",
101 },
102 16: {
103 Type: RawNode,
104 Data: "7<pre>8</pre>9",
105 },
106 }
107
108
109
110
111
112 treeAsText := [...]string{
113 0: `<html>`,
114 1: `. <head>`,
115 2: `. <body>`,
116 3: `. . "0<1"`,
117 4: `. . <p id="A" foo="abc"def">`,
118 5: `. . . "2"`,
119 6: `. . . <b empty="">`,
120 7: `. . . . "3"`,
121 8: `. . . <i backslash="\">`,
122 9: `. . . . "&4"`,
123 10: `. . "5"`,
124 11: `. . <blockquote>`,
125 12: `. . <br>`,
126 13: `. . "6"`,
127 14: `. . "<!--comm-->"`,
128 15: `. . "<!--x-->y-->"`,
129 16: `. . "7<pre>8</pre>9"`,
130 }
131 if len(nodes) != len(treeAsText) {
132 t.Fatal("len(nodes) != len(treeAsText)")
133 }
134 var stack [8]*Node
135 for i, line := range treeAsText {
136 level := 0
137 for line[0] == '.' {
138
139 line = line[2:]
140 level++
141 }
142 n := nodes[i]
143 if level == 0 {
144 if stack[0] != nil {
145 t.Fatal("multiple root nodes")
146 }
147 stack[0] = n
148 } else {
149 stack[level-1].AppendChild(n)
150 stack[level] = n
151 for i := level + 1; i < len(stack); i++ {
152 stack[i] = nil
153 }
154 }
155
156 for j, m := range nodes {
157 if err := checkNodeConsistency(m); err != nil {
158 t.Fatalf("i=%d, j=%d: %v", i, j, err)
159 }
160 }
161 }
162
163 want := `<html><head></head><body>0<1<p id="A" foo="abc"def">` +
164 `2<b empty="">3</b><i backslash="\">&4</i></p>` +
165 `5<blockquote></blockquote><br/>6<!--comm--><!--x-->y-->7<pre>8</pre>9</body></html>`
166 b := new(bytes.Buffer)
167 if err := Render(b, nodes[0]); err != nil {
168 t.Fatal(err)
169 }
170 if got := b.String(); got != want {
171 t.Errorf("got vs want:\n%s\n%s\n", got, want)
172 }
173 }
174
175 func TestRenderTextNodes(t *testing.T) {
176 elements := []string{"style", "script", "xmp", "iframe", "noembed", "noframes", "plaintext", "noscript"}
177 for _, namespace := range []string{
178 "",
179 "svg",
180 "math",
181 } {
182 for _, e := range elements {
183 var namespaceOpen, namespaceClose string
184 if namespace != "" {
185 namespaceOpen, namespaceClose = fmt.Sprintf("<%s>", namespace), fmt.Sprintf("</%s>", namespace)
186 }
187 doc := fmt.Sprintf(`<html><head></head><body>%s<%s>&</%s>%s</body></html>`, namespaceOpen, e, e, namespaceClose)
188 n, err := Parse(strings.NewReader(doc))
189 if err != nil {
190 t.Fatal(err)
191 }
192 b := bytes.NewBuffer(nil)
193 if err := Render(b, n); err != nil {
194 t.Fatal(err)
195 }
196
197 expected := doc
198 if namespace != "" {
199 expected = strings.Replace(expected, "&", "&", 1)
200 }
201
202 if b.String() != expected {
203 t.Errorf("unexpected output: got %q, want %q", b.String(), expected)
204 }
205 }
206 }
207 }
208
View as plain text