1
0
Fork 0
mirror of https://github.com/imjasonh/csvstruct synced 2026-07-08 19:14:56 +00:00
csvstruct/decode_test.go

180 lines
3.6 KiB
Go
Raw Normal View History

package csvstruct
import (
2014-05-15 12:31:56 -04:00
"fmt"
"io"
2014-05-14 21:11:21 -04:00
"reflect"
"strings"
"testing"
)
func TestDecode(t *testing.T) {
type row struct {
Foo, Bar, Baz string
}
for _, c := range []struct {
data string
out []row
}{{
data: `Foo,Bar,Baz
a,b,c
2014-05-15 10:07:07 -04:00
d,e,f
`,
out: []row{{"a", "b", "c"}, {"d", "e", "f"}},
}, {
// Rows that only have partial data are only partially filled.
2014-05-15 08:31:35 -04:00
data: `Foo,Bar,Baz
a,,
2014-05-15 10:07:07 -04:00
,b,
`,
2014-05-15 08:31:35 -04:00
out: []row{{"a", "", ""}, {"", "b", ""}},
}, {
// Rows that don't define all the columns are partially filled.
data: `Foo,Bar
a,
2014-05-15 10:07:07 -04:00
,b
`,
out: []row{{"a", "", ""}, {"", "b", ""}},
2014-05-15 10:07:07 -04:00
}, {
// Entirely disjoint columns produce empty structs.
data: `Qux
d
`,
out: []row{{}},
}} {
d := NewDecoder(strings.NewReader(c.data))
2014-05-14 21:11:21 -04:00
rows := []row{}
2014-05-15 10:32:47 -04:00
var r row
for {
2014-05-15 10:32:47 -04:00
if err := d.DecodeNext(&r); err == io.EOF {
break
2014-05-15 10:07:07 -04:00
} else if err != nil {
t.Errorf("%v", err)
break
}
2014-05-15 10:32:47 -04:00
rows = append(rows, r)
2014-05-14 21:11:21 -04:00
}
2014-05-15 08:31:35 -04:00
if !reflect.DeepEqual(rows, c.out) {
2014-05-14 21:11:21 -04:00
t.Errorf("unexpected result, got %v, want %v", rows, c.out)
}
2014-05-15 12:55:24 -04:00
if !isDone(d) {
t.Errorf("decoder unexpectedly not done")
}
}
}
2014-05-15 10:32:47 -04:00
func TestDecode_Unexported(t *testing.T) {
type row struct {
Exported, unexported string
}
var r row
if err := NewDecoder(strings.NewReader(`Exported,unexported
a,b`)).DecodeNext(&r); err != nil {
2014-05-15 10:32:47 -04:00
t.Errorf("unexpected error: %v", err)
}
exp := row{Exported: "a"}
if !reflect.DeepEqual(r, exp) {
t.Errorf("unexpected result, got %v, want %v", r, exp)
}
}
2014-05-15 10:42:25 -04:00
func TestDecode_Tags(t *testing.T) {
type row struct {
Foo string `csv:"renamed_foo"`
Bar string
Ignored string `csv:"-"`
}
var r row
if err := NewDecoder(strings.NewReader(`renamed_foo,Bar,Ignored
a,b,c`)).DecodeNext(&r); err != nil {
2014-05-15 10:42:25 -04:00
t.Errorf("unexpected error: %v", err)
}
exp := row{"a", "b", ""}
if !reflect.DeepEqual(r, exp) {
t.Errorf("unexpected results, got %v, want %v", r, exp)
}
}
func TestDecode_NonStrings(t *testing.T) {
type row struct {
Int int
Int64 int64
2014-05-15 12:20:41 -04:00
Uint64 uint64
Float64 float64
Bool bool
}
var r row
2014-05-15 12:20:41 -04:00
if err := NewDecoder(strings.NewReader(`Int,Int64,Uint64,Float64,Bool
123,-123456789,123456789,123.456,true`)).DecodeNext(&r); err != nil {
t.Errorf("unexpected error: %v", err)
}
2014-05-15 12:20:41 -04:00
exp := row{123, -123456789, 123456789, 123.456, true}
if !reflect.DeepEqual(r, exp) {
t.Errorf("unexpected results, got %v, want %v", r, exp)
}
}
func TestDecode_Pointers(t *testing.T) {
t.Skip("pointers are not yet supported")
type row struct {
S string
SP *string
}
var r row
if err := NewDecoder(strings.NewReader(`S,SP
a,b`)).DecodeNext(&r); err != nil {
t.Errorf("unexpected error: %v", err)
}
if r.S != "a" || r.SP == nil || *r.SP != "b" {
t.Errorf("unexpected results, got %v", r)
}
}
2014-05-15 12:31:56 -04:00
2014-05-15 12:55:24 -04:00
func TestDecode_DecodeNil(t *testing.T) {
type row struct {
Foo, Bar string
}
d := NewDecoder(strings.NewReader(`Foo,Bar
ignore,this
a,b`))
if err := d.DecodeNext(nil); err != nil {
t.Errorf("unexpected error while skipping line: %v", err)
}
var r row
if err := d.DecodeNext(&r); err != nil {
t.Errorf("unexpected error decoding after skip: %v", err)
}
exp := row{"a", "b"}
if r != exp {
t.Errorf("unexpected result, got %v, want %v", r, exp)
}
if !isDone(d) {
t.Errorf("decoder unexpectedly not done")
}
}
func isDone(d Decoder) bool {
return d.DecodeNext(nil) == io.EOF
}
2014-05-15 12:31:56 -04:00
func ExampleDecoder_DecodeNext() {
csv := `Foo,Bar,Baz
a,b,c
d,e,f`
type row struct {
Foo, Bar, Baz string
}
var r row
d := NewDecoder(strings.NewReader(csv))
for {
if err := d.DecodeNext(&r); err == io.EOF {
break
}
fmt.Println(r)
}
// Output:
// {a b c}
// {d e f}
}