Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions spatial-index/csv_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package spatialindex

import (
"errors"
"strings"
"testing"

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

type testRow struct {
A string
B string
}

func fromFuncSimple(data []string, headers []string) (testRow, error) {
return testRow{A: data[0], B: data[1]}, nil
}

func fromFuncWithError(data []string, headers []string) (testRow, error) {
return testRow{}, errors.New("parse error")
}

func TestParseCSV_WithHeader_Success(t *testing.T) {
csvData := "a,b\nfoo,bar\nbaz,qux\n"
reader := strings.NewReader(csvData)

var results []Result[testRow]
iter := parseCSV(reader, true, fromFuncSimple)
for r := range iter {
results = append(results, r)
}

require.Len(t, results, 2)
require.Equal(t, 1, results[0].LineNum)
require.Equal(t, "foo", results[0].Value.A)
require.Equal(t, "bar", results[0].Value.B)
require.NoError(t, results[0].Error)
require.Equal(t, 2, results[1].LineNum)
require.Equal(t, "baz", results[1].Value.A)
require.Equal(t, "qux", results[1].Value.B)
require.NoError(t, results[1].Error)
}

func TestParseCSV_WithoutHeader_Success(t *testing.T) {
csvData := "foo,bar\nbaz,qux\n"
reader := strings.NewReader(csvData)

var results []Result[testRow]
iter := parseCSV(reader, false, fromFuncSimple)
for r := range iter {
results = append(results, r)
}

require.Len(t, results, 2)
require.Equal(t, 1, results[0].LineNum)
require.Equal(t, "foo", results[0].Value.A)
require.Equal(t, "bar", results[0].Value.B)
require.NoError(t, results[0].Error)
Comment thread
rm-hull marked this conversation as resolved.
require.Equal(t, 2, results[1].LineNum)
require.Equal(t, "baz", results[1].Value.A)
require.Equal(t, "qux", results[1].Value.B)
require.NoError(t, results[1].Error)
}

func TestParseCSV_ParseError(t *testing.T) {
csvData := "a,b\nfoo,bar\nbaz,qux\n"
reader := strings.NewReader(csvData)

var results []Result[testRow]
iter := parseCSV(reader, true, fromFuncWithError)
for r := range iter {
results = append(results, r)
}

require.Len(t, results, 1)
require.Equal(t, 1, results[0].LineNum)
require.Error(t, results[0].Error)
require.Contains(t, results[0].Error.Error(), "failed to parse CSV line 1")
}

func TestParseCSV_MalformedLine(t *testing.T) {
csvData := "a,b\nfoo\n"
reader := strings.NewReader(csvData)

var results []Result[testRow]
iter := parseCSV(reader, true, fromFuncSimple)
for r := range iter {
results = append(results, r)
}

require.Len(t, results, 1)
require.Equal(t, 1, results[0].LineNum)
require.Error(t, results[0].Error)
// Error message is from underlying csv.Reader
require.Contains(t, results[0].Error.Error(), "wrong number of fields")
Comment thread
rm-hull marked this conversation as resolved.
}

func TestParseCSV_HeaderReadError(t *testing.T) {
// An empty reader will cause an io.EOF when reading headers.
reader := strings.NewReader("")
iter := parseCSV(reader, true, fromFuncSimple)
var results []Result[testRow]
for r := range iter {
results = append(results, r)
}
require.Len(t, results, 1)
require.Equal(t, 0, results[0].LineNum)
require.Error(t, results[0].Error)
require.Contains(t, results[0].Error.Error(), "failed to read CSV headers")
}

func TestParseCSV_YieldStopsEarly(t *testing.T) {
csvData := "a,b\nfoo,bar\nbaz,qux\n"
reader := strings.NewReader(csvData)

count := 0
iter := parseCSV(reader, true, fromFuncSimple)
iter(func(r Result[testRow]) bool {
count++
return false // stop after first
})
require.Equal(t, 1, count)
}