mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-31 22:41:53 +02:00
tpl/collections: Unwrap any interface value in sort and where
Hugo `0.55.0` introduced some new interface types for `Page` etc. This worked great in general, but there were cases where this would fail in `where` and `sort`. One such example would be sorting by `MenuItem.Page.Date` where `Page` on `MenuItem` was a small subset of the bigger `page.Page` interface. This commit fixes that by unwrapping such interface values. Fixes #5989
This commit is contained in:
@@ -38,13 +38,31 @@ func TestWhere(t *testing.T) {
|
||||
d5 := d4.Add(1 * time.Hour)
|
||||
d6 := d5.Add(1 * time.Hour)
|
||||
|
||||
for i, test := range []struct {
|
||||
type testt struct {
|
||||
seq interface{}
|
||||
key interface{}
|
||||
op string
|
||||
match interface{}
|
||||
expect interface{}
|
||||
}{
|
||||
}
|
||||
|
||||
createTestVariants := func(test testt) []testt {
|
||||
testVariants := []testt{test}
|
||||
if islice := ToTstXIs(test.seq); islice != nil {
|
||||
variant := test
|
||||
variant.seq = islice
|
||||
expect := ToTstXIs(test.expect)
|
||||
if expect != nil {
|
||||
variant.expect = expect
|
||||
}
|
||||
testVariants = append(testVariants, variant)
|
||||
}
|
||||
|
||||
return testVariants
|
||||
|
||||
}
|
||||
|
||||
for i, test := range []testt{
|
||||
{
|
||||
seq: []map[int]string{
|
||||
{1: "a", 2: "m"}, {1: "c", 2: "d"}, {1: "e", 3: "m"},
|
||||
@@ -216,6 +234,24 @@ func TestWhere(t *testing.T) {
|
||||
{"foo": &TstX{A: "c", B: "d"}},
|
||||
},
|
||||
},
|
||||
{
|
||||
seq: []TstXIHolder{
|
||||
{&TstX{A: "a", B: "b"}}, {&TstX{A: "c", B: "d"}}, {&TstX{A: "e", B: "f"}},
|
||||
},
|
||||
key: "XI.TstRp", match: "rc",
|
||||
expect: []TstXIHolder{
|
||||
{&TstX{A: "c", B: "d"}},
|
||||
},
|
||||
},
|
||||
{
|
||||
seq: []TstXIHolder{
|
||||
{&TstX{A: "a", B: "b"}}, {&TstX{A: "c", B: "d"}}, {&TstX{A: "e", B: "f"}},
|
||||
},
|
||||
key: "XI.A", match: "e",
|
||||
expect: []TstXIHolder{
|
||||
{&TstX{A: "e", B: "f"}},
|
||||
},
|
||||
},
|
||||
{
|
||||
seq: []map[string]Mid{
|
||||
{"foo": Mid{Tst: TstX{A: "a", B: "b"}}}, {"foo": Mid{Tst: TstX{A: "c", B: "d"}}}, {"foo": Mid{Tst: TstX{A: "e", B: "f"}}},
|
||||
@@ -522,28 +558,33 @@ func TestWhere(t *testing.T) {
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(fmt.Sprintf("test case %d for key %s", i, test.key), func(t *testing.T) {
|
||||
var results interface{}
|
||||
var err error
|
||||
|
||||
if len(test.op) > 0 {
|
||||
results, err = ns.Where(test.seq, test.key, test.op, test.match)
|
||||
} else {
|
||||
results, err = ns.Where(test.seq, test.key, test.match)
|
||||
}
|
||||
if b, ok := test.expect.(bool); ok && !b {
|
||||
if err == nil {
|
||||
t.Errorf("[%d] Where didn't return an expected error", i)
|
||||
testVariants := createTestVariants(test)
|
||||
for j, test := range testVariants {
|
||||
name := fmt.Sprintf("[%d/%d] %T %s %s", i, j, test.seq, test.op, test.key)
|
||||
t.Run(name, func(t *testing.T) {
|
||||
var results interface{}
|
||||
var err error
|
||||
|
||||
if len(test.op) > 0 {
|
||||
results, err = ns.Where(test.seq, test.key, test.op, test.match)
|
||||
} else {
|
||||
results, err = ns.Where(test.seq, test.key, test.match)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("[%d] failed: %s", i, err)
|
||||
if b, ok := test.expect.(bool); ok && !b {
|
||||
if err == nil {
|
||||
t.Fatalf("[%d] Where didn't return an expected error", i)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Fatalf("[%d] failed: %s", i, err)
|
||||
}
|
||||
if !reflect.DeepEqual(results, test.expect) {
|
||||
t.Fatalf("Where clause matching %v with %v in seq %v (%T),\ngot\n%v (%T) but expected\n%v (%T)", test.key, test.match, test.seq, test.seq, results, results, test.expect, test.expect)
|
||||
}
|
||||
}
|
||||
if !reflect.DeepEqual(results, test.expect) {
|
||||
t.Errorf("[%d] Where clause matching %v with %v, got %v but expected %v", i, test.key, test.match, results, test.expect)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
|
Reference in New Issue
Block a user