golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/html/render_test.go (about) 1 // Copyright 2010 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 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", // Needs escaping. 101 }, 102 16: { 103 Type: RawNode, 104 Data: "7<pre>8</pre>9", 105 }, 106 } 107 108 // Build a tree out of those nodes, based on a textual representation. 109 // Only the ".\t"s are significant. The trailing HTML-like text is 110 // just commentary. The "0:" prefixes are for easy cross-reference with 111 // the nodes array. 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 // Strip a leading ".\t". 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 // At each stage of tree construction, we check all nodes for consistency. 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 "", // html 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 }