The reconcile package is used for DOM reconcilation in Isomorphic Go web applications.

render_test.go 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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. }
  90. // Build a tree out of those nodes, based on a textual representation.
  91. // Only the ".\t"s are significant. The trailing HTML-like text is
  92. // just commentary. The "0:" prefixes are for easy cross-reference with
  93. // the nodes array.
  94. treeAsText := [...]string{
  95. 0: `<html>`,
  96. 1: `. <head>`,
  97. 2: `. <body>`,
  98. 3: `. . "0&lt;1"`,
  99. 4: `. . <p id="A" foo="abc&#34;def">`,
  100. 5: `. . . "2"`,
  101. 6: `. . . <b empty="">`,
  102. 7: `. . . . "3"`,
  103. 8: `. . . <i backslash="\">`,
  104. 9: `. . . . "&amp;4"`,
  105. 10: `. . "5"`,
  106. 11: `. . <blockquote>`,
  107. 12: `. . <br>`,
  108. 13: `. . "6"`,
  109. }
  110. if len(nodes) != len(treeAsText) {
  111. t.Fatal("len(nodes) != len(treeAsText)")
  112. }
  113. var stack [8]*Node
  114. for i, line := range treeAsText {
  115. level := 0
  116. for line[0] == '.' {
  117. // Strip a leading ".\t".
  118. line = line[2:]
  119. level++
  120. }
  121. n := nodes[i]
  122. if level == 0 {
  123. if stack[0] != nil {
  124. t.Fatal("multiple root nodes")
  125. }
  126. stack[0] = n
  127. } else {
  128. stack[level-1].AppendChild(n)
  129. stack[level] = n
  130. for i := level + 1; i < len(stack); i++ {
  131. stack[i] = nil
  132. }
  133. }
  134. // At each stage of tree construction, we check all nodes for consistency.
  135. for j, m := range nodes {
  136. if err := checkNodeConsistency(m); err != nil {
  137. t.Fatalf("i=%d, j=%d: %v", i, j, err)
  138. }
  139. }
  140. }
  141. want := `<html><head></head><body>0&lt;1<p id="A" foo="abc&#34;def">` +
  142. `2<b empty="">3</b><i backslash="\">&amp;4</i></p>` +
  143. `5<blockquote></blockquote><br/>6</body></html>`
  144. b := new(bytes.Buffer)
  145. if err := Render(b, nodes[0]); err != nil {
  146. t.Fatal(err)
  147. }
  148. if got := b.String(); got != want {
  149. t.Errorf("got vs want:\n%s\n%s\n", got, want)
  150. }
  151. }