Nigel Tao | ea127e8 | 2013-02-11 11:55:20 +1100 | [diff] [blame] | 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 | "testing" |
| 10 | ) |
| 11 | |
| 12 | func TestRenderer(t *testing.T) { |
| 13 | nodes := [...]*Node{ |
| 14 | 0: { |
| 15 | Type: ElementNode, |
| 16 | Data: "html", |
| 17 | }, |
| 18 | 1: { |
| 19 | Type: ElementNode, |
| 20 | Data: "head", |
| 21 | }, |
| 22 | 2: { |
| 23 | Type: ElementNode, |
| 24 | Data: "body", |
| 25 | }, |
| 26 | 3: { |
| 27 | Type: TextNode, |
| 28 | Data: "0<1", |
| 29 | }, |
| 30 | 4: { |
| 31 | Type: ElementNode, |
| 32 | Data: "p", |
| 33 | Attr: []Attribute{ |
| 34 | { |
| 35 | Key: "id", |
| 36 | Val: "A", |
| 37 | }, |
| 38 | { |
| 39 | Key: "foo", |
| 40 | Val: `abc"def`, |
| 41 | }, |
| 42 | }, |
| 43 | }, |
| 44 | 5: { |
| 45 | Type: TextNode, |
| 46 | Data: "2", |
| 47 | }, |
| 48 | 6: { |
| 49 | Type: ElementNode, |
| 50 | Data: "b", |
| 51 | Attr: []Attribute{ |
| 52 | { |
| 53 | Key: "empty", |
| 54 | Val: "", |
| 55 | }, |
| 56 | }, |
| 57 | }, |
| 58 | 7: { |
| 59 | Type: TextNode, |
| 60 | Data: "3", |
| 61 | }, |
| 62 | 8: { |
| 63 | Type: ElementNode, |
| 64 | Data: "i", |
| 65 | Attr: []Attribute{ |
| 66 | { |
| 67 | Key: "backslash", |
| 68 | Val: `\`, |
| 69 | }, |
| 70 | }, |
| 71 | }, |
| 72 | 9: { |
| 73 | Type: TextNode, |
| 74 | Data: "&4", |
| 75 | }, |
| 76 | 10: { |
| 77 | Type: TextNode, |
| 78 | Data: "5", |
| 79 | }, |
| 80 | 11: { |
| 81 | Type: ElementNode, |
| 82 | Data: "blockquote", |
| 83 | }, |
| 84 | 12: { |
| 85 | Type: ElementNode, |
| 86 | Data: "br", |
| 87 | }, |
| 88 | 13: { |
| 89 | Type: TextNode, |
| 90 | Data: "6", |
| 91 | }, |
| 92 | } |
| 93 | |
| 94 | // Build a tree out of those nodes, based on a textual representation. |
| 95 | // Only the ".\t"s are significant. The trailing HTML-like text is |
| 96 | // just commentary. The "0:" prefixes are for easy cross-reference with |
| 97 | // the nodes array. |
| 98 | treeAsText := [...]string{ |
| 99 | 0: `<html>`, |
| 100 | 1: `. <head>`, |
| 101 | 2: `. <body>`, |
| 102 | 3: `. . "0<1"`, |
| 103 | 4: `. . <p id="A" foo="abc"def">`, |
| 104 | 5: `. . . "2"`, |
| 105 | 6: `. . . <b empty="">`, |
| 106 | 7: `. . . . "3"`, |
| 107 | 8: `. . . <i backslash="\">`, |
| 108 | 9: `. . . . "&4"`, |
| 109 | 10: `. . "5"`, |
| 110 | 11: `. . <blockquote>`, |
| 111 | 12: `. . <br>`, |
| 112 | 13: `. . "6"`, |
| 113 | } |
| 114 | if len(nodes) != len(treeAsText) { |
| 115 | t.Fatal("len(nodes) != len(treeAsText)") |
| 116 | } |
| 117 | var stack [8]*Node |
| 118 | for i, line := range treeAsText { |
| 119 | level := 0 |
| 120 | for line[0] == '.' { |
| 121 | // Strip a leading ".\t". |
| 122 | line = line[2:] |
| 123 | level++ |
| 124 | } |
| 125 | n := nodes[i] |
| 126 | if level == 0 { |
| 127 | if stack[0] != nil { |
| 128 | t.Fatal("multiple root nodes") |
| 129 | } |
| 130 | stack[0] = n |
| 131 | } else { |
| 132 | stack[level-1].AppendChild(n) |
| 133 | stack[level] = n |
| 134 | for i := level + 1; i < len(stack); i++ { |
| 135 | stack[i] = nil |
| 136 | } |
| 137 | } |
| 138 | // At each stage of tree construction, we check all nodes for consistency. |
| 139 | for j, m := range nodes { |
| 140 | if err := checkNodeConsistency(m); err != nil { |
| 141 | t.Fatalf("i=%d, j=%d: %v", i, j, err) |
| 142 | } |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | want := `<html><head></head><body>0<1<p id="A" foo="abc"def">` + |
| 147 | `2<b empty="">3</b><i backslash="\">&4</i></p>` + |
| 148 | `5<blockquote></blockquote><br/>6</body></html>` |
| 149 | b := new(bytes.Buffer) |
| 150 | if err := Render(b, nodes[0]); err != nil { |
| 151 | t.Fatal(err) |
| 152 | } |
| 153 | if got := b.String(); got != want { |
| 154 | t.Errorf("got vs want:\n%s\n%s\n", got, want) |
| 155 | } |
| 156 | } |