fspl/lexer/test-common.go
2024-01-25 08:27:18 +00:00

124 lines
2.6 KiB
Go

package lexer
import "fmt"
import "testing"
import "strings"
import "github.com/alecthomas/participle/v2"
import "github.com/alecthomas/participle/v2/lexer"
func tok (ty lexer.TokenType, value string) lexer.Token {
return lexer.Token {
Type: ty,
Value: value,
}
}
func testString (
test *testing.T,
input string,
correct ...lexer.Token,
) {
testStringErr(test, "", 0, 0, input, correct...)
}
func testStringErr (
test *testing.T,
errMessage string,
errLine int,
errColumn int,
input string,
correct ...lexer.Token,
) {
testError := func (err error) bool {
got := err.(participle.Error)
gotMessage := got.Message()
gotLine := got.Position().Line
gotColumn := got.Position().Column
correct :=
gotMessage == errMessage &&
gotLine == errLine &&
gotColumn == errColumn
if !correct {
test.Log("errors do not match")
test.Logf("got:\n%v:%v: %v", gotLine, gotColumn, gotMessage)
test.Logf("correct:\n%v:%v: %v", errLine, errColumn, errMessage)
test.Fail()
}
return correct
}
reader := strings.NewReader(input)
lx, err := NewDefinition().Lex("stream0.fspl", reader)
if err != nil {
if errMessage == "" {
test.Error("lexer returned error: ", err)
return
} else {
if !testError(err) { return }
}
}
var tokens []lexer.Token
for {
got, err := lx.Next()
tokens = append(tokens, got)
if got.EOF() { break }
if err != nil {
if errMessage == "" {
test.Error("lexer returned error: ", err)
return
} else {
if !testError(err) { return }
}
break
}
}
printColumns := func (left, right string) {
test.Logf("%-40v | %-40v", left, right)
}
dumpToken := func (token lexer.Token) string {
return fmt.Sprintf("%4v: \"%s\"", token.Type, token.Value)
}
compareTokens := func () {
length := len(tokens)
if len(correct) > length { length = len(correct) }
printColumns("CORRECT", "GOT")
for index := 0; index < length; index ++ {
left := "..."
right := "..."
if index < len(correct) {
left = dumpToken(correct[index])
}
if index < len(tokens) {
right = dumpToken(tokens[index])
}
printColumns(left, right)
}
}
if len(tokens) != len(correct) {
test.Logf (
"len(correct) and len(got) do not match (%v, %v)",
len(correct), len(tokens))
compareTokens()
test.Fail()
return
}
for index, token := range correct {
gotToken := tokens[index]
if token.Type != gotToken.Type || token.Value != gotToken.Value {
test.Logf("correct and got do not match at %v", index)
compareTokens()
test.Fail()
return
}
}
}