зеркало из https://github.com/golang/tools.git
177 строки
3.9 KiB
Go
177 строки
3.9 KiB
Go
// Copyright 2020 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package present
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"html/template"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
"testing"
|
|
)
|
|
|
|
func TestTestdata(t *testing.T) {
|
|
tmpl := template.Must(Template().Parse(testTmpl))
|
|
filesP, err := filepath.Glob("testdata/*.p")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
filesMD, err := filepath.Glob("testdata/*.md")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
files := append(filesP, filesMD...)
|
|
for _, file := range files {
|
|
file := file
|
|
name := filepath.Base(file)
|
|
if name == "README" {
|
|
continue
|
|
}
|
|
t.Run(name, func(t *testing.T) {
|
|
data, err := os.ReadFile(file)
|
|
if err != nil {
|
|
t.Fatalf("%s: %v", file, err)
|
|
}
|
|
marker := []byte("\n---\n")
|
|
i := bytes.Index(data, marker)
|
|
if i < 0 {
|
|
t.Fatalf("%s: cannot find --- marker in input", file)
|
|
}
|
|
input, html := data[:i+1], data[i+len(marker):]
|
|
doc, err := Parse(bytes.NewReader(input), name, 0)
|
|
if err != nil {
|
|
t.Fatalf("%s: %v", file, err)
|
|
}
|
|
var buf bytes.Buffer
|
|
if err := doc.Render(&buf, tmpl); err != nil {
|
|
t.Fatalf("%s: %v", file, err)
|
|
}
|
|
if !bytes.Equal(buf.Bytes(), html) {
|
|
diffText, err := diff("present-test-", "want", html, "have", buf.Bytes())
|
|
if err != nil {
|
|
t.Fatalf("%s: diff: %v", file, err)
|
|
}
|
|
t.Errorf("%s: incorrect html:\n%s", file, diffText)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func diff(prefix string, name1 string, b1 []byte, name2 string, b2 []byte) ([]byte, error) {
|
|
f1, err := writeTempFile(prefix, b1)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer os.Remove(f1)
|
|
|
|
f2, err := writeTempFile(prefix, b2)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer os.Remove(f2)
|
|
|
|
cmd := "diff"
|
|
if runtime.GOOS == "plan9" {
|
|
cmd = "/bin/ape/diff"
|
|
}
|
|
|
|
data, err := exec.Command(cmd, "-u", f1, f2).Output()
|
|
if len(data) > 0 {
|
|
// diff exits with a non-zero status when the files don't match.
|
|
// Ignore that failure as long as we get output.
|
|
err = nil
|
|
} else if exit, ok := err.(*exec.ExitError); ok && len(exit.Stderr) > 0 {
|
|
err = fmt.Errorf("%w\nstderr:\n%s)", err, exit.Stderr)
|
|
}
|
|
|
|
data = bytes.Replace(data, []byte(f1), []byte(name1), -1)
|
|
data = bytes.Replace(data, []byte(f2), []byte(name2), -1)
|
|
|
|
return data, err
|
|
}
|
|
|
|
func writeTempFile(prefix string, data []byte) (string, error) {
|
|
file, err := os.CreateTemp("", prefix)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
_, err = file.Write(data)
|
|
if err1 := file.Close(); err == nil {
|
|
err = err1
|
|
}
|
|
if err != nil {
|
|
os.Remove(file.Name())
|
|
return "", err
|
|
}
|
|
return file.Name(), nil
|
|
}
|
|
|
|
var testTmpl = `
|
|
{{define "root" -}}
|
|
<h1>{{.Title}}</h1>
|
|
{{with .Subtitle}}<h2>{{.}}</h2>
|
|
{{end -}}
|
|
{{range .Authors}}<author>
|
|
{{range .Elem}}{{elem $.Template .}}{{end}}</author>
|
|
{{end -}}
|
|
{{range .Sections}}<section>{{elem $.Template .}}</section>
|
|
{{end -}}
|
|
{{end}}
|
|
|
|
{{define "newline"}}{{/* No automatic line break. Paragraphs are free-form. */}}
|
|
{{end}}
|
|
|
|
{{define "section"}}
|
|
{{if .Title}}<h2 id="TOC_{{.FormattedNumber}}">{{.Title}}</h2>
|
|
{{end -}}
|
|
{{range .Elem}}{{elem $.Template .}}{{end}}
|
|
{{- end}}
|
|
|
|
{{define "list" -}}
|
|
<ul>
|
|
{{range .Bullet -}}
|
|
<li>{{style .}}</li>
|
|
{{end -}}
|
|
</ul>
|
|
{{end}}
|
|
|
|
{{define "text" -}}
|
|
{{if .Pre -}}
|
|
<pre>{{range .Lines}}{{.}}{{end}}</pre>
|
|
{{else -}}
|
|
<p>{{range $i, $l := .Lines}}{{if $i}}{{template "newline"}}{{end}}{{style $l}}{{end}}</p>
|
|
{{end -}}
|
|
{{end}}
|
|
|
|
{{define "code" -}}
|
|
{{if .Play -}}
|
|
<div class="playground">{{.Text}}</div>
|
|
{{else -}}
|
|
<div class="code">{{.Text}}</div>
|
|
{{end -}}
|
|
{{end}}
|
|
|
|
{{define "image" -}}
|
|
<img src="{{.URL}}"{{with .Height}} height="{{.}}"{{end}}{{with .Width}} width="{{.}}"{{end}} alt="">
|
|
{{end}}
|
|
|
|
{{define "caption" -}}
|
|
<figcaption>{{style .Text}}</figcaption>
|
|
{{end}}
|
|
|
|
{{define "iframe" -}}
|
|
<iframe src="{{.URL}}"{{with .Height}} height="{{.}}"{{end}}{{with .Width}} width="{{.}}"{{end}}></iframe>
|
|
{{end}}
|
|
|
|
{{define "link" -}}
|
|
<p class="link"><a href="{{.URL}}">{{style .Label}}</a></p>
|
|
{{end}}
|
|
|
|
{{define "html" -}}{{.HTML}}{{end}}
|
|
`
|