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 &#34;fmt&#34;</span>
    32  <span num="5"></span>
    33  <span num="6">func main() {</span>
    34  <span num="7">    fmt.Println(&#34;hello, test&#34;)</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(&#34;hello, test&#34;)"),
    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(&#34;hello, test&#34;)</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  }