// 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" "html/template" "io/ioutil" "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 := ioutil.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).CombinedOutput() 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 } 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 := ioutil.TempFile("", 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" -}}

{{.Title}}

{{with .Subtitle}}

{{.}}

{{end -}} {{range .Authors}} {{range .Elem}}{{elem $.Template .}}{{end}} {{end -}} {{range .Sections}}
{{elem $.Template .}}
{{end -}} {{end}} {{define "newline"}}{{/* No automatic line break. Paragraphs are free-form. */}} {{end}} {{define "section"}} {{if .Title}}

{{.Title}}

{{end -}} {{range .Elem}}{{elem $.Template .}}{{end}} {{- end}} {{define "list" -}} {{end}} {{define "text" -}} {{if .Pre -}}
{{range .Lines}}{{.}}{{end}}
{{else -}}

{{range $i, $l := .Lines}}{{if $i}}{{template "newline"}}{{end}}{{style $l}}{{end}}

{{end -}} {{end}} {{define "code" -}} {{if .Play -}}
{{.Text}}
{{else -}}
{{.Text}}
{{end -}} {{end}} {{define "image" -}} {{end}} {{define "caption" -}}
{{style .Text}}
{{end}} {{define "iframe" -}} {{end}} {{define "link" -}} {{end}} {{define "html" -}}{{.HTML}}{{end}} `