From 35a76ae752213bf729e2900c492b628368887cbf Mon Sep 17 00:00:00 2001 From: laurentu Date: Fri, 25 Mar 2022 11:31:15 +0100 Subject: [PATCH] Enabling unit testing --- csv-parser.go | 40 +++++++++++++++------------ csv-parser_test.go | 68 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 18 deletions(-) create mode 100644 csv-parser_test.go diff --git a/csv-parser.go b/csv-parser.go index 0ee8417..440c83a 100644 --- a/csv-parser.go +++ b/csv-parser.go @@ -41,47 +41,51 @@ func (parser *CsvParser) Init() { parser.Delimiter = " \t" } -func (parser *CsvParser) ExtractEnclosedFieldValue(line string, endChar byte) (string, error) { - lineLen := len(line) +func (parser *CsvParser) ExtractEnclosedFieldValue(endChar byte) error { + lineLen := len(parser.Line) for i := 1; i < lineLen; i++ { - if line[i] == endChar && line[i-1] != '\\' { - parser.Fields = append(parser.Fields, line[1:i]) - return line[i+1:], nil + if parser.Line[i] == endChar && parser.Line[i-1] != '\\' { + parser.Fields = append(parser.Fields, parser.Line[0:i]) + parser.Line = parser.Line[i+1:] + return nil } } - return line, errors.New("Encloser close not found") + return errors.New("Encloser close not found") } -func (parser *CsvParser) Parse(line string) error { +func (parser *CsvParser) Parse(CsvLine string) error { var err error = nil - for len(line) > 0 { - line = strings.TrimLeft(line, parser.Delimiter) - line = strings.TrimRight(line, parser.Delimiter) - if len(line) == 0 { + parser.Fields = make([]string,0) + parser.Line = CsvLine + for len(parser.Line) > 0 { + parser.Line = strings.TrimLeft(parser.Line, parser.Delimiter) + parser.Line = strings.TrimRight(parser.Line, parser.Delimiter) + if len(parser.Line) == 0 { break } // Search for an encloser encloserId := None for _, id := range parser.Enclosers { - if line[0] == EnclosersRunes[id].Open { + if parser.Line[0] == EnclosersRunes[id].Open { encloserId = id break } } if encloserId != None { - line, err = parser.ExtractEnclosedFieldValue(line, EnclosersRunes[encloserId].Close) + parser.Line = parser.Line[1:] + err = parser.ExtractEnclosedFieldValue(EnclosersRunes[encloserId].Close) if err != nil { return err } } else { - nextSpace := strings.IndexAny(line, parser.Delimiter) + nextSpace := strings.IndexAny(parser.Line, parser.Delimiter) if nextSpace != -1 { - parser.Fields = append(parser.Fields, line[:nextSpace]) - line = line[nextSpace:] + parser.Fields = append(parser.Fields, parser.Line[:nextSpace]) + parser.Line = parser.Line[nextSpace:] } else { - parser.Fields = append(parser.Fields, line) - line = "" + parser.Fields = append(parser.Fields, parser.Line) + parser.Line = "" break } diff --git a/csv-parser_test.go b/csv-parser_test.go new file mode 100644 index 0000000..05a0588 --- /dev/null +++ b/csv-parser_test.go @@ -0,0 +1,68 @@ +package csvparser + +import( + "testing" +) + + +func TestParse(t *testing.T) { + var parser CsvParser + + var CsvTestValues = [...]string { + "field1 field2 field3", // standard CSV + " field1 field2 field3 ", // Space or multiple spaces as delimiters + " field1 field2 field3 ", // Spaces + tabs as delimiters + " \"field1\" field2 field3 ", // Enclosed fields + " \"field1\" field2 [field3] ", // Enclosed fields + } + var CsvExpectedValues = [...]string { + "field1", + "field2", + "field3", + } + + parser.Init() + for _, v := range CsvTestValues { + err := parser.Parse(v) + if err != nil { + t.Error("Parse error:", err, " in ", v) + } + if len(parser.Fields) != len(CsvExpectedValues) { + t.Error("Extracted field number does not match expected", parser.Fields) + } + for i,val := range CsvExpectedValues { + if parser.Fields[i] != val { + t.Error("Field values do not match", i, " ", val, " ", parser.Fields[i]) + } + } + } +} +func TestParseWithEscape(t *testing.T) { + var parser CsvParser + + var CsvTestValues = [...]string { + "\"\\\"field1\" field2 [\\[field3] ", // Enclosed fields + } + var CsvExpectedValues = [...]string { + "\"field1", + "field2", + "[field3", + } + + + parser.Init() + for _, v := range CsvTestValues { + err := parser.Parse(v) + if err != nil { + t.Error("Parse error:", err, " in ", v) + } + if len(parser.Fields) != len(CsvExpectedValues) { + t.Error("Extracted field number does not match expected", parser.Fields) + } + for i,val := range CsvExpectedValues { + if parser.Fields[i] != val { + t.Error("Field values do not match", i, " ", val, " ", parser.Fields[i]) + } + } + } +}