Change parser interface to be more iterator-like

Call Next() to advance the parser state until it returns a non-nil
error, then check if the error is io.EOF. This makes EOF handling easier
and also means that Line() and PeekLine() can be called multiple times
without changing state.

The next step is to update parse functions to return an internal marker
error if they are called on an invalid line. This should improve
correctness and remove the duplication of testing a condition and then
calling a parse function, which checks the same condition.
This commit is contained in:
Billy Keyes
2019-03-24 22:03:53 -07:00
parent 699084298b
commit ccf0c58db8
4 changed files with 80 additions and 77 deletions
+18 -23
View File
@@ -17,19 +17,21 @@ func TestLineOperations(t *testing.T) {
t.Run("readLine", func(t *testing.T) {
p := newParser()
line, err := p.Line()
if err != nil {
t.Fatalf("error reading first line: %v", err)
if err := p.Next(); err != nil {
t.Fatalf("error advancing parser: %v", err)
}
line := p.Line()
if line != "the first line\n" {
t.Fatalf("incorrect first line: %s", line)
}
line, err = p.Line()
if err != nil {
t.Fatalf("error reading second line: %v", err)
if err := p.Next(); err != nil {
t.Fatalf("error advancing parser: %v", err)
}
if line != "the second line\n" {
line = p.Line()
if p.Line() != "the second line\n" {
t.Fatalf("incorrect second line: %s", line)
}
})
@@ -37,29 +39,22 @@ func TestLineOperations(t *testing.T) {
t.Run("peekLine", func(t *testing.T) {
p := newParser()
line, err := p.PeekLine()
if err != nil {
t.Fatalf("error peeking line: %v", err)
}
if line != "the first line\n" {
t.Fatalf("incorrect peek line: %s", line)
if err := p.Next(); err != nil {
t.Fatalf("error advancing parser: %v", err)
}
// test that a second peek returns the same value
line, err = p.PeekLine()
if err != nil {
t.Fatalf("error peeking line: %v", err)
}
if line != "the first line\n" {
line := p.PeekLine()
if line != "the second line\n" {
t.Fatalf("incorrect peek line: %s", line)
}
// test that reading the line returns the same value
line, err = p.Line()
if err != nil {
t.Fatalf("error reading line: %v", err)
if err := p.Next(); err != nil {
t.Fatalf("error advancing parser: %v", err)
}
if line != "the first line\n" {
line = p.Line()
if line != "the second line\n" {
t.Fatalf("incorrect line: %s", line)
}
})