Skip to content

Commit

Permalink
slices: update Int.Scan() to parse empty slices
Browse files Browse the repository at this point in the history
Previously, Int.Scan() returned the slice '[0]' when reading an empty
slice of ints from the database. This is a bug, as the output should
also be empty. This patch fixes the bug and adds regression tests.
Additionally, the code is updated to percolate up the errors from
integer to string conversion, which was previously swallowed.
  • Loading branch information
carloruiz authored and sio4 committed Nov 1, 2022
1 parent 0240e62 commit 7dcfd55
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 6 deletions.
25 changes: 19 additions & 6 deletions slices/int.go
Expand Up @@ -27,8 +27,10 @@ func (i *Int) Scan(src interface{}) error {
default:
return fmt.Errorf("scan source was not []byte nor string but %T", src)
}
*i = strToInt(str)
return nil

v, err := strToInt(str)
*i = v
return err
}

// Value implements the driver.Valuer interface.
Expand Down Expand Up @@ -56,12 +58,23 @@ func (i *Int) UnmarshalText(text []byte) error {
return nil
}

func strToInt(s string) []int {
func strToInt(s string) ([]int, error) {
r := strings.Trim(s, "{}")
a := make([]int, 0, 10)
for _, t := range strings.Split(r, ",") {
i, _ := strconv.Atoi(t)

split := strings.Split(r, ",")
// Split returns [""] when splitting the empty string.
if len(split) == 1 && split[0] == "" {
return a, nil
}

for _, t := range split {
i, err := strconv.Atoi(t)
if err != nil {
return nil, err
}
a = append(a, i)
}
return a

return a, nil
}
30 changes: 30 additions & 0 deletions slices/int_test.go
@@ -0,0 +1,30 @@
package slices

import (
"testing"

"github.com/stretchr/testify/require"
)

func Test_Int_Scan(t *testing.T) {
r := require.New(t)
t.Run("empty slice", func(t *testing.T) {
in := "{}"
v := &Int{}
r.NoError(v.Scan(in))
r.Len(*v, 0)
})

t.Run("non-empty slice", func(t *testing.T) {
in := "{44,55}"
v := &Int{}
r.NoError(v.Scan(in))
r.Equal([]int(*v), []int{44, 55})
})

t.Run("invalid entry", func(t *testing.T) {
in := "{44,word}"
v := &Int{}
r.Error(v.Scan(in))
})
}

0 comments on commit 7dcfd55

Please sign in to comment.