From ab0f0c69544bac5d397734f74b765118b3d0c97b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D2=88=D2=88=D2=88Luiz=20Branco?= Date: Thu, 16 Nov 2017 12:35:50 -0400 Subject: [PATCH] Fix list index when item doesn't support comparison (#23) --- list/list.go | 13 +++++++------ list/list_test.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/list/list.go b/list/list.go index 141fca0..b1cc8be 100644 --- a/list/list.go +++ b/list/list.go @@ -17,8 +17,8 @@ const NotFound = -1 // visible items. The list can be moved up, down by one item of time or an // entire page (ie: visible size). It keeps track of the current selected item. type List struct { - items []interface{} - scope []interface{} + items []*interface{} + scope []*interface{} cursor int // cursor holds the index of the current selected item size int // size is the number of visible options start int @@ -37,10 +37,11 @@ func New(items interface{}, size int) (*List, error) { } slice := reflect.ValueOf(items) - values := make([]interface{}, slice.Len()) + values := make([]*interface{}, slice.Len()) for i := range values { - values[i] = slice.Index(i).Interface() + item := slice.Index(i).Interface() + values[i] = &item } return &List{size: size, items: values, scope: values}, nil @@ -77,7 +78,7 @@ func (l *List) CancelSearch() { } func (l *List) search(term string) { - var scope []interface{} + var scope []*interface{} for i, item := range l.items { if l.Searcher(term, i) { @@ -189,7 +190,7 @@ func (l *List) Items() ([]interface{}, int) { active = j } - result = append(result, l.scope[i]) + result = append(result, *l.scope[i]) } return result, active diff --git a/list/list_test.go b/list/list_test.go index acc6732..4dd6fde 100644 --- a/list/list_test.go +++ b/list/list_test.go @@ -109,6 +109,52 @@ func TestListPageDown(t *testing.T) { }) } +func TestListComparion(t *testing.T) { + t.Run("when item supports comparison", func(t *testing.T) { + type comparable struct { + Number int + } + + structs := []comparable{ + {Number: 1}, + {Number: 2}, + } + + l, err := New(structs, 4) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + + idx := l.Index() + + if idx != 0 { + t.Errorf("expected index to be first, got %d", idx) + } + }) + + t.Run("when item doesn't support comparison", func(t *testing.T) { + type uncomparable struct { + Numbers []int + } + + structs := []uncomparable{ + {Numbers: []int{1}}, + {Numbers: []int{2}}, + } + + l, err := New(structs, 4) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + + idx := l.Index() + + if idx != 0 { + t.Errorf("expected index to be first, got %d", idx) + } + }) +} + func castList(list []interface{}) []rune { result := make([]rune, len(list)) for i, l := range list {