132 lines
3.5 KiB
Go
132 lines
3.5 KiB
Go
package parsekit_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"git.makaay.nl/mauricem/go-parsekit"
|
|
)
|
|
|
|
func TestAtoms(t *testing.T) {
|
|
for i, c := range []struct {
|
|
input string
|
|
matcher parsekit.Matcher
|
|
mustMatch bool
|
|
}{
|
|
{"", a.EndOfFile, true},
|
|
{"⌘", a.AnyRune, true},
|
|
{"\xbc", a.AnyRune, false}, // invalid UTF8 rune
|
|
{"", a.AnyRune, false}, // end of file
|
|
{" ", a.Space, true},
|
|
{"X", a.Space, false},
|
|
{"\t", a.Tab, true},
|
|
{"\r", a.CarriageRet, true},
|
|
{"\n", a.Newline, true},
|
|
{"!", a.Excl, true},
|
|
{"\"", a.DoubleQuote, true},
|
|
{"#", a.Hash, true},
|
|
{"$", a.Dollar, true},
|
|
{"%", a.Percent, true},
|
|
{"&", a.Amp, true},
|
|
{"'", a.SingleQuote, true},
|
|
{"(", a.RoundOpen, true},
|
|
{")", a.RoundClose, true},
|
|
{"*", a.Asterisk, true},
|
|
{"+", a.Plus, true},
|
|
{",", a.Comma, true},
|
|
{"-", a.Minus, true},
|
|
{".", a.Dot, true},
|
|
{"/", a.Slash, true},
|
|
{":", a.Colon, true},
|
|
{";", a.Semicolon, true},
|
|
{"<", a.AngleOpen, true},
|
|
{"=", a.Equal, true},
|
|
{">", a.AngleClose, true},
|
|
{"?", a.Question, true},
|
|
{"@", a.At, true},
|
|
{"[", a.SquareOpen, true},
|
|
{"\\", a.Backslash, true},
|
|
{"]", a.SquareClose, true},
|
|
{"^", a.Caret, true},
|
|
{"_", a.Underscore, true},
|
|
{"`", a.Backquote, true},
|
|
{"{", a.CurlyOpen, true},
|
|
{"|", a.Pipe, true},
|
|
{"}", a.CurlyClose, true},
|
|
{"~", a.Tilde, true},
|
|
{" \t \t ", a.Whitespace, true},
|
|
{" \t\r\n ", a.WhitespaceAndNewlines, true},
|
|
{"", a.EndOfLine, true},
|
|
{"\r\n", a.EndOfLine, true},
|
|
{"\n", a.EndOfLine, true},
|
|
{"0", a.Digit, true},
|
|
{"1", a.Digit, true},
|
|
{"2", a.Digit, true},
|
|
{"3", a.Digit, true},
|
|
{"4", a.Digit, true},
|
|
{"5", a.Digit, true},
|
|
{"6", a.Digit, true},
|
|
{"7", a.Digit, true},
|
|
{"8", a.Digit, true},
|
|
{"9", a.Digit, true},
|
|
{"X", a.Digit, false},
|
|
{"a", a.ASCIILower, true},
|
|
{"z", a.ASCIILower, true},
|
|
{"A", a.ASCIILower, false},
|
|
{"Z", a.ASCIILower, false},
|
|
{"A", a.ASCIIUpper, true},
|
|
{"Z", a.ASCIIUpper, true},
|
|
{"a", a.ASCIIUpper, false},
|
|
{"z", a.ASCIIUpper, false},
|
|
{"0", a.HexDigit, true},
|
|
{"9", a.HexDigit, true},
|
|
{"a", a.HexDigit, true},
|
|
{"f", a.HexDigit, true},
|
|
{"A", a.HexDigit, true},
|
|
{"F", a.HexDigit, true},
|
|
{"g", a.HexDigit, false},
|
|
{"G", a.HexDigit, false},
|
|
} {
|
|
parser := parsekit.New(c.input, func(p *parsekit.P) {
|
|
if p.On(c.matcher).Accept().End() {
|
|
p.EmitLiteral(SuccessItem)
|
|
} else {
|
|
p.EmitLiteral(FailItem)
|
|
}
|
|
})
|
|
item, err, ok := parser.Next()
|
|
if !ok {
|
|
t.Fatalf("Test [%d] %q failed with error: %s", i+1, c.input, err)
|
|
}
|
|
if c.mustMatch && item.Type != SuccessItem {
|
|
t.Fatalf("Test [%d] %q failed: should match, but it didn't", i+1, c.input)
|
|
}
|
|
if !c.mustMatch && item.Type != FailItem {
|
|
t.Fatalf("Test [%d] %q failed: should not match, but it did", i+1, c.input)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSequenceOfRunes(t *testing.T) {
|
|
sequence := c.Sequence(
|
|
a.Hash, a.Dollar, a.Percent, a.Amp, a.SingleQuote, a.RoundOpen,
|
|
a.RoundClose, a.Asterisk, a.Plus, a.Comma, a.Minus, a.Dot, a.Slash,
|
|
a.Colon, a.Semicolon, a.AngleOpen, a.Equal, a.AngleClose, a.Question,
|
|
a.At, a.SquareOpen, a.Backslash, a.SquareClose, a.Caret, a.Underscore,
|
|
a.Backquote, a.CurlyOpen, a.Pipe, a.CurlyClose, a.Tilde,
|
|
)
|
|
input := "#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
|
|
parser := parsekit.New(input, func(p *parsekit.P) {
|
|
p.Expects("Sequence of runes")
|
|
if p.On(sequence).Accept().End() {
|
|
p.EmitLiteral(TestItem)
|
|
}
|
|
})
|
|
item, err, ok := parser.Next()
|
|
if !ok {
|
|
t.Fatalf("Parsing failed: %s", err)
|
|
}
|
|
if item.Value != input {
|
|
t.Fatalf("Unexpected output from parser:\nexpected: %s\nactual: %s\n", input, item.Value)
|
|
}
|
|
}
|