From b74b8d6478c7ad68c8f3fec6597b336f55ea0a94 Mon Sep 17 00:00:00 2001 From: khayyam Date: Wed, 28 Jun 2023 03:41:36 -0400 Subject: [PATCH] common/collections: Fix append regression to allow appending nil Closes #11180 --- common/collections/append.go | 10 ++++- common/collections/append_test.go | 3 ++ tpl/collections/integration_test.go | 60 +++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/common/collections/append.go b/common/collections/append.go index 91abc46d348..8f1e21ea315 100644 --- a/common/collections/append.go +++ b/common/collections/append.go @@ -66,6 +66,10 @@ func Append(to any, from ...any) (any, error) { if len(from) == 1 { fromv := reflect.ValueOf(from[0]) + if !fromv.IsValid() { + // from[0] is nil + return appendToInterfaceSliceFromValues(tov, fromv) + } fromt := fromv.Type() if fromt.Kind() == reflect.Slice { fromt = fromt.Elem() @@ -94,7 +98,7 @@ func Append(to any, from ...any) (any, error) { for _, f := range from { fv := reflect.ValueOf(f) - if !fv.Type().AssignableTo(tot) { + if !fv.IsValid() || !fv.Type().AssignableTo(tot) { // Fall back to a []interface{} slice. tov, _ := indirect(reflect.ValueOf(to)) return appendToInterfaceSlice(tov, from...) @@ -109,6 +113,10 @@ func appendToInterfaceSliceFromValues(slice1, slice2 reflect.Value) ([]any, erro var tos []any for _, slice := range []reflect.Value{slice1, slice2} { + if !slice.IsValid() { + tos = append(tos, nil) + continue + } for i := 0; i < slice.Len(); i++ { tos = append(tos, slice.Index(i).Interface()) } diff --git a/common/collections/append_test.go b/common/collections/append_test.go index 415eb2f257e..3c2aab2db99 100644 --- a/common/collections/append_test.go +++ b/common/collections/append_test.go @@ -74,6 +74,9 @@ func TestAppend(t *testing.T) { []any{"c"}, false, }, + {[]string{"a", "b"}, []any{nil}, []any{"a", "b", nil}}, + {[]string{"a", "b"}, []any{nil, "d", nil}, []any{"a", "b", nil, "d", nil}}, + {[]any{"a", nil, "c"}, []any{"d", nil, "f"}, []any{"a", nil, "c", "d", nil, "f"}}, } { result, err := Append(test.start, test.addend...) diff --git a/tpl/collections/integration_test.go b/tpl/collections/integration_test.go index da1d6e488a6..829aee355b4 100644 --- a/tpl/collections/integration_test.go +++ b/tpl/collections/integration_test.go @@ -104,3 +104,63 @@ func TestAppendSliceToASliceOfSlices(t *testing.T) { } } + +func TestAppendNilToSlice(t *testing.T) { + + t.Parallel() + + files := ` +-- hugo.toml -- +-- layouts/index.html -- +{{ $obj := (slice "a") }} +{{ $obj = $obj | append nil }} + +{{ $obj }} + + + ` + + for i := 0; i < 4; i++ { + + b := hugolib.NewIntegrationTestBuilder( + hugolib.IntegrationTestConfig{ + T: t, + TxtarString: files, + }, + ).Build() + + b.AssertFileContent("public/index.html", "[a <nil>]") + + } + +} + +func TestAppendNilsToSliceWithNils(t *testing.T) { + + t.Parallel() + + files := ` +-- hugo.toml -- +-- layouts/index.html -- +{{ $obj := (slice "a" nil "c") }} +{{ $obj = $obj | append nil }} + +{{ $obj }} + + + ` + + for i := 0; i < 4; i++ { + + b := hugolib.NewIntegrationTestBuilder( + hugolib.IntegrationTestConfig{ + T: t, + TxtarString: files, + }, + ).Build() + + b.AssertFileContent("public/index.html", "[a <nil> c <nil>]") + + } + +}