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