render_test.go 3.0 KB

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