You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

225 lines
5.9 KiB

  1. // Copyright 2012 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 present
  5. import (
  6. "fmt"
  7. "html/template"
  8. "strings"
  9. "testing"
  10. )
  11. func TestParseCode(t *testing.T) {
  12. // Enable play but revert the change at the end.
  13. defer func(play bool) { PlayEnabled = play }(PlayEnabled)
  14. PlayEnabled = true
  15. helloTest := []byte(`
  16. package main
  17. import "fmt"
  18. func main() {
  19. fmt.Println("hello, test")
  20. }
  21. `)
  22. helloTestHTML := template.HTML(`
  23. <pre><span num="2">package main</span>
  24. <span num="3"></span>
  25. <span num="4">import &#34;fmt&#34;</span>
  26. <span num="5"></span>
  27. <span num="6">func main() {</span>
  28. <span num="7"> fmt.Println(&#34;hello, test&#34;)</span>
  29. <span num="8">}</span>
  30. </pre>
  31. `)
  32. helloTestHL := []byte(`
  33. package main
  34. import "fmt" // HLimport
  35. func main() { // HLfunc
  36. fmt.Println("hello, test") // HL
  37. }
  38. `)
  39. highlight := func(h template.HTML, s string) template.HTML {
  40. return template.HTML(strings.Replace(string(h), s, "<b>"+s+"</b>", -1))
  41. }
  42. read := func(b []byte, err error) func(string) ([]byte, error) {
  43. return func(string) ([]byte, error) { return b, err }
  44. }
  45. tests := []struct {
  46. name string
  47. readFile func(string) ([]byte, error)
  48. sourceFile string
  49. cmd string
  50. err string
  51. Code
  52. }{
  53. {
  54. name: "all code, no play",
  55. readFile: read(helloTest, nil),
  56. sourceFile: "main.go",
  57. cmd: ".code main.go",
  58. Code: Code{
  59. Ext: ".go",
  60. FileName: "main.go",
  61. Raw: helloTest,
  62. Text: helloTestHTML,
  63. },
  64. },
  65. {
  66. name: "all code, play",
  67. readFile: read(helloTest, nil),
  68. sourceFile: "main.go",
  69. cmd: ".play main.go",
  70. Code: Code{
  71. Ext: ".go",
  72. FileName: "main.go",
  73. Play: true,
  74. Raw: helloTest,
  75. Text: helloTestHTML,
  76. },
  77. },
  78. {
  79. name: "all code, highlighted",
  80. readFile: read(helloTestHL, nil),
  81. sourceFile: "main.go",
  82. cmd: ".code main.go",
  83. Code: Code{
  84. Ext: ".go",
  85. FileName: "main.go",
  86. Raw: helloTestHL,
  87. Text: highlight(helloTestHTML, "fmt.Println(&#34;hello, test&#34;)"),
  88. },
  89. },
  90. {
  91. name: "highlight only func",
  92. readFile: read(helloTestHL, nil),
  93. sourceFile: "main.go",
  94. cmd: ".code main.go HLfunc",
  95. Code: Code{
  96. Ext: ".go",
  97. FileName: "main.go",
  98. Play: false,
  99. Raw: []byte("package main\n\nimport \"fmt\" // HLimport\n\nfunc main() { // HLfunc\n\tfmt.Println(\"hello, test\") // HL\n}"),
  100. Text: highlight(helloTestHTML, "func main() {"),
  101. },
  102. },
  103. {
  104. name: "bad highlight syntax",
  105. readFile: read(helloTest, nil),
  106. sourceFile: "main.go",
  107. cmd: ".code main.go HL",
  108. err: "invalid highlight syntax",
  109. },
  110. {
  111. name: "error reading file",
  112. readFile: read(nil, fmt.Errorf("nope")),
  113. sourceFile: "main.go",
  114. cmd: ".code main.go",
  115. err: "main.go:0: nope",
  116. },
  117. {
  118. name: "from func main to the end",
  119. readFile: read(helloTest, nil),
  120. sourceFile: "main.go",
  121. cmd: ".code main.go /func main/,",
  122. Code: Code{
  123. Ext: ".go",
  124. FileName: "main.go",
  125. Play: false,
  126. Raw: []byte("func main() {\n\tfmt.Println(\"hello, test\")\n}"),
  127. Text: "<pre><span num=\"6\">func main() {</span>\n<span num=\"7\"> fmt.Println(&#34;hello, test&#34;)</span>\n<span num=\"8\">}</span>\n</pre>",
  128. },
  129. },
  130. {
  131. name: "just func main",
  132. readFile: read(helloTest, nil),
  133. sourceFile: "main.go",
  134. cmd: ".code main.go /func main/",
  135. Code: Code{
  136. Ext: ".go",
  137. FileName: "main.go",
  138. Play: false,
  139. Raw: []byte("func main() {"),
  140. Text: "<pre><span num=\"6\">func main() {</span>\n</pre>",
  141. },
  142. },
  143. {
  144. name: "bad address",
  145. readFile: read(helloTest, nil),
  146. sourceFile: "main.go",
  147. cmd: ".code main.go /function main/",
  148. err: "main.go:0: no match for function main",
  149. },
  150. {
  151. name: "all code with numbers",
  152. readFile: read(helloTest, nil),
  153. sourceFile: "main.go",
  154. cmd: ".code -numbers main.go",
  155. Code: Code{
  156. Ext: ".go",
  157. FileName: "main.go",
  158. Raw: helloTest,
  159. // Replacing the first "<pre>"
  160. Text: "<pre class=\"numbers\">" + helloTestHTML[6:],
  161. },
  162. },
  163. {
  164. name: "all code editable",
  165. readFile: read(helloTest, nil),
  166. sourceFile: "main.go",
  167. cmd: ".code -edit main.go",
  168. Code: Code{
  169. Ext: ".go",
  170. FileName: "main.go",
  171. Raw: helloTest,
  172. Text: "<pre contenteditable=\"true\" spellcheck=\"false\">" + helloTestHTML[6:],
  173. },
  174. },
  175. }
  176. trimHTML := func(t template.HTML) string { return strings.TrimSpace(string(t)) }
  177. trimBytes := func(b []byte) string { return strings.TrimSpace(string(b)) }
  178. for _, tt := range tests {
  179. ctx := &Context{tt.readFile}
  180. e, err := parseCode(ctx, tt.sourceFile, 0, tt.cmd)
  181. if err != nil {
  182. if tt.err == "" {
  183. t.Errorf("%s: unexpected error %v", tt.name, err)
  184. } else if !strings.Contains(err.Error(), tt.err) {
  185. t.Errorf("%s: expected error %s; got %v", tt.name, tt.err, err)
  186. }
  187. continue
  188. }
  189. if tt.err != "" {
  190. t.Errorf("%s: expected error %s; but got none", tt.name, tt.err)
  191. continue
  192. }
  193. c, ok := e.(Code)
  194. if !ok {
  195. t.Errorf("%s: expected a Code value; got %T", tt.name, e)
  196. continue
  197. }
  198. if c.FileName != tt.FileName {
  199. t.Errorf("%s: expected FileName %s; got %s", tt.name, tt.FileName, c.FileName)
  200. }
  201. if c.Ext != tt.Ext {
  202. t.Errorf("%s: expected Ext %s; got %s", tt.name, tt.Ext, c.Ext)
  203. }
  204. if c.Play != tt.Play {
  205. t.Errorf("%s: expected Play %v; got %v", tt.name, tt.Play, c.Play)
  206. }
  207. if got, wants := trimBytes(c.Raw), trimBytes(tt.Raw); got != wants {
  208. t.Errorf("%s: expected Raw \n%q\n; got \n%q\n", tt.name, wants, got)
  209. }
  210. if got, wants := trimHTML(c.Text), trimHTML(tt.Text); got != wants {
  211. t.Errorf("%s: expected Text \n%q\n; got \n%q\n", tt.name, wants, got)
  212. }
  213. }
  214. }