tpl: Rework the partial test and benchmarks
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sat, 7 Oct 2017 14:52:35 +0000 (16:52 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sat, 7 Oct 2017 14:53:01 +0000 (16:53 +0200)
tpl/partials/init.go
tpl/partials/partials.go
tpl/tplimpl/template_funcs_test.go

index eca93783ca78a8cdc5a2a96b8894e5d4b3486b94..b68256a9a5f791637e3e8e11fb0201e720b5674d 100644 (file)
@@ -36,7 +36,7 @@ func init() {
                        },
                )
 
-               ns.AddMethodMapping(ctx.getCached,
+               ns.AddMethodMapping(ctx.IncludeCached,
                        []string{"partialCached"},
                        [][2]string{},
                )
index cf89bad37aacb7909182bf439c1c3b8f4afc409b..da131a97480c3546f9a945aece01bc9c430fe5c6 100644 (file)
@@ -88,11 +88,11 @@ func (ns *Namespace) Include(name string, contextList ...interface{}) (interface
        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
 // 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.
-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
        if len(variant) > 0 {
                for i := 0; i < len(variant); i++ {
index 04f4464ec63ebdeb110d69df22638d93e675ac58..546effdf349d2bb59344cb2385016361beb71077 100644 (file)
@@ -19,6 +19,7 @@ import (
        "path/filepath"
        "reflect"
        "testing"
+       "time"
 
        "io/ioutil"
        "log"
@@ -31,6 +32,7 @@ import (
        "github.com/gohugoio/hugo/i18n"
        "github.com/gohugoio/hugo/tpl"
        "github.com/gohugoio/hugo/tpl/internal"
+       "github.com/gohugoio/hugo/tpl/partials"
        "github.com/spf13/afero"
        jww "github.com/spf13/jwalterweatherman"
        "github.com/spf13/viper"
@@ -112,85 +114,19 @@ func TestTemplateFuncsExamples(t *testing.T) {
 // we have some package cycle issues to solve first.
 func TestPartialCached(t *testing.T) {
        t.Parallel()
-       testCases := []struct {
-               name    string
-               partial string
-               tmpl    string
-               variant string
-       }{
-               // 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 {
-               Title   string
-               Section string
-               Params  map[string]interface{}
-       }
-
-       data.Title = "**BatMan**"
-       data.Section = "blog"
-       data.Params = map[string]interface{}{"langCode": "en"}
-
-       for i, tc := range testCases {
-               var tmp string
-               if tc.variant != "" {
-                       tmp = fmt.Sprintf(tc.tmpl, tc.variant)
-               } else {
-                       tmp = tc.tmpl
-               }
 
-               config := newDepsConfig(viper.New())
+       assert := require.New(t)
 
-               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
-               }
+       partial := `Now: {{ now.UnixNano }}`
+       name := "testing"
 
-               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 {
-                       t.Fatalf("[%d] error executing template: %s", i, err)
-               }
-
-               for j := 0; j < 10; j++ {
-                       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) {
-                               t.Fatalf("[%d] cached results do not match:\nResult 1:\n%q\nResult 2:\n%q", i, buf, buf2)
-                       }
-               }
+       var data struct {
        }
-}
 
-func BenchmarkPartial(b *testing.B) {
        config := newDepsConfig(viper.New())
+
        config.WithTemplate = func(templ tpl.TemplateHandler) error {
-               err := templ.AddTemplate("testroot", `{{ partial "bench1" . }}`)
-               if err != nil {
-                       return err
-               }
-               err = templ.AddTemplate("partials/bench1", `{{ shuffle (seq 1 10) }}`)
+               err := templ.AddTemplate("partials/"+name, partial)
                if err != nil {
                        return err
                }
@@ -199,30 +135,51 @@ func BenchmarkPartial(b *testing.B) {
        }
 
        de, err := deps.New(config)
-       require.NoError(b, err)
-       require.NoError(b, de.LoadResources())
+       assert.NoError(err)
+       assert.NoError(de.LoadResources())
 
-       buf := new(bytes.Buffer)
-       tmpl := de.Tmpl.Lookup("testroot")
+       ns := partials.New(de)
 
-       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)
+       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")
                }
-               buf.Reset()
        }
+
+}
+
+func BenchmarkPartial(b *testing.B) {
+       doBenchmarkPartial(b, func(ns *partials.Namespace) error {
+               _, err := ns.Include("bench1")
+               return err
+       })
 }
 
 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.WithTemplate = func(templ tpl.TemplateHandler) error {
-               err := templ.AddTemplate("testroot", `{{ partialCached "bench1" . }}`)
-               if err != nil {
-                       return err
-               }
-               err = templ.AddTemplate("partials/bench1", `{{ shuffle (seq 1 10) }}`)
+               err := templ.AddTemplate("partials/bench1", `{{ shuffle (seq 1 10) }}`)
                if err != nil {
                        return err
                }
@@ -234,16 +191,13 @@ func BenchmarkPartialCached(b *testing.B) {
        require.NoError(b, err)
        require.NoError(b, de.LoadResources())
 
-       buf := new(bytes.Buffer)
-       tmpl := de.Tmpl.Lookup("testroot")
+       ns := partials.New(de)
 
-       b.ReportAllocs()
        b.ResetTimer()
        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)
                }
-               buf.Reset()
        }
 }