mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
Pull in latest Go template source
This commit is contained in:
parent
21e9eb18ac
commit
ccb822eb5a
11 changed files with 157 additions and 20 deletions
|
@ -18,7 +18,7 @@ import (
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// TODO(bep) git checkout tag
|
// TODO(bep) git checkout tag
|
||||||
// The current is built with Go version da54dfb6a1f3bef827b9ec3780c98fde77a97d11 / go1.16dev
|
// The current is built with Go version c8bd8010ff7c0115bf186443119216ba51f09d2b / go1.16dev
|
||||||
fmt.Println("Forking ...")
|
fmt.Println("Forking ...")
|
||||||
defer fmt.Println("Done ...")
|
defer fmt.Println("Done ...")
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ package template_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -23,7 +22,7 @@ type templateFile struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTestDir(files []templateFile) string {
|
func createTestDir(files []templateFile) string {
|
||||||
dir, err := ioutil.TempDir("", "template")
|
dir, err := os.MkdirTemp("", "template")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,11 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
htmltemplate "html/template"
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
template "github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate"
|
template "github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate"
|
||||||
|
@ -1709,3 +1711,127 @@ func TestIssue31810(t *testing.T) {
|
||||||
t.Errorf("%s got %q, expected %q", textCall, b.String(), "result")
|
t.Errorf("%s got %q, expected %q", textCall, b.String(), "result")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue 39807. There was a race applying escapeTemplate.
|
||||||
|
|
||||||
|
const raceText = `
|
||||||
|
{{- define "jstempl" -}}
|
||||||
|
var v = "v";
|
||||||
|
{{- end -}}
|
||||||
|
<script type="application/javascript">
|
||||||
|
{{ template "jstempl" $ }}
|
||||||
|
</script>
|
||||||
|
`
|
||||||
|
|
||||||
|
func TestEscapeRace(t *testing.T) {
|
||||||
|
t.Skip("this test currently fails with -race; see issue #39807")
|
||||||
|
|
||||||
|
tmpl := New("")
|
||||||
|
_, err := tmpl.New("templ.html").Parse(raceText)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
const count = 20
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
_, err := tmpl.New(fmt.Sprintf("x%d.html", i)).Parse(`{{ template "templ.html" .}}`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
for j := 0; j < count; j++ {
|
||||||
|
sub := tmpl.Lookup(fmt.Sprintf("x%d.html", j))
|
||||||
|
if err := sub.Execute(io.Discard, nil); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRecursiveExecute(t *testing.T) {
|
||||||
|
tmpl := New("")
|
||||||
|
|
||||||
|
recur := func() (htmltemplate.HTML, error) {
|
||||||
|
var sb strings.Builder
|
||||||
|
if err := tmpl.ExecuteTemplate(&sb, "subroutine", nil); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
return htmltemplate.HTML(sb.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
m := FuncMap{
|
||||||
|
"recur": recur,
|
||||||
|
}
|
||||||
|
|
||||||
|
top, err := tmpl.New("x.html").Funcs(m).Parse(`{{recur}}`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, err = tmpl.New("subroutine").Parse(`<a href="/x?p={{"'a<b'"}}">`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := top.Execute(io.Discard, nil); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// recursiveInvoker is for TestRecursiveExecuteViaMethod.
|
||||||
|
type recursiveInvoker struct {
|
||||||
|
t *testing.T
|
||||||
|
tmpl *Template
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *recursiveInvoker) Recur() (string, error) {
|
||||||
|
var sb strings.Builder
|
||||||
|
if err := r.tmpl.ExecuteTemplate(&sb, "subroutine", nil); err != nil {
|
||||||
|
r.t.Fatal(err)
|
||||||
|
}
|
||||||
|
return sb.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRecursiveExecuteViaMethod(t *testing.T) {
|
||||||
|
tmpl := New("")
|
||||||
|
top, err := tmpl.New("x.html").Parse(`{{.Recur}}`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, err = tmpl.New("subroutine").Parse(`<a href="/x?p={{"'a<b'"}}">`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
r := &recursiveInvoker{
|
||||||
|
t: t,
|
||||||
|
tmpl: tmpl,
|
||||||
|
}
|
||||||
|
if err := top.Execute(io.Discard, r); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Issue 43295.
|
||||||
|
func TestTemplateFuncsAfterClone(t *testing.T) {
|
||||||
|
s := `{{ f . }}`
|
||||||
|
want := "test"
|
||||||
|
orig := New("orig").Funcs(map[string]interface{}{
|
||||||
|
"f": func(in string) string {
|
||||||
|
return in
|
||||||
|
},
|
||||||
|
}).New("child")
|
||||||
|
|
||||||
|
overviewTmpl := Must(Must(orig.Clone()).Parse(s))
|
||||||
|
var out strings.Builder
|
||||||
|
if err := overviewTmpl.Execute(&out, want); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if got := out.String(); got != want {
|
||||||
|
t.Fatalf("got %q; want %q", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"io/ioutil"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -524,7 +524,7 @@ func parseFS(t *Template, fsys fs.FS, patterns []string) (*Template, error) {
|
||||||
|
|
||||||
func readFileOS(file string) (name string, b []byte, err error) {
|
func readFileOS(file string) (name string, b []byte, err error) {
|
||||||
name = filepath.Base(file)
|
name = filepath.Base(file)
|
||||||
b, err = ioutil.ReadFile(file)
|
b, err = os.ReadFile(file)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ package testenv
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
|
"github.com/gohugoio/hugo/tpl/internal/go_templates/cfg"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -21,9 +22,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/cli/safeexec"
|
|
||||||
"github.com/gohugoio/hugo/tpl/internal/go_templates/cfg"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Builder reports the name of the builder running this test
|
// Builder reports the name of the builder running this test
|
||||||
|
@ -109,7 +107,7 @@ func GoTool() (string, error) {
|
||||||
if _, err := os.Stat(path); err == nil {
|
if _, err := os.Stat(path); err == nil {
|
||||||
return path, nil
|
return path, nil
|
||||||
}
|
}
|
||||||
goBin, err := safeexec.LookPath("go" + exeSuffix)
|
goBin, err := exec.LookPath("go" + exeSuffix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New("cannot find go tool: " + err.Error())
|
return "", errors.New("cannot find go tool: " + err.Error())
|
||||||
}
|
}
|
||||||
|
@ -154,7 +152,7 @@ func MustHaveExecPath(t testing.TB, path string) {
|
||||||
|
|
||||||
err, found := execPaths.Load(path)
|
err, found := execPaths.Load(path)
|
||||||
if !found {
|
if !found {
|
||||||
_, err = safeexec.LookPath(path)
|
_, err = exec.LookPath(path)
|
||||||
err, _ = execPaths.LoadOrStore(path, err)
|
err, _ = execPaths.LoadOrStore(path, err)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
package testenv
|
package testenv
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -16,7 +15,7 @@ var symlinkOnce sync.Once
|
||||||
var winSymlinkErr error
|
var winSymlinkErr error
|
||||||
|
|
||||||
func initWinHasSymlink() {
|
func initWinHasSymlink() {
|
||||||
tmpdir, err := ioutil.TempDir("", "symtest")
|
tmpdir, err := os.MkdirTemp("", "symtest")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("failed to create temp directory: " + err.Error())
|
panic("failed to create temp directory: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ package template_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -22,7 +21,7 @@ type templateFile struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTestDir(files []templateFile) string {
|
func createTestDir(files []templateFile) string {
|
||||||
dir, err := ioutil.TempDir("", "template")
|
dir, err := os.MkdirTemp("", "template")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -373,6 +373,10 @@ func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) {
|
||||||
if val.IsNil() {
|
if val.IsNil() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if val.Type().ChanDir() == reflect.SendDir {
|
||||||
|
s.errorf("range over send-only channel %v", val)
|
||||||
|
break
|
||||||
|
}
|
||||||
i := 0
|
i := 0
|
||||||
for ; ; i++ {
|
for ; ; i++ {
|
||||||
elem, ok := val.Recv()
|
elem, ok := val.Recv()
|
||||||
|
|
|
@ -1699,3 +1699,16 @@ func TestIssue31810(t *testing.T) {
|
||||||
t.Errorf("%s got %q, expected %q", textCall, b.String(), "result")
|
t.Errorf("%s got %q, expected %q", textCall, b.String(), "result")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue 43065, range over send only channel
|
||||||
|
func TestIssue43065(t *testing.T) {
|
||||||
|
var b bytes.Buffer
|
||||||
|
tmp := Must(New("").Parse(`{{range .}}{{end}}`))
|
||||||
|
ch := make(chan<- int)
|
||||||
|
err := tmp.Execute(&b, ch)
|
||||||
|
if err == nil {
|
||||||
|
t.Error("expected err got nil")
|
||||||
|
} else if !strings.Contains(err.Error(), "range over send-only channel") {
|
||||||
|
t.Errorf("%s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ package template
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"io/ioutil"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
@ -164,7 +164,7 @@ func parseFS(t *Template, fsys fs.FS, patterns []string) (*Template, error) {
|
||||||
|
|
||||||
func readFileOS(file string) (name string, b []byte, err error) {
|
func readFileOS(file string) (name string, b []byte, err error) {
|
||||||
name = filepath.Base(file)
|
name = filepath.Base(file)
|
||||||
b, err = ioutil.ReadFile(file)
|
b, err = os.ReadFile(file)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ package template_test
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"github.com/gohugoio/hugo/tpl/internal/go_templates/testenv"
|
"github.com/gohugoio/hugo/tpl/internal/go_templates/testenv"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -42,13 +41,13 @@ func main() {
|
||||||
t.Used()
|
t.Used()
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
td, err := ioutil.TempDir("", "text_template_TestDeadCodeElimination")
|
td, err := os.MkdirTemp("", "text_template_TestDeadCodeElimination")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
defer os.RemoveAll(td)
|
defer os.RemoveAll(td)
|
||||||
|
|
||||||
if err := ioutil.WriteFile(filepath.Join(td, "x.go"), []byte(prog), 0644); err != nil {
|
if err := os.WriteFile(filepath.Join(td, "x.go"), []byte(prog), 0644); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "x.exe", "x.go")
|
cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", "x.exe", "x.go")
|
||||||
|
@ -56,7 +55,7 @@ func main() {
|
||||||
if out, err := cmd.CombinedOutput(); err != nil {
|
if out, err := cmd.CombinedOutput(); err != nil {
|
||||||
t.Fatalf("go build: %v, %s", err, out)
|
t.Fatalf("go build: %v, %s", err, out)
|
||||||
}
|
}
|
||||||
slurp, err := ioutil.ReadFile(filepath.Join(td, "x.exe"))
|
slurp, err := os.ReadFile(filepath.Join(td, "x.exe"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue