URI: 
       tpl/collections: Fix append when appending a slice to a slice of slices - hugo - [fork] hugo port for 9front
  HTML git clone git@git.drkhsh.at/hugo.git
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
   DIR commit d178fe94fe26ce2cf8096f330f3d160af3ec818d
   DIR parent 732dcb848f6455ad8f1d5ec2351257015c87eec7
  HTML Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
       Date:   Wed, 14 Jun 2023 09:00:28 +0200
       
       tpl/collections: Fix append when appending a slice to a slice of slices
       
       Fixes #11093
       
       Diffstat:
         M common/collections/append.go        |      29 +++++++++++++++++++++++++++--
         M common/collections/append_test.go   |      45 +++++++++++++++++++++++++++++--
         M tpl/collections/integration_test.go |      31 +++++++++++++++++++++++++++++++
       
       3 files changed, 101 insertions(+), 4 deletions(-)
       ---
   DIR diff --git a/common/collections/append.go b/common/collections/append.go
       @@ -22,6 +22,9 @@ import (
        // If length of from is one and the only element is a slice of same type as to,
        // it will be appended.
        func Append(to any, from ...any) (any, error) {
       +        if len(from) == 0 {
       +                return to, nil
       +        }
                tov, toIsNil := indirect(reflect.ValueOf(to))
        
                toIsNil = toIsNil || to == nil
       @@ -33,18 +36,39 @@ func Append(to any, from ...any) (any, error) {
                        }
        
                        tot = tov.Type().Elem()
       +                if tot.Kind() == reflect.Slice {
       +                        totvt := tot.Elem()
       +                        fromvs := make([]reflect.Value, len(from))
       +                        for i, f := range from {
       +                                fromv := reflect.ValueOf(f)
       +                                fromt := fromv.Type()
       +                                if fromt.Kind() == reflect.Slice {
       +                                        fromt = fromt.Elem()
       +                                }
       +                                if totvt != fromt {
       +                                        return nil, fmt.Errorf("cannot append slice of %s to slice of %s", fromt, totvt)
       +                                } else {
       +                                        fromvs[i] = fromv
       +                                }
       +                        }
       +                        return reflect.Append(tov, fromvs...).Interface(), nil
       +
       +                }
       +
                        toIsNil = tov.Len() == 0
        
                        if len(from) == 1 {
                                fromv := reflect.ValueOf(from[0])
       +                        fromt := fromv.Type()
       +                        if fromt.Kind() == reflect.Slice {
       +                                fromt = fromt.Elem()
       +                        }
                                if fromv.Kind() == reflect.Slice {
                                        if toIsNil {
                                                // If we get nil []string, we just return the []string
                                                return from[0], nil
                                        }
        
       -                                fromt := reflect.TypeOf(from[0]).Elem()
       -
                                        // If we get []string []string, we append the from slice to to
                                        if tot == fromt {
                                                return reflect.AppendSlice(tov, fromv).Interface(), nil
       @@ -52,6 +76,7 @@ func Append(to any, from ...any) (any, error) {
                                                // Fall back to a []interface{} slice.
                                                return appendToInterfaceSliceFromValues(tov, fromv)
                                        }
       +
                                }
                        }
                }
   DIR diff --git a/common/collections/append_test.go b/common/collections/append_test.go
       @@ -24,7 +24,7 @@ func TestAppend(t *testing.T) {
                t.Parallel()
                c := qt.New(t)
        
       -        for _, test := range []struct {
       +        for i, test := range []struct {
                        start    any
                        addend   []any
                        expected any
       @@ -85,6 +85,47 @@ func TestAppend(t *testing.T) {
                        }
        
                        c.Assert(err, qt.IsNil)
       -                c.Assert(result, qt.DeepEquals, test.expected)
       +                c.Assert(result, qt.DeepEquals, test.expected, qt.Commentf("test: [%d] %v", i, test))
                }
        }
       +
       +// #11093
       +func TestAppendToMultiDimensionalSlice(t *testing.T) {
       +        t.Parallel()
       +        c := qt.New(t)
       +
       +        for _, test := range []struct {
       +                to       any
       +                from     []any
       +                expected any
       +        }{
       +                {[][]string{{"a", "b"}},
       +                        []any{[]string{"c", "d"}},
       +                        [][]string{
       +                                {"a", "b"},
       +                                {"c", "d"},
       +                        },
       +                },
       +                {[][]string{{"a", "b"}},
       +                        []any{[]string{"c", "d"}, []string{"e", "f"}},
       +                        [][]string{
       +                                {"a", "b"},
       +                                {"c", "d"},
       +                                {"e", "f"},
       +                        },
       +                },
       +                {[][]string{{"a", "b"}},
       +                        []any{[]int{1, 2}},
       +                        false,
       +                },
       +        } {
       +                result, err := Append(test.to, test.from...)
       +                if b, ok := test.expected.(bool); ok && !b {
       +                        c.Assert(err, qt.Not(qt.IsNil))
       +                } else {
       +                        c.Assert(err, qt.IsNil)
       +                        c.Assert(result, qt.DeepEquals, test.expected)
       +                }
       +        }
       +
       +}
   DIR diff --git a/tpl/collections/integration_test.go b/tpl/collections/integration_test.go
       @@ -73,3 +73,34 @@ Desc: [map[a:3 b:3] map[a:3 b:1] map[a:3 b:1] map[a:3 b:1] map[a:3 b:0] map[a:3 
        
                }
        }
       +
       +// Issue #11004.
       +func TestAppendSliceToASliceOfSlices(t *testing.T) {
       +        t.Parallel()
       +
       +        files := `
       +-- hugo.toml --
       +-- layouts/index.html --
       +{{ $obj := slice (slice "a") }}
       +{{ $obj = $obj | append (slice "b") }}
       +{{ $obj = $obj | append (slice "c") }}
       +
       +{{ $obj }}
       +
       +
       +  `
       +
       +        for i := 0; i < 4; i++ {
       +
       +                b := hugolib.NewIntegrationTestBuilder(
       +                        hugolib.IntegrationTestConfig{
       +                                T:           t,
       +                                TxtarString: files,
       +                        },
       +                ).Build()
       +
       +                b.AssertFileContent("public/index.html", "[[a] [b] [c]]")
       +
       +        }
       +
       +}