diff options
author | RishabhBhatnagar <bhatnagarrishabh4@gmail.com> | 2020-01-09 20:39:55 +0530 |
---|---|---|
committer | RishabhBhatnagar <bhatnagarrishabh4@gmail.com> | 2020-01-09 21:04:37 +0530 |
commit | cd59ee66408a908f7ef94548814514f6bc9fc906 (patch) | |
tree | 550b146d4de0cc00a4784147f7d8f2a7bc93cffe /tvloader/reader | |
parent | f4fef41a45620391fca6481f4700b89de170ab88 (diff) | |
download | spdx-tools-cd59ee66408a908f7ef94548814514f6bc9fc906.tar.gz |
Create Go Module
- Unpack directory v0 to move all the content to the root directory.
- ./v0/* converted to ./*
- all the test cases were fixed to remove one directory less indexing for test files
- add go.mod
- go version 1.13 is used to have a relatively stable versioning system
Signed-off-by: RishabhBhatnagar <bhatnagarrishabh4@gmail.com>
Diffstat (limited to 'tvloader/reader')
-rw-r--r-- | tvloader/reader/reader.go | 161 | ||||
-rw-r--r-- | tvloader/reader/reader_test.go | 563 |
2 files changed, 724 insertions, 0 deletions
diff --git a/tvloader/reader/reader.go b/tvloader/reader/reader.go new file mode 100644 index 0000000..786f7ea --- /dev/null +++ b/tvloader/reader/reader.go @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + +package reader + +import ( + "bufio" + "fmt" + "io" + "strings" + "unicode" +) + +// TagValuePair is a convenience struct for a (tag, value) string pair. +type TagValuePair struct { + Tag string + Value string +} + +// ReadTagValues takes an io.Reader, scans it line by line and returns +// a slice of {string, string} structs in the form {tag, value}. +func ReadTagValues(content io.Reader) ([]TagValuePair, error) { + r := &tvReader{} + + scanner := bufio.NewScanner(content) + for scanner.Scan() { + // read each line, one by one + err := r.readNextLine(scanner.Text()) + if err != nil { + return nil, err + } + } + if err := scanner.Err(); err != nil { + return nil, err + } + + // finalize and make sure all is well + tvList, err := r.finalize() + if err != nil { + return nil, err + } + + // convert internal format to exported TagValueList + var exportedTVList []TagValuePair + for _, tv := range tvList { + tvPair := TagValuePair{Tag: tv.tag, Value: tv.value} + exportedTVList = append(exportedTVList, tvPair) + } + + return exportedTVList, nil +} + +type tagvalue struct { + tag string + value string +} + +type tvReader struct { + midtext bool + tvList []tagvalue + currentLine int + currentTag string + currentValue string +} + +func (reader *tvReader) finalize() ([]tagvalue, error) { + if reader.midtext { + return nil, fmt.Errorf("finalize called while still midtext parsing a text tag") + } + return reader.tvList, nil +} + +func (reader *tvReader) readNextLine(line string) error { + reader.currentLine++ + + if reader.midtext { + return reader.readNextLineFromMidtext(line) + } + + return reader.readNextLineFromReady(line) +} + +func (reader *tvReader) readNextLineFromReady(line string) error { + // strip whitespace from beginning of line + line2 := strings.TrimLeftFunc(line, func(r rune) bool { + return unicode.IsSpace(r) + }) + + // ignore empty lines + if line2 == "" { + return nil + } + + // ignore comment lines + if strings.HasPrefix(line2, "#") { + return nil + } + + // split at colon + substrings := strings.SplitN(line2, ":", 2) + if len(substrings) == 1 { + // error if a colon isn't found + return fmt.Errorf("no colon found in '%s'", line) + } + + // the first substring is the tag + reader.currentTag = strings.TrimSpace(substrings[0]) + + // determine whether the value contains (or starts) a <text> line + substrings = strings.SplitN(substrings[1], "<text>", 2) + if len(substrings) == 1 { + // no <text> tag found means this is a single-line value + // strip whitespace and use as a single line + reader.currentValue = strings.TrimSpace(substrings[0]) + } else { + // there was a <text> tag; now decide whether it's multi-line + substrings = strings.SplitN(substrings[1], "</text>", 2) + if len(substrings) > 1 { + // there is also a </text> tag; take the middle part and + // set as value + reader.currentValue = substrings[0] + } else { + // there is no </text> tag on this line; switch to midtext + reader.currentValue = substrings[0] + "\n" + reader.midtext = true + return nil + } + } + + // if we got here, the value was on a single line + // so go ahead and add it to the tag-value list + tv := tagvalue{reader.currentTag, reader.currentValue} + reader.tvList = append(reader.tvList, tv) + + // and reset + reader.currentTag = "" + reader.currentValue = "" + + return nil +} + +func (reader *tvReader) readNextLineFromMidtext(line string) error { + // look for whether the line closes here + substrings := strings.SplitN(line, "</text>", 2) + if len(substrings) == 1 { + // doesn't contain </text>, so keep building the current value + reader.currentValue += line + "\n" + return nil + } + + // contains </text>, so end and record this pair + reader.currentValue += substrings[0] + tv := tagvalue{reader.currentTag, reader.currentValue} + reader.tvList = append(reader.tvList, tv) + + // and reset + reader.midtext = false + reader.currentTag = "" + reader.currentValue = "" + + return nil +} diff --git a/tvloader/reader/reader_test.go b/tvloader/reader/reader_test.go new file mode 100644 index 0000000..73b4c9f --- /dev/null +++ b/tvloader/reader/reader_test.go @@ -0,0 +1,563 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +package reader + +import ( + "strings" + "testing" +) + +func TestCanReadTagValues(t *testing.T) { + sText := ` +Tag1: Value1 +Tag2: Value2 + +Tag3: <text>line 1 + line 2</text> +# Comment +Tag4: Value4 +Tag5: Value 5 +` + sReader := strings.NewReader(sText) + + tvPairList, err := ReadTagValues(sReader) + if err != nil { + t.Errorf("got error when calling ReadTagValues: %v", err) + } + if len(tvPairList) != 5 { + t.Fatalf("expected len(tvPairList) to be 5, got %d", len(tvPairList)) + } + if tvPairList[0].Tag != "Tag1" { + t.Errorf("expected tvPairList[0].Tag to be Tag1, got %s", tvPairList[0].Tag) + } + if tvPairList[0].Value != "Value1" { + t.Errorf("expected tvPairList[0].Value to be Value1, got %s", tvPairList[0].Value) + } + if tvPairList[1].Tag != "Tag2" { + t.Errorf("expected tvPairList[1].Tag to be Tag2, got %s", tvPairList[1].Tag) + } + if tvPairList[1].Value != "Value2" { + t.Errorf("expected tvPairList[1].Value to be Value2, got %s", tvPairList[1].Value) + } + if tvPairList[2].Tag != "Tag3" { + t.Errorf("expected tvPairList[2].Tag to be Tag3, got %s", tvPairList[2].Tag) + } + if tvPairList[2].Value != "line 1\n line 2" { + t.Errorf("expected tvPairList[2].Value to be line 1\n line 2, got %s", tvPairList[2].Value) + } + if tvPairList[3].Tag != "Tag4" { + t.Errorf("expected tvPairList[3].Tag to be Tag4, got %s", tvPairList[3].Tag) + } + if tvPairList[3].Value != "Value4" { + t.Errorf("expected tvPairList[3].Value to be Value4, got %s", tvPairList[3].Value) + } + if tvPairList[4].Tag != "Tag5" { + t.Errorf("expected tvPairList[4].Tag to be Tag5, got %s", tvPairList[4].Tag) + } + if tvPairList[4].Value != "Value 5" { + t.Errorf("expected tvPairList[4].Value to be Value 5, got %s", tvPairList[4].Value) + } +} + +func TestCanGetTVListWithFinalize(t *testing.T) { + reader := &tvReader{} + err := reader.readNextLine("Tag:value") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + tvList, err := reader.finalize() + if err != nil { + t.Errorf("got error when calling finalize: %v", err) + } + if len(tvList) != 1 || tvList[0].tag != "Tag" || tvList[0].value != "value" { + t.Errorf("got invalid tag/value list: %v", tvList) + } +} + +func TestCanGetTVListIncludingMultilineWithFinalize(t *testing.T) { + reader := &tvReader{} + err := reader.readNextLine("Tag:<text>value") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + err = reader.readNextLine("rest of value</text>") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + tvList, err := reader.finalize() + if err != nil { + t.Errorf("got error when calling finalize: %v", err) + } + if len(tvList) != 1 || tvList[0].tag != "Tag" || tvList[0].value != "value\nrest of value" { + t.Errorf("got invalid tag/value list: %v", tvList) + } +} + +func TestCannotFinalizeIfInMidtextState(t *testing.T) { + reader := &tvReader{} + err := reader.readNextLine("Tag:<text>value") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + _, err = reader.finalize() + if err == nil { + t.Errorf("should have gotten error when calling finalize midtext") + } +} + +func TestCurrentLineIncreasesOnEachReadCall(t *testing.T) { + reader := &tvReader{} + err := reader.readNextLine("Tag:value") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + if reader.currentLine != 1 { + t.Errorf("expected %d for currentLine, got %d", 1, reader.currentLine) + } + + reader.currentLine = 23 + err = reader.readNextLine("Tag:value") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + if reader.currentLine != 24 { + t.Errorf("expected %d for currentLine, got %d", 23, reader.currentLine) + } +} + +func TestReadyCanReadSingleTagValue(t *testing.T) { + reader := &tvReader{} + err := reader.readNextLine("Tag:value") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + if len(reader.tvList) != 1 || reader.tvList[0].tag != "Tag" || reader.tvList[0].value != "value" { + t.Errorf("got invalid tag/value list: %v", reader.tvList) + } + if reader.currentLine != 1 { + t.Errorf("expected %d for currentLine, got %d", 1, reader.currentLine) + } + if reader.currentTag != "" { + t.Errorf("expected empty string for currentTag, got %s", reader.currentTag) + } + if reader.currentValue != "" { + t.Errorf("expected empty string for currentValue, got %s", reader.currentValue) + } +} + +func TestReadyCanStripWhitespaceFromValue(t *testing.T) { + reader := &tvReader{} + err := reader.readNextLine("Tag: value ") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + if len(reader.tvList) != 1 || reader.tvList[0].tag != "Tag" || reader.tvList[0].value != "value" { + t.Errorf("got invalid tag/value list: %v", reader.tvList) + } +} + +func TestReadyCannotReadLineWithNoColon(t *testing.T) { + reader := &tvReader{} + err := reader.readNextLine("No colon should be an error") + if err == nil { + t.Errorf("should have gotten error when calling readNextLine") + } +} + +func TestReadyTextTagSwitchesToMidtext(t *testing.T) { + reader := &tvReader{} + err := reader.readNextLine("Tag: <text>This begins a multiline value") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + if len(reader.tvList) != 0 { + t.Errorf("expected empty tag/value list, got %v", reader.tvList) + } + if !reader.midtext { + t.Errorf("expected midtext to be true, got false") + } + if reader.currentLine != 1 { + t.Errorf("expected %d for currentLine, got %d", 1, reader.currentLine) + } + if reader.currentTag != "Tag" { + t.Errorf("expected %s for currentTag, got %s", "Tag", reader.currentTag) + } + if reader.currentValue != "This begins a multiline value\n" { + t.Errorf("expected %s for currentValue, got %s", "This begins a multiline value\n", reader.currentValue) + } +} + +func TestReadyTextTagAndClosingTagInOneLineFinishesRead(t *testing.T) { + reader := &tvReader{} + err := reader.readNextLine("Tag: <text>Just one line</text>") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + if len(reader.tvList) != 1 || reader.tvList[0].tag != "Tag" || reader.tvList[0].value != "Just one line" { + t.Errorf("got invalid tag/value list: %v", reader.tvList) + } + if reader.midtext { + t.Errorf("expected midtext to be false, got true") + } + if reader.currentLine != 1 { + t.Errorf("expected %d for currentLine, got %d", 1, reader.currentLine) + } + if reader.currentTag != "" { + t.Errorf("expected empty string for currentTag, got %s", reader.currentTag) + } + if reader.currentValue != "" { + t.Errorf("expected empty string for currentValue, got %s", reader.currentValue) + } +} + +func TestCanReadMultilineTextAcrossThreeLines(t *testing.T) { + reader := &tvReader{} + err := reader.readNextLine("Tag: <text>This value") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + err = reader.readNextLine("is three") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + err = reader.readNextLine("lines long</text>") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + + if len(reader.tvList) != 1 || reader.tvList[0].tag != "Tag" || reader.tvList[0].value != "This value\nis three\nlines long" { + t.Errorf("got invalid tag/value list: %v", reader.tvList) + } + if reader.midtext { + t.Errorf("expected midtext to be false, got true") + } + if reader.currentLine != 3 { + t.Errorf("expected %d for currentLine, got %d", 3, reader.currentLine) + } + if reader.currentTag != "" { + t.Errorf("expected empty string for currentTag, got %s", reader.currentTag) + } + if reader.currentValue != "" { + t.Errorf("expected empty string for currentValue, got %s", reader.currentValue) + } +} + +func TestMidtextContinuesIfNoClosingText(t *testing.T) { + reader := &tvReader{} + reader.midtext = true + reader.currentLine = 1 + reader.currentTag = "Multiline" + reader.currentValue = "First line\n" + + err := reader.readNextLine("Second line") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + + if len(reader.tvList) != 0 { + t.Errorf("expected empty tag/value list, got %v", reader.tvList) + } + if !reader.midtext { + t.Errorf("expected midtext to be true, got false") + } + if reader.currentLine != 2 { + t.Errorf("expected %d for currentLine, got %d", 2, reader.currentLine) + } + if reader.currentTag != "Multiline" { + t.Errorf("expected %s for currentTag, got %s", "Multiline", reader.currentTag) + } + if reader.currentValue != "First line\nSecond line\n" { + t.Errorf("expected %s for currentValue, got %s", "First line\nSecond line\n", reader.currentValue) + } +} + +func TestMidtextFinishesIfReachingClosingText(t *testing.T) { + reader := &tvReader{} + reader.midtext = true + reader.currentLine = 1 + reader.currentTag = "Multiline" + reader.currentValue = "First line\n" + + err := reader.readNextLine("Second line</text>") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + + if len(reader.tvList) != 1 || reader.tvList[0].tag != "Multiline" || reader.tvList[0].value != "First line\nSecond line" { + t.Errorf("got invalid tag/value list: %v", reader.tvList) + } + if reader.midtext { + t.Errorf("expected midtext to be false, got true") + } + if reader.currentLine != 2 { + t.Errorf("expected %d for currentLine, got %d", 2, reader.currentLine) + } + if reader.currentTag != "" { + t.Errorf("expected empty string for currentTag, got %s", reader.currentTag) + } + if reader.currentValue != "" { + t.Errorf("expected empty string for currentValue, got %s", reader.currentValue) + } +} + +func TestReadyIgnoresCommentLines(t *testing.T) { + reader := &tvReader{} + err := reader.readNextLine("# this is a comment") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + + if len(reader.tvList) != 0 { + t.Errorf("expected empty tag/value list, got %v", reader.tvList) + } + if reader.midtext { + t.Errorf("expected midtext to be false, got true") + } + if reader.currentLine != 1 { + t.Errorf("expected %d for currentLine, got %d", 1, reader.currentLine) + } + if reader.currentTag != "" { + t.Errorf("expected empty string for currentTag, got %s", reader.currentTag) + } + if reader.currentValue != "" { + t.Errorf("expected empty string for currentValue, got %s", reader.currentValue) + } +} + +func TestMidtextIncludesCommentLines(t *testing.T) { + reader := &tvReader{} + reader.midtext = true + reader.currentLine = 1 + reader.currentTag = "Multiline" + reader.currentValue = "First line\n" + + err := reader.readNextLine("# This is part of multiline text") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + + if len(reader.tvList) != 0 { + t.Errorf("expected empty tag/value list, got %v", reader.tvList) + } + if !reader.midtext { + t.Errorf("expected midtext to be true, got false") + } + if reader.currentLine != 2 { + t.Errorf("expected %d for currentLine, got %d", 2, reader.currentLine) + } + if reader.currentTag != "Multiline" { + t.Errorf("expected %s for currentTag, got %s", "Multiline", reader.currentTag) + } + if reader.currentValue != "First line\n# This is part of multiline text\n" { + t.Errorf("expected %s for currentValue, got %s", "First line\n# This is part of multiline text\n", reader.currentValue) + } +} + +func TestReadyIgnoresEmptyLines(t *testing.T) { + reader := &tvReader{} + err := reader.readNextLine("") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + + if len(reader.tvList) != 0 { + t.Errorf("expected empty tag/value list, got %v", reader.tvList) + } + if reader.midtext { + t.Errorf("expected midtext to be false, got true") + } + if reader.currentLine != 1 { + t.Errorf("expected %d for currentLine, got %d", 1, reader.currentLine) + } + if reader.currentTag != "" { + t.Errorf("expected empty string for currentTag, got %s", reader.currentTag) + } + if reader.currentValue != "" { + t.Errorf("expected empty string for currentValue, got %s", reader.currentValue) + } +} + +func TestMidtextIncludesEmptyLines(t *testing.T) { + reader := &tvReader{} + reader.midtext = true + reader.currentLine = 1 + reader.currentTag = "Multiline" + reader.currentValue = "First line\n" + + err := reader.readNextLine("") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + + if len(reader.tvList) != 0 { + t.Errorf("expected empty tag/value list, got %v", reader.tvList) + } + if !reader.midtext { + t.Errorf("expected midtext to be true, got false") + } + if reader.currentLine != 2 { + t.Errorf("expected %d for currentLine, got %d", 2, reader.currentLine) + } + if reader.currentTag != "Multiline" { + t.Errorf("expected %s for currentTag, got %s", "Multiline", reader.currentTag) + } + if reader.currentValue != "First line\n\n" { + t.Errorf("expected %s for currentValue, got %s", "First line\n\n", reader.currentValue) + } +} + +func TestReadyIgnoresWhitespaceOnlyLines(t *testing.T) { + reader := &tvReader{} + err := reader.readNextLine(" \t\t\t ") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + + if len(reader.tvList) != 0 { + t.Errorf("expected empty tag/value list, got %v", reader.tvList) + } + if reader.midtext { + t.Errorf("expected midtext to be false, got true") + } + if reader.currentLine != 1 { + t.Errorf("expected %d for currentLine, got %d", 1, reader.currentLine) + } + if reader.currentTag != "" { + t.Errorf("expected empty string for currentTag, got %s", reader.currentTag) + } + if reader.currentValue != "" { + t.Errorf("expected empty string for currentValue, got %s", reader.currentValue) + } +} + +func TestMidtextIncludesWhitespaceOnlyLines(t *testing.T) { + reader := &tvReader{} + reader.midtext = true + reader.currentLine = 1 + reader.currentTag = "Multiline" + reader.currentValue = "First line\n" + + err := reader.readNextLine(" \t\t ") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + + if len(reader.tvList) != 0 { + t.Errorf("expected empty tag/value list, got %v", reader.tvList) + } + if !reader.midtext { + t.Errorf("expected midtext to be true, got false") + } + if reader.currentLine != 2 { + t.Errorf("expected %d for currentLine, got %d", 2, reader.currentLine) + } + if reader.currentTag != "Multiline" { + t.Errorf("expected %s for currentTag, got %s", "Multiline", reader.currentTag) + } + if reader.currentValue != "First line\n \t\t \n" { + t.Errorf("expected %s for currentValue, got %s", "First line\n \t\t \n", reader.currentValue) + } +} + +func TestReadyIgnoresSpacesBeforeTag(t *testing.T) { + reader := &tvReader{} + err := reader.readNextLine(" \t Tag:value") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + if len(reader.tvList) != 1 || reader.tvList[0].tag != "Tag" || reader.tvList[0].value != "value" { + t.Errorf("got invalid tag/value list: %v", reader.tvList) + } + if reader.currentLine != 1 { + t.Errorf("expected %d for currentLine, got %d", 1, reader.currentLine) + } + if reader.currentTag != "" { + t.Errorf("expected empty string for currentTag, got %s", reader.currentTag) + } + if reader.currentValue != "" { + t.Errorf("expected empty string for currentValue, got %s", reader.currentValue) + } +} + +func TestReadyIgnoresSpacesBeforeCommentLines(t *testing.T) { + reader := &tvReader{} + err := reader.readNextLine(" \t\t # this is a comment") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + + if len(reader.tvList) != 0 { + t.Errorf("expected empty tag/value list, got %v", reader.tvList) + } + if reader.midtext { + t.Errorf("expected midtext to be false, got true") + } + if reader.currentLine != 1 { + t.Errorf("expected %d for currentLine, got %d", 1, reader.currentLine) + } + if reader.currentTag != "" { + t.Errorf("expected empty string for currentTag, got %s", reader.currentTag) + } + if reader.currentValue != "" { + t.Errorf("expected empty string for currentValue, got %s", reader.currentValue) + } +} + +func TestReadyIgnoresSpacesBetweenTagAndColon(t *testing.T) { + reader := &tvReader{} + err := reader.readNextLine("Tag \t :value") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + if len(reader.tvList) != 1 || reader.tvList[0].tag != "Tag" || reader.tvList[0].value != "value" { + t.Errorf("got invalid tag/value list: %v", reader.tvList) + } + if reader.currentLine != 1 { + t.Errorf("expected %d for currentLine, got %d", 1, reader.currentLine) + } + if reader.currentTag != "" { + t.Errorf("expected empty string for currentTag, got %s", reader.currentTag) + } + if reader.currentValue != "" { + t.Errorf("expected empty string for currentValue, got %s", reader.currentValue) + } +} + +func TestReadyIgnoresSpacesBetweenColonAndValue(t *testing.T) { + reader := &tvReader{} + err := reader.readNextLine("Tag: \t value") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + if len(reader.tvList) != 1 || reader.tvList[0].tag != "Tag" || reader.tvList[0].value != "value" { + t.Errorf("got invalid tag/value list: %v", reader.tvList) + } + if reader.currentLine != 1 { + t.Errorf("expected %d for currentLine, got %d", 1, reader.currentLine) + } + if reader.currentTag != "" { + t.Errorf("expected empty string for currentTag, got %s", reader.currentTag) + } + if reader.currentValue != "" { + t.Errorf("expected empty string for currentValue, got %s", reader.currentValue) + } +} + +func TestReadyIgnoresSpacesAfterEndOfValue(t *testing.T) { + reader := &tvReader{} + err := reader.readNextLine("Tag:value \t ") + if err != nil { + t.Errorf("got error when calling readNextLine: %v", err) + } + if len(reader.tvList) != 1 || reader.tvList[0].tag != "Tag" || reader.tvList[0].value != "value" { + t.Errorf("got invalid tag/value list: %v", reader.tvList) + } + if reader.currentLine != 1 { + t.Errorf("expected %d for currentLine, got %d", 1, reader.currentLine) + } + if reader.currentTag != "" { + t.Errorf("expected empty string for currentTag, got %s", reader.currentTag) + } + if reader.currentValue != "" { + t.Errorf("expected empty string for currentValue, got %s", reader.currentValue) + } +} |