github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/present/parse_test.go (about)

     1  // Copyright 2020 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  	"bytes"
     9  	"html/template"
    10  	"io/ioutil"
    11  	"os"
    12  	"os/exec"
    13  	"path/filepath"
    14  	"runtime"
    15  	"testing"
    16  )
    17  
    18  func TestTestdata(t *testing.T) {
    19  	tmpl := template.Must(Template().Parse(testTmpl))
    20  	filesP, err := filepath.Glob("testdata/*.p")
    21  	if err != nil {
    22  		t.Fatal(err)
    23  	}
    24  	filesMD, err := filepath.Glob("testdata/*.md")
    25  	if err != nil {
    26  		t.Fatal(err)
    27  	}
    28  	files := append(filesP, filesMD...)
    29  	for _, file := range files {
    30  		file := file
    31  		name := filepath.Base(file)
    32  		if name == "README" {
    33  			continue
    34  		}
    35  		t.Run(name, func(t *testing.T) {
    36  			data, err := ioutil.ReadFile(file)
    37  			if err != nil {
    38  				t.Fatalf("%s: %v", file, err)
    39  			}
    40  			marker := []byte("\n---\n")
    41  			i := bytes.Index(data, marker)
    42  			if i < 0 {
    43  				t.Fatalf("%s: cannot find --- marker in input", file)
    44  			}
    45  			input, html := data[:i+1], data[i+len(marker):]
    46  			doc, err := Parse(bytes.NewReader(input), name, 0)
    47  			if err != nil {
    48  				t.Fatalf("%s: %v", file, err)
    49  			}
    50  			var buf bytes.Buffer
    51  			if err := doc.Render(&buf, tmpl); err != nil {
    52  				t.Fatalf("%s: %v", file, err)
    53  			}
    54  			if !bytes.Equal(buf.Bytes(), html) {
    55  				diffText, err := diff("present-test-", "want", html, "have", buf.Bytes())
    56  				if err != nil {
    57  					t.Fatalf("%s: diff: %v", file, err)
    58  				}
    59  				t.Errorf("%s: incorrect html:\n%s", file, diffText)
    60  			}
    61  		})
    62  	}
    63  }
    64  
    65  func diff(prefix string, name1 string, b1 []byte, name2 string, b2 []byte) ([]byte, error) {
    66  	f1, err := writeTempFile(prefix, b1)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  	defer os.Remove(f1)
    71  
    72  	f2, err := writeTempFile(prefix, b2)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  	defer os.Remove(f2)
    77  
    78  	cmd := "diff"
    79  	if runtime.GOOS == "plan9" {
    80  		cmd = "/bin/ape/diff"
    81  	}
    82  
    83  	data, err := exec.Command(cmd, "-u", f1, f2).CombinedOutput()
    84  	if len(data) > 0 {
    85  		// diff exits with a non-zero status when the files don't match.
    86  		// Ignore that failure as long as we get output.
    87  		err = nil
    88  	}
    89  
    90  	data = bytes.Replace(data, []byte(f1), []byte(name1), -1)
    91  	data = bytes.Replace(data, []byte(f2), []byte(name2), -1)
    92  
    93  	return data, err
    94  }
    95  
    96  func writeTempFile(prefix string, data []byte) (string, error) {
    97  	file, err := ioutil.TempFile("", prefix)
    98  	if err != nil {
    99  		return "", err
   100  	}
   101  	_, err = file.Write(data)
   102  	if err1 := file.Close(); err == nil {
   103  		err = err1
   104  	}
   105  	if err != nil {
   106  		os.Remove(file.Name())
   107  		return "", err
   108  	}
   109  	return file.Name(), nil
   110  }
   111  
   112  var testTmpl = `
   113  {{define "root" -}}
   114  <h1>{{.Title}}</h1>
   115  {{with .Subtitle}}<h2>{{.}}</h2>
   116  {{end -}}
   117  {{range .Authors}}<author>
   118  {{range .Elem}}{{elem $.Template .}}{{end}}</author>
   119  {{end -}}
   120  {{range .Sections}}<section>{{elem $.Template .}}</section>
   121  {{end -}}
   122  {{end}}
   123  
   124  {{define "newline"}}{{/* No automatic line break. Paragraphs are free-form. */}}
   125  {{end}}
   126  
   127  {{define "section"}}
   128  {{if .Title}}<h2 id="TOC_{{.FormattedNumber}}">{{.Title}}</h2>
   129  {{end -}}
   130  {{range .Elem}}{{elem $.Template .}}{{end}}
   131  {{- end}}
   132  
   133  {{define "list" -}}
   134  <ul>
   135  {{range .Bullet -}}
   136  <li>{{style .}}</li>
   137  {{end -}}
   138  </ul>
   139  {{end}}
   140  
   141  {{define "text" -}}
   142  {{if .Pre -}}
   143  <pre>{{range .Lines}}{{.}}{{end}}</pre>
   144  {{else -}}
   145  <p>{{range $i, $l := .Lines}}{{if $i}}{{template "newline"}}{{end}}{{style $l}}{{end}}</p>
   146  {{end -}}
   147  {{end}}
   148  
   149  {{define "code" -}}
   150  {{if .Play -}}
   151  <div class="playground">{{.Text}}</div>
   152  {{else -}}
   153  <div class="code">{{.Text}}</div>
   154  {{end -}}
   155  {{end}}
   156  
   157  {{define "image" -}}
   158  <img src="{{.URL}}"{{with .Height}} height="{{.}}"{{end}}{{with .Width}} width="{{.}}"{{end}} alt="">
   159  {{end}}
   160  
   161  {{define "caption" -}}
   162  <figcaption>{{style .Text}}</figcaption>
   163  {{end}}
   164  
   165  {{define "iframe" -}}
   166  <iframe src="{{.URL}}"{{with .Height}} height="{{.}}"{{end}}{{with .Width}} width="{{.}}"{{end}}></iframe>
   167  {{end}}
   168  
   169  {{define "link" -}}
   170  <p class="link"><a href="{{.URL}}">{{style .Label}}</a></p>
   171  {{end}}
   172  
   173  {{define "html" -}}{{.HTML}}{{end}}
   174  `