Added a unit test for the actual parser loop issue that I ran into myself. This one will not bite me again!

This commit is contained in:
Maurice Makaay 2019-05-28 23:13:28 +00:00
parent d31d09abf0
commit 11883b06ac
1 changed files with 29 additions and 0 deletions

View File

@ -1,6 +1,7 @@
package parsekit_test package parsekit_test
import ( import (
"fmt"
"testing" "testing"
"git.makaay.nl/mauricem/go-parsekit" "git.makaay.nl/mauricem/go-parsekit"
@ -106,3 +107,31 @@ func TestGivenLoopingParserDefinition_ParserPanics(t *testing.T) {
"(*parserWithLoop).second at /home/ubuntu/Projects/Parsekit/go-parsekit" + "(*parserWithLoop).second at /home/ubuntu/Projects/Parsekit/go-parsekit" +
"/parsehandler_test.go, line 87"}) "/parsehandler_test.go, line 87"})
} }
// This test incorporates an actual loop bug that I dropped on myself and
// that I could not easily spot in my code. It sounded so logical:
// I want to get chunks of 5 chars from the input, so I simply loop on:
//
// p.On(c.Max(5, a.AnyRune))
//
// The problem here is that Max(5, ...) will also match when there is
// no more input, since Max(5, ---) is actually MinMax(0, 5, ...).
// Therefore the loop will never stop. Solving the loop was simple:
//
// p.On(c.MinMax(1, 5, a.AnyRune))
//
// Now the loop stops when the parser finds no more matching input data.
func TestGivenLoopingParserDefinition2_ParserPanics(t *testing.T) {
parser := parsekit.NewParser(func(p *parsekit.ParseAPI) {
for p.On(c.Max(5, a.AnyRune)).Accept() {
fmt.Printf("Cycle: %s\n", p.BufLiteral())
p.BufClear()
}
p.Stop()
})
RunPanicTest(t, PanicTest{
func() { parser.Execute("This will end soon") },
"Loop detected in parser in git.makaay.nl/mauricem/go-parsekit_test." +
"TestGivenLoopingParserDefinition2_ParserPanics.func1 at " +
"/home/ubuntu/Projects/Parsekit/go-parsekit/parsehandler_test.go, line 126"})
}