From 66268fe5e6a556e953982575bce89988a1908d4e Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 10:03:43 -0300 Subject: [PATCH 01/28] test for walk func --- reflection/reflection_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 reflection/reflection_test.go diff --git a/reflection/reflection_test.go b/reflection/reflection_test.go new file mode 100644 index 0000000..2c3442c --- /dev/null +++ b/reflection/reflection_test.go @@ -0,0 +1,20 @@ +package reflection + +import "testing" + +func TestWalk(t *testing.T) { + expected := "Chris" + var got []string + + x := struct { + Name string + }{expected} + + walk(x, func(input string) { + got = append(got, input) + }) + + if len(got) != 1 { + t.Errorf("wrong number of function calls, got %d want %d", len(got), 1) + } +} From 7bfc165d69bd6f23de242439347c433997f75013 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 10:07:52 -0300 Subject: [PATCH 02/28] implementing walk code e make the tests pass --- reflection/reflection.go | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 reflection/reflection.go diff --git a/reflection/reflection.go b/reflection/reflection.go new file mode 100644 index 0000000..bfa991f --- /dev/null +++ b/reflection/reflection.go @@ -0,0 +1,5 @@ +package reflection + +func walk(x interface{}, fn func(input string)) { + fn("I still can't believe South Korea beat Germany 2-0 to put them last in their group") +} From ad4757225e3247dbf2dd370248fe57dabcfe09aa Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 10:08:23 -0300 Subject: [PATCH 03/28] assert by content walk return --- reflection/reflection_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/reflection/reflection_test.go b/reflection/reflection_test.go index 2c3442c..249da2b 100644 --- a/reflection/reflection_test.go +++ b/reflection/reflection_test.go @@ -17,4 +17,8 @@ func TestWalk(t *testing.T) { if len(got) != 1 { t.Errorf("wrong number of function calls, got %d want %d", len(got), 1) } + + if got[0] != expected { + t.Errorf("got %q want %q", got[0], expected) + } } From 651b9e42525bb61030d7c8a2662aeacf59e178fe Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 10:09:46 -0300 Subject: [PATCH 04/28] use reflection to get the value of struct in walk --- reflection/reflection.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/reflection/reflection.go b/reflection/reflection.go index bfa991f..6f82d26 100644 --- a/reflection/reflection.go +++ b/reflection/reflection.go @@ -1,5 +1,9 @@ package reflection +import "reflect" + func walk(x interface{}, fn func(input string)) { - fn("I still can't believe South Korea beat Germany 2-0 to put them last in their group") + val := reflect.ValueOf(x) + field := val.Field(0) + fn(field.String()) } From ee8fc517d91f6ffe5629cf615945ef66ba946564 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 10:21:43 -0300 Subject: [PATCH 05/28] Refactor test to testing more cases with flexibility --- reflection/reflection_test.go | 42 ++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/reflection/reflection_test.go b/reflection/reflection_test.go index 249da2b..6d9b3ed 100644 --- a/reflection/reflection_test.go +++ b/reflection/reflection_test.go @@ -1,24 +1,36 @@ package reflection -import "testing" +import ( + "reflect" + "testing" +) func TestWalk(t *testing.T) { - expected := "Chris" - var got []string - - x := struct { - Name string - }{expected} + cases := []struct { + Name string + Input interface{} + ExpectedCalls []string + }{ + { + "struct with one string field", + struct { + Name string + }{"Chris"}, + []string{"Chris"}, + }, + } - walk(x, func(input string) { - got = append(got, input) - }) + for _, test := range cases { + t.Run(test.Name, func(t *testing.T) { + var got []string - if len(got) != 1 { - t.Errorf("wrong number of function calls, got %d want %d", len(got), 1) - } + walk(test.Input, func(input string) { + got = append(got, input) + }) - if got[0] != expected { - t.Errorf("got %q want %q", got[0], expected) + if !reflect.DeepEqual(got, test.ExpectedCalls) { + t.Errorf("got %v want %v", got, test.ExpectedCalls) + } + }) } } From 0997bed9b0c74ff013ff42b0fc1147f949600eb2 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 10:23:54 -0300 Subject: [PATCH 06/28] testing for two string fields in struct --- reflection/reflection_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/reflection/reflection_test.go b/reflection/reflection_test.go index 6d9b3ed..b1f407c 100644 --- a/reflection/reflection_test.go +++ b/reflection/reflection_test.go @@ -18,6 +18,14 @@ func TestWalk(t *testing.T) { }{"Chris"}, []string{"Chris"}, }, + { + "struct with two string fields", + struct { + Name string + City string + }{"Chris", "London"}, + []string{"Chris", "London"}, + }, } for _, test := range cases { From 75e5020a33f868775ac087217c8f141cfa7cd124 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 10:25:37 -0300 Subject: [PATCH 07/28] refactor code to be able to compute any number of string fields --- reflection/reflection.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/reflection/reflection.go b/reflection/reflection.go index 6f82d26..bbf7f44 100644 --- a/reflection/reflection.go +++ b/reflection/reflection.go @@ -4,6 +4,9 @@ import "reflect" func walk(x interface{}, fn func(input string)) { val := reflect.ValueOf(x) - field := val.Field(0) - fn(field.String()) + + for i := 0; i < val.NumField(); i++ { + field := val.Field(i) + fn(field.String()) + } } From 94d375a2b941e5c5f7e78a79ccbd05aa7f6fb172 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 10:28:37 -0300 Subject: [PATCH 08/28] test for non string fields --- reflection/reflection_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/reflection/reflection_test.go b/reflection/reflection_test.go index b1f407c..e79383a 100644 --- a/reflection/reflection_test.go +++ b/reflection/reflection_test.go @@ -26,6 +26,14 @@ func TestWalk(t *testing.T) { }{"Chris", "London"}, []string{"Chris", "London"}, }, + { + "struct with non string field", + struct { + Name string + Age int + }{"Chris", 33}, + []string{"Chris"}, + }, } for _, test := range cases { From 95b4bb7188c73ebb37442d2e3d2659f31b6036a4 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 10:29:20 -0300 Subject: [PATCH 09/28] check if field is string type before call function --- reflection/reflection.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/reflection/reflection.go b/reflection/reflection.go index bbf7f44..4626a86 100644 --- a/reflection/reflection.go +++ b/reflection/reflection.go @@ -7,6 +7,9 @@ func walk(x interface{}, fn func(input string)) { for i := 0; i < val.NumField(); i++ { field := val.Field(i) - fn(field.String()) + + if field.Kind() == reflect.String { + fn(field.String()) + } } } From f647b5054168e3a8df28ca37cfb2d9e37cd1f638 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 10:40:40 -0300 Subject: [PATCH 10/28] add case test for nested fields --- reflection/reflection_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/reflection/reflection_test.go b/reflection/reflection_test.go index e79383a..5c6fc84 100644 --- a/reflection/reflection_test.go +++ b/reflection/reflection_test.go @@ -5,6 +5,16 @@ import ( "testing" ) +type Person struct { + Name string + Profile Profile +} + +type Profile struct { + Age int + City string +} + func TestWalk(t *testing.T) { cases := []struct { Name string @@ -34,6 +44,14 @@ func TestWalk(t *testing.T) { }{"Chris", 33}, []string{"Chris"}, }, + { + "nested fields", + Person{ + "Chris", + Profile{33, "Longon"}, + }, + []string{"Chris", "London"}, + }, } for _, test := range cases { From 3baf3233c32382dff8c9436d3ee5016adde6aa75 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 10:41:04 -0300 Subject: [PATCH 11/28] change de walk function to check nested fields --- reflection/reflection.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/reflection/reflection.go b/reflection/reflection.go index 4626a86..09ab024 100644 --- a/reflection/reflection.go +++ b/reflection/reflection.go @@ -11,5 +11,9 @@ func walk(x interface{}, fn func(input string)) { if field.Kind() == reflect.String { fn(field.String()) } + + if field.Kind() == reflect.Struct { + walk(field.Interface(), fn) + } } } From dad2476d7be5a08a02d89882f383de3d6566d28a Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 10:46:01 -0300 Subject: [PATCH 12/28] fix case test typo --- reflection/reflection_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reflection/reflection_test.go b/reflection/reflection_test.go index 5c6fc84..c157d96 100644 --- a/reflection/reflection_test.go +++ b/reflection/reflection_test.go @@ -48,7 +48,7 @@ func TestWalk(t *testing.T) { "nested fields", Person{ "Chris", - Profile{33, "Longon"}, + Profile{33, "London"}, }, []string{"Chris", "London"}, }, From 8d5b23af7ceaea962dc05c4f015cbd4ef441a6f6 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 10:46:23 -0300 Subject: [PATCH 13/28] test for pointers in struct --- reflection/reflection_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/reflection/reflection_test.go b/reflection/reflection_test.go index c157d96..ebf3650 100644 --- a/reflection/reflection_test.go +++ b/reflection/reflection_test.go @@ -52,6 +52,14 @@ func TestWalk(t *testing.T) { }, []string{"Chris", "London"}, }, + { + "pointers to things", + &Person{ + "Chris", + Profile{33, "London"}, + }, + []string{"Chris", "London"}, + }, } for _, test := range cases { From 3a17d0475ec6cbb49a2acee7e6e42072143c9024 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 10:46:44 -0300 Subject: [PATCH 14/28] check for pointers before call NumFields --- reflection/reflection.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/reflection/reflection.go b/reflection/reflection.go index 09ab024..88e4939 100644 --- a/reflection/reflection.go +++ b/reflection/reflection.go @@ -5,14 +5,17 @@ import "reflect" func walk(x interface{}, fn func(input string)) { val := reflect.ValueOf(x) + if val.Kind() == reflect.Pointer { + val = val.Elem() + } + for i := 0; i < val.NumField(); i++ { field := val.Field(i) - if field.Kind() == reflect.String { + switch field.Kind() { + case reflect.String: fn(field.String()) - } - - if field.Kind() == reflect.Struct { + case reflect.Struct: walk(field.Interface(), fn) } } From e42206065ec2482c464cbe1a0cf0565fc71643f3 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 10:52:45 -0300 Subject: [PATCH 15/28] refactor to get value in dedicate function --- reflection/reflection.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/reflection/reflection.go b/reflection/reflection.go index 88e4939..638ec8d 100644 --- a/reflection/reflection.go +++ b/reflection/reflection.go @@ -3,11 +3,7 @@ package reflection import "reflect" func walk(x interface{}, fn func(input string)) { - val := reflect.ValueOf(x) - - if val.Kind() == reflect.Pointer { - val = val.Elem() - } + val := getValue(x) for i := 0; i < val.NumField(); i++ { field := val.Field(i) @@ -20,3 +16,13 @@ func walk(x interface{}, fn func(input string)) { } } } + +func getValue(x interface{}) reflect.Value { + val := reflect.ValueOf(x) + + if val.Kind() == reflect.Pointer { + val = val.Elem() + } + + return val +} From c0e8a5ac732c157a7b2d059a7e758186f9bbc399 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 11:06:42 -0300 Subject: [PATCH 16/28] case test for slices --- reflection/reflection_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/reflection/reflection_test.go b/reflection/reflection_test.go index ebf3650..15a5090 100644 --- a/reflection/reflection_test.go +++ b/reflection/reflection_test.go @@ -60,6 +60,14 @@ func TestWalk(t *testing.T) { }, []string{"Chris", "London"}, }, + { + "slices", + []Profile{ + {33, "London"}, + {34, "Reykjavík"}, + }, + []string{"London", "Reykjavík"}, + }, } for _, test := range cases { From 81648afa11b6c54822935f3c752502e7d3d9a2f5 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 11:07:04 -0300 Subject: [PATCH 17/28] change de code to works with slices --- reflection/reflection.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/reflection/reflection.go b/reflection/reflection.go index 638ec8d..b257894 100644 --- a/reflection/reflection.go +++ b/reflection/reflection.go @@ -5,6 +5,13 @@ import "reflect" func walk(x interface{}, fn func(input string)) { val := getValue(x) + if val.Kind() == reflect.Slice { + for i := 0; i < val.Len(); i++ { + walk(val.Index(i).Interface(), fn) + } + return + } + for i := 0; i < val.NumField(); i++ { field := val.Field(i) From 96f70b821378a53c81f62b337430c918ed0ffcd5 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 11:12:42 -0300 Subject: [PATCH 18/28] refactor to check all types in switch --- reflection/reflection.go | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/reflection/reflection.go b/reflection/reflection.go index b257894..c91cc14 100644 --- a/reflection/reflection.go +++ b/reflection/reflection.go @@ -5,21 +5,16 @@ import "reflect" func walk(x interface{}, fn func(input string)) { val := getValue(x) - if val.Kind() == reflect.Slice { + switch val.Kind() { + case reflect.String: + fn(val.String()) + case reflect.Slice: for i := 0; i < val.Len(); i++ { walk(val.Index(i).Interface(), fn) } - return - } - - for i := 0; i < val.NumField(); i++ { - field := val.Field(i) - - switch field.Kind() { - case reflect.String: - fn(field.String()) - case reflect.Struct: - walk(field.Interface(), fn) + case reflect.Struct: + for i := 0; i < val.NumField(); i++ { + walk(val.Field(i).Interface(), fn) } } } From 419aa8c464013b33cc375c8f6e20c56d1e2c8548 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 11:16:23 -0300 Subject: [PATCH 19/28] iterate on fields in a unique point --- reflection/reflection.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/reflection/reflection.go b/reflection/reflection.go index c91cc14..a82e5c3 100644 --- a/reflection/reflection.go +++ b/reflection/reflection.go @@ -5,17 +5,22 @@ import "reflect" func walk(x interface{}, fn func(input string)) { val := getValue(x) + numberOfValues := 0 + var getField func(int) reflect.Value + switch val.Kind() { case reflect.String: fn(val.String()) case reflect.Slice: - for i := 0; i < val.Len(); i++ { - walk(val.Index(i).Interface(), fn) - } + numberOfValues = val.Len() + getField = val.Index case reflect.Struct: - for i := 0; i < val.NumField(); i++ { - walk(val.Field(i).Interface(), fn) - } + numberOfValues = val.NumField() + getField = val.Field + } + + for i := 0; i < numberOfValues; i++ { + walk(getField(i).Interface(), fn) } } From a524aff3c610b7b2287d5e9074bb8ed3dbcee2ac Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 11:18:47 -0300 Subject: [PATCH 20/28] case test for arrays --- reflection/reflection_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/reflection/reflection_test.go b/reflection/reflection_test.go index 15a5090..69bea0b 100644 --- a/reflection/reflection_test.go +++ b/reflection/reflection_test.go @@ -68,6 +68,14 @@ func TestWalk(t *testing.T) { }, []string{"London", "Reykjavík"}, }, + { + "arrays", + [2]Profile{ + {33, "London"}, + {34, "Reykjavík"}, + }, + []string{"London", "Reykjavík"}, + }, } for _, test := range cases { From 2b1b3263e32617ca5ffc02e6532e20d4381c2f74 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 11:19:09 -0300 Subject: [PATCH 21/28] change de walk code to works with array --- reflection/reflection.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reflection/reflection.go b/reflection/reflection.go index a82e5c3..9e0c82d 100644 --- a/reflection/reflection.go +++ b/reflection/reflection.go @@ -11,7 +11,7 @@ func walk(x interface{}, fn func(input string)) { switch val.Kind() { case reflect.String: fn(val.String()) - case reflect.Slice: + case reflect.Slice, reflect.Array: numberOfValues = val.Len() getField = val.Index case reflect.Struct: From d70131e59927aa0616dca3e181dfdc0bb1b3291d Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 12:01:17 -0300 Subject: [PATCH 22/28] case test for maps --- reflection/reflection_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/reflection/reflection_test.go b/reflection/reflection_test.go index 69bea0b..f95d5df 100644 --- a/reflection/reflection_test.go +++ b/reflection/reflection_test.go @@ -76,6 +76,14 @@ func TestWalk(t *testing.T) { }, []string{"London", "Reykjavík"}, }, + { + "maps", + map[string]string{ + "Cow": "Moo", + "Sheep": "Baa", + }, + []string{"Moo", "Baa"}, + }, } for _, test := range cases { From e9bfd6183b0bfc55131a5b03cb2d7b7453f133dc Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 12:04:33 -0300 Subject: [PATCH 23/28] change code to works with maps --- reflection/reflection.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/reflection/reflection.go b/reflection/reflection.go index 9e0c82d..225f043 100644 --- a/reflection/reflection.go +++ b/reflection/reflection.go @@ -17,6 +17,11 @@ func walk(x interface{}, fn func(input string)) { case reflect.Struct: numberOfValues = val.NumField() getField = val.Field + case reflect.Map: + for _, key := range val.MapKeys() { + walk(val.MapIndex(key).Interface(), fn) + } + } for i := 0; i < numberOfValues; i++ { From 48e34eca9f9bbfb7cdc262dd150b4e4f5c54c3ec Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 12:08:44 -0300 Subject: [PATCH 24/28] change the abstraction to only pass reflect.Value --- reflection/reflection.go | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/reflection/reflection.go b/reflection/reflection.go index 225f043..8dab5cc 100644 --- a/reflection/reflection.go +++ b/reflection/reflection.go @@ -5,27 +5,25 @@ import "reflect" func walk(x interface{}, fn func(input string)) { val := getValue(x) - numberOfValues := 0 - var getField func(int) reflect.Value + walkValue := func(value reflect.Value) { + walk(value.Interface(), fn) + } switch val.Kind() { case reflect.String: fn(val.String()) case reflect.Slice, reflect.Array: - numberOfValues = val.Len() - getField = val.Index + for i := 0; i < val.Len(); i++ { + walkValue(val.Index(i)) + } case reflect.Struct: - numberOfValues = val.NumField() - getField = val.Field + for i := 0; i < val.NumField(); i++ { + walkValue(val.Field(i)) + } case reflect.Map: for _, key := range val.MapKeys() { - walk(val.MapIndex(key).Interface(), fn) + walkValue(val.MapIndex(key)) } - - } - - for i := 0; i < numberOfValues; i++ { - walk(getField(i).Interface(), fn) } } From b5a83275ba069ec7d1b0d44da1b245d080bd5ac4 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 12:15:01 -0300 Subject: [PATCH 25/28] tests maps without order dependency --- reflection/reflection_test.go | 38 +++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/reflection/reflection_test.go b/reflection/reflection_test.go index f95d5df..b8d7c88 100644 --- a/reflection/reflection_test.go +++ b/reflection/reflection_test.go @@ -76,14 +76,6 @@ func TestWalk(t *testing.T) { }, []string{"London", "Reykjavík"}, }, - { - "maps", - map[string]string{ - "Cow": "Moo", - "Sheep": "Baa", - }, - []string{"Moo", "Baa"}, - }, } for _, test := range cases { @@ -99,4 +91,34 @@ func TestWalk(t *testing.T) { } }) } + + t.Run("with maps", func(t *testing.T) { + aMap := map[string]string{ + "Cow": "Moo", + "Sheep": "Baa", + } + + var got []string + walk(aMap, func(input string) { + got = append(got, input) + }) + + assertContains(t, got, "Moo") + assertContains(t, got, "Baa") + }) +} + +func assertContains(t testing.TB, results []string, needle string) { + t.Helper() + contains := false + + for _, x := range results { + if x == needle { + contains = true + } + } + + if !contains { + t.Errorf("expected %v to contain %q but it didn't", results, needle) + } } From 603c4717f0d01785cbf3b66d5a30c36fa55e4e25 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 12:25:30 -0300 Subject: [PATCH 26/28] test for channels --- reflection/reflection.go | 12 +++++++++++- reflection/reflection_test.go | 21 +++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/reflection/reflection.go b/reflection/reflection.go index 8dab5cc..1f1d996 100644 --- a/reflection/reflection.go +++ b/reflection/reflection.go @@ -1,6 +1,8 @@ package reflection -import "reflect" +import ( + "reflect" +) func walk(x interface{}, fn func(input string)) { val := getValue(x) @@ -24,6 +26,14 @@ func walk(x interface{}, fn func(input string)) { for _, key := range val.MapKeys() { walkValue(val.MapIndex(key)) } + case reflect.Chan: + for { + if v, ok := val.Recv(); ok { + walkValue(v) + } else { + break + } + } } } diff --git a/reflection/reflection_test.go b/reflection/reflection_test.go index b8d7c88..9e57e31 100644 --- a/reflection/reflection_test.go +++ b/reflection/reflection_test.go @@ -106,6 +106,27 @@ func TestWalk(t *testing.T) { assertContains(t, got, "Moo") assertContains(t, got, "Baa") }) + + t.Run("with channels", func(t *testing.T) { + aChannel := make(chan Profile) + + go func() { + aChannel <- Profile{33, "Berlin"} + aChannel <- Profile{34, "Katowice"} + close(aChannel) + }() + + var got []string + want := []string{"Berlin", "Katowice"} + + walk(aChannel, func(input string) { + got = append(got, input) + }) + + if !reflect.DeepEqual(got, want) { + t.Errorf("got %v, want %v", got, want) + } + }) } func assertContains(t testing.TB, results []string, needle string) { From 921969b01385357e6aaf3497ee82c3eb7a9bf2a9 Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 12:30:44 -0300 Subject: [PATCH 27/28] case test for functions --- reflection/reflection_test.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/reflection/reflection_test.go b/reflection/reflection_test.go index 9e57e31..23a0901 100644 --- a/reflection/reflection_test.go +++ b/reflection/reflection_test.go @@ -127,6 +127,23 @@ func TestWalk(t *testing.T) { t.Errorf("got %v, want %v", got, want) } }) + + t.Run("with functions", func(t *testing.T) { + aFunction := func() (Profile, Profile) { + return Profile{33, "Berlin"}, Profile{34, "Katowice"} + } + + var got []string + want := []string{"Berlin", "Katowice"} + + walk(aFunction, func(input string) { + got = append(got, input) + }) + + if !reflect.DeepEqual(got, want) { + t.Errorf("got %v, want %v", got, want) + } + }) } func assertContains(t testing.TB, results []string, needle string) { From 791b92110cc800e18e1906dd0095df0ca358075d Mon Sep 17 00:00:00 2001 From: Neftales Antunes Date: Sat, 1 Jun 2024 12:31:01 -0300 Subject: [PATCH 28/28] change code to works with functions --- reflection/reflection.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/reflection/reflection.go b/reflection/reflection.go index 1f1d996..5733c61 100644 --- a/reflection/reflection.go +++ b/reflection/reflection.go @@ -34,6 +34,11 @@ func walk(x interface{}, fn func(input string)) { break } } + case reflect.Func: + valResults := val.Call(nil) + for _, result := range valResults { + walkValue(result) + } } }