mirror of
https://github.com/gohugoio/hugo.git
synced 2025-04-14 22:25:05 +00:00
tpl: Rework the partial test and benchmarks
This commit is contained in:
parent
66a169a249
commit
e2e8bcbec3
3 changed files with 54 additions and 100 deletions
|
@ -36,7 +36,7 @@ func init() {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
ns.AddMethodMapping(ctx.getCached,
|
ns.AddMethodMapping(ctx.IncludeCached,
|
||||||
[]string{"partialCached"},
|
[]string{"partialCached"},
|
||||||
[][2]string{},
|
[][2]string{},
|
||||||
)
|
)
|
||||||
|
|
|
@ -88,11 +88,11 @@ func (ns *Namespace) Include(name string, contextList ...interface{}) (interface
|
||||||
return "", fmt.Errorf("Partial %q not found", name)
|
return "", fmt.Errorf("Partial %q not found", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getCached executes and caches partial templates. An optional variant
|
// IncludeCached executes and caches partial templates. An optional variant
|
||||||
// string parameter (a string slice actually, but be only use a variadic
|
// string parameter (a string slice actually, but be only use a variadic
|
||||||
// argument to make it optional) can be passed so that a given partial can have
|
// argument to make it optional) can be passed so that a given partial can have
|
||||||
// multiple uses. The cache is created with name+variant as the key.
|
// multiple uses. The cache is created with name+variant as the key.
|
||||||
func (ns *Namespace) getCached(name string, context interface{}, variant ...string) (interface{}, error) {
|
func (ns *Namespace) IncludeCached(name string, context interface{}, variant ...string) (interface{}, error) {
|
||||||
key := name
|
key := name
|
||||||
if len(variant) > 0 {
|
if len(variant) > 0 {
|
||||||
for i := 0; i < len(variant); i++ {
|
for i := 0; i < len(variant); i++ {
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
@ -31,6 +32,7 @@ import (
|
||||||
"github.com/gohugoio/hugo/i18n"
|
"github.com/gohugoio/hugo/i18n"
|
||||||
"github.com/gohugoio/hugo/tpl"
|
"github.com/gohugoio/hugo/tpl"
|
||||||
"github.com/gohugoio/hugo/tpl/internal"
|
"github.com/gohugoio/hugo/tpl/internal"
|
||||||
|
"github.com/gohugoio/hugo/tpl/partials"
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
jww "github.com/spf13/jwalterweatherman"
|
jww "github.com/spf13/jwalterweatherman"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
@ -112,117 +114,72 @@ func TestTemplateFuncsExamples(t *testing.T) {
|
||||||
// we have some package cycle issues to solve first.
|
// we have some package cycle issues to solve first.
|
||||||
func TestPartialCached(t *testing.T) {
|
func TestPartialCached(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
testCases := []struct {
|
|
||||||
name string
|
assert := require.New(t)
|
||||||
partial string
|
|
||||||
tmpl string
|
partial := `Now: {{ now.UnixNano }}`
|
||||||
variant string
|
name := "testing"
|
||||||
}{
|
|
||||||
// name and partial should match between test cases.
|
|
||||||
{"test1", "{{ .Title }} seq: {{ shuffle (seq 1 20) }}", `{{ partialCached "test1" . }}`, ""},
|
|
||||||
{"test1", "{{ .Title }} seq: {{ shuffle (seq 1 20) }}", `{{ partialCached "test1" . "%s" }}`, "header"},
|
|
||||||
{"test1", "{{ .Title }} seq: {{ shuffle (seq 1 20) }}", `{{ partialCached "test1" . "%s" }}`, "footer"},
|
|
||||||
{"test1", "{{ .Title }} seq: {{ shuffle (seq 1 20) }}", `{{ partialCached "test1" . "%s" }}`, "header"},
|
|
||||||
}
|
|
||||||
|
|
||||||
var data struct {
|
var data struct {
|
||||||
Title string
|
|
||||||
Section string
|
|
||||||
Params map[string]interface{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data.Title = "**BatMan**"
|
config := newDepsConfig(viper.New())
|
||||||
data.Section = "blog"
|
|
||||||
data.Params = map[string]interface{}{"langCode": "en"}
|
|
||||||
|
|
||||||
for i, tc := range testCases {
|
config.WithTemplate = func(templ tpl.TemplateHandler) error {
|
||||||
var tmp string
|
err := templ.AddTemplate("partials/"+name, partial)
|
||||||
if tc.variant != "" {
|
|
||||||
tmp = fmt.Sprintf(tc.tmpl, tc.variant)
|
|
||||||
} else {
|
|
||||||
tmp = tc.tmpl
|
|
||||||
}
|
|
||||||
|
|
||||||
config := newDepsConfig(viper.New())
|
|
||||||
|
|
||||||
config.WithTemplate = func(templ tpl.TemplateHandler) error {
|
|
||||||
err := templ.AddTemplate("testroot", tmp)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = templ.AddTemplate("partials/"+tc.name, tc.partial)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
de, err := deps.New(config)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NoError(t, de.LoadResources())
|
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
templ := de.Tmpl.Lookup("testroot")
|
|
||||||
err = templ.Execute(buf, &data)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("[%d] error executing template: %s", i, err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for j := 0; j < 10; j++ {
|
return nil
|
||||||
buf2 := new(bytes.Buffer)
|
}
|
||||||
err := templ.Execute(buf2, nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("[%d] error executing template 2nd time: %s", i, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(buf, buf2) {
|
de, err := deps.New(config)
|
||||||
t.Fatalf("[%d] cached results do not match:\nResult 1:\n%q\nResult 2:\n%q", i, buf, buf2)
|
assert.NoError(err)
|
||||||
}
|
assert.NoError(de.LoadResources())
|
||||||
|
|
||||||
|
ns := partials.New(de)
|
||||||
|
|
||||||
|
res1, err := ns.IncludeCached(name, &data)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
for j := 0; j < 10; j++ {
|
||||||
|
time.Sleep(2 * time.Nanosecond)
|
||||||
|
res2, err := ns.IncludeCached(name, &data)
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(res1, res2) {
|
||||||
|
t.Fatalf("cache mismatch")
|
||||||
|
}
|
||||||
|
|
||||||
|
res3, err := ns.IncludeCached(name, &data, fmt.Sprintf("variant%d", j))
|
||||||
|
assert.NoError(err)
|
||||||
|
|
||||||
|
if reflect.DeepEqual(res1, res3) {
|
||||||
|
t.Fatalf("cache mismatch")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkPartial(b *testing.B) {
|
func BenchmarkPartial(b *testing.B) {
|
||||||
config := newDepsConfig(viper.New())
|
doBenchmarkPartial(b, func(ns *partials.Namespace) error {
|
||||||
config.WithTemplate = func(templ tpl.TemplateHandler) error {
|
_, err := ns.Include("bench1")
|
||||||
err := templ.AddTemplate("testroot", `{{ partial "bench1" . }}`)
|
return err
|
||||||
if err != nil {
|
})
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = templ.AddTemplate("partials/bench1", `{{ shuffle (seq 1 10) }}`)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
de, err := deps.New(config)
|
|
||||||
require.NoError(b, err)
|
|
||||||
require.NoError(b, de.LoadResources())
|
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
tmpl := de.Tmpl.Lookup("testroot")
|
|
||||||
|
|
||||||
b.ReportAllocs()
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
if err := tmpl.Execute(buf, nil); err != nil {
|
|
||||||
b.Fatalf("error executing template: %s", err)
|
|
||||||
}
|
|
||||||
buf.Reset()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkPartialCached(b *testing.B) {
|
func BenchmarkPartialCached(b *testing.B) {
|
||||||
|
doBenchmarkPartial(b, func(ns *partials.Namespace) error {
|
||||||
|
_, err := ns.IncludeCached("bench1", nil)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func doBenchmarkPartial(b *testing.B, f func(ns *partials.Namespace) error) {
|
||||||
config := newDepsConfig(viper.New())
|
config := newDepsConfig(viper.New())
|
||||||
config.WithTemplate = func(templ tpl.TemplateHandler) error {
|
config.WithTemplate = func(templ tpl.TemplateHandler) error {
|
||||||
err := templ.AddTemplate("testroot", `{{ partialCached "bench1" . }}`)
|
err := templ.AddTemplate("partials/bench1", `{{ shuffle (seq 1 10) }}`)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = templ.AddTemplate("partials/bench1", `{{ shuffle (seq 1 10) }}`)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -234,16 +191,13 @@ func BenchmarkPartialCached(b *testing.B) {
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
require.NoError(b, de.LoadResources())
|
require.NoError(b, de.LoadResources())
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
ns := partials.New(de)
|
||||||
tmpl := de.Tmpl.Lookup("testroot")
|
|
||||||
|
|
||||||
b.ReportAllocs()
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
if err := tmpl.Execute(buf, nil); err != nil {
|
if err := f(ns); err != nil {
|
||||||
b.Fatalf("error executing template: %s", err)
|
b.Fatalf("error executing template: %s", err)
|
||||||
}
|
}
|
||||||
buf.Reset()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue