2024-09-18 16:15:01 +00:00
|
|
|
package walk
|
|
|
|
|
|
|
|
import (
|
2024-09-20 17:56:28 +00:00
|
|
|
"reflect"
|
2024-09-18 16:15:01 +00:00
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
2024-09-20 18:27:53 +00:00
|
|
|
type Profile struct {
|
|
|
|
Age int
|
|
|
|
City string
|
|
|
|
}
|
|
|
|
|
2024-09-20 18:19:49 +00:00
|
|
|
type Person struct {
|
|
|
|
Name string
|
2024-09-20 18:27:53 +00:00
|
|
|
Profile Profile
|
2024-09-20 18:19:49 +00:00
|
|
|
}
|
|
|
|
|
2024-09-18 16:15:01 +00:00
|
|
|
func TestWalk(t *testing.T) {
|
2024-09-20 17:56:28 +00:00
|
|
|
cases := []struct {
|
|
|
|
Name string
|
|
|
|
Input interface{}
|
|
|
|
ExpectedCalls []string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"struct with one string field",
|
|
|
|
struct {
|
|
|
|
Name string
|
|
|
|
}{"Chris"},
|
|
|
|
[]string{"Chris"},
|
|
|
|
},
|
2024-09-20 17:59:39 +00:00
|
|
|
{
|
|
|
|
"struct with two string fields",
|
|
|
|
struct {
|
|
|
|
Name string
|
|
|
|
City string
|
|
|
|
}{"Chris", "London"},
|
|
|
|
[]string{"Chris", "London"},
|
|
|
|
},
|
2024-09-20 18:05:32 +00:00
|
|
|
{
|
|
|
|
"struct with non string field",
|
|
|
|
struct {
|
|
|
|
Name string
|
|
|
|
Age int
|
|
|
|
}{"Chris", 29},
|
|
|
|
[]string{"Chris"},
|
|
|
|
},
|
2024-09-20 18:15:59 +00:00
|
|
|
{
|
|
|
|
"nested fields",
|
2024-09-20 18:27:53 +00:00
|
|
|
Person{"Chris", Profile{29, "London"}},
|
2024-09-20 18:19:49 +00:00
|
|
|
[]string{"Chris", "London"},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"pointer to things",
|
2024-09-20 18:27:53 +00:00
|
|
|
&Person{"Chris", Profile{29, "London"}},
|
2024-09-20 18:15:59 +00:00
|
|
|
[]string{"Chris", "London"},
|
|
|
|
},
|
2024-09-20 18:27:53 +00:00
|
|
|
{
|
|
|
|
"slices",
|
|
|
|
[]Profile{
|
|
|
|
{29, "London"},
|
|
|
|
{33, "Paris"},
|
|
|
|
},
|
|
|
|
[]string{"London", "Paris"},
|
|
|
|
},
|
2024-09-20 18:37:54 +00:00
|
|
|
{
|
|
|
|
"arrays",
|
|
|
|
[2]Profile{
|
|
|
|
{29, "London"},
|
|
|
|
{33, "Paris"},
|
|
|
|
},
|
|
|
|
[]string{"London", "Paris"},
|
|
|
|
},
|
2024-09-20 17:56:28 +00:00
|
|
|
}
|
2024-09-18 16:15:01 +00:00
|
|
|
|
2024-09-20 17:56:28 +00:00
|
|
|
for _, test := range cases {
|
|
|
|
t.Run(test.Name, func(t *testing.T) {
|
|
|
|
var got []string
|
|
|
|
Walk(test.Input, func(input string) {
|
|
|
|
got = append(got, input)
|
|
|
|
})
|
2024-09-18 16:15:01 +00:00
|
|
|
|
2024-09-20 17:56:28 +00:00
|
|
|
if !reflect.DeepEqual(got, test.ExpectedCalls) {
|
|
|
|
t.Errorf("got %v want %v", got, test.ExpectedCalls)
|
|
|
|
}
|
2024-09-18 16:15:01 +00:00
|
|
|
})
|
2024-09-20 17:56:28 +00:00
|
|
|
}
|
2024-09-20 18:51:44 +00:00
|
|
|
|
|
|
|
t.Run("with maps", func(t *testing.T) {
|
|
|
|
aMap := map[string]string{
|
|
|
|
"Cow": "meuh",
|
|
|
|
"Sheep": "meh",
|
|
|
|
}
|
|
|
|
var got []string
|
|
|
|
Walk(aMap, func(input string) {
|
|
|
|
got = append(got, input)
|
|
|
|
})
|
|
|
|
|
|
|
|
assertContains(t, got, "meuh")
|
|
|
|
assertContains(t, got, "meh")
|
|
|
|
})
|
2024-09-20 19:00:47 +00:00
|
|
|
|
|
|
|
t.Run("with channels", func(t *testing.T) {
|
|
|
|
aChannel := make(chan Profile)
|
|
|
|
go func() {
|
|
|
|
aChannel <- Profile{21, "Berlin"}
|
|
|
|
aChannel <- Profile{28, "Beijing"}
|
|
|
|
close(aChannel)
|
|
|
|
}()
|
|
|
|
var got []string
|
|
|
|
want := []string{"Berlin", "Beijing"}
|
|
|
|
Walk(aChannel, func(input string) {
|
|
|
|
got = append(got, input)
|
|
|
|
})
|
|
|
|
if !reflect.DeepEqual(got, want) {
|
|
|
|
t.Errorf("got %v want %v", got, want)
|
|
|
|
}
|
|
|
|
})
|
2024-09-20 19:04:25 +00:00
|
|
|
|
|
|
|
t.Run("with functions", func(t *testing.T) {
|
|
|
|
aFunction := func() (Profile, Profile) {
|
|
|
|
return Profile{21, "Berlin"}, Profile{28, "Beijing"}
|
|
|
|
}
|
|
|
|
|
|
|
|
var got []string
|
|
|
|
want := []string{"Berlin", "Beijing"}
|
|
|
|
Walk(aFunction, func(input string) {
|
|
|
|
got = append(got, input)
|
|
|
|
})
|
|
|
|
if !reflect.DeepEqual(got, want) {
|
|
|
|
t.Errorf("got %v want %v", got, want)
|
|
|
|
}
|
|
|
|
})
|
2024-09-20 18:51:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func assertContains(t testing.TB, haystack []string, needle string) {
|
|
|
|
t.Helper()
|
|
|
|
contains := false
|
|
|
|
|
|
|
|
for _, x := range haystack {
|
|
|
|
if x == needle {
|
|
|
|
contains = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !contains {
|
|
|
|
t.Errorf("expected %v to contain %q but it didn't", haystack, needle)
|
|
|
|
}
|
2024-09-18 16:15:01 +00:00
|
|
|
}
|