goparsify/parser_test.go

183 lines
4.6 KiB
Go
Raw Normal View History

2017-08-07 12:07:29 +02:00
package goparsify
2017-08-06 06:31:35 +02:00
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestParsify(t *testing.T) {
t.Run("strings", func(t *testing.T) {
2017-08-07 10:25:23 +02:00
require.Equal(t, "ff", Parsify("ff")(InputString("ffooo")).Token)
2017-08-06 06:31:35 +02:00
})
t.Run("parsers", func(t *testing.T) {
2017-08-07 10:25:23 +02:00
require.Equal(t, "ff", Parsify(Chars("f"))(InputString("ffooo")).Token)
2017-08-06 06:31:35 +02:00
})
2017-08-06 07:43:23 +02:00
t.Run("parser funcs", func(t *testing.T) {
2017-08-07 10:25:23 +02:00
node := Parsify(func(p *State) *Node {
return &Node{Token: "hello"}
2017-08-06 15:32:10 +02:00
})(InputString("ffooo"))
2017-08-07 10:25:23 +02:00
require.Equal(t, "hello", node.Token)
2017-08-06 07:43:23 +02:00
})
2017-08-06 06:31:35 +02:00
t.Run("*parsers", func(t *testing.T) {
var parser Parser
parserfied := Parsify(&parser)
2017-08-06 15:32:10 +02:00
parser = Chars("f")
2017-08-06 06:31:35 +02:00
2017-08-06 15:32:10 +02:00
node := parserfied(InputString("ffooo"))
2017-08-07 10:25:23 +02:00
require.Equal(t, "ff", node.Token)
2017-08-06 06:31:35 +02:00
})
2017-08-06 07:43:23 +02:00
require.Panics(t, func() {
Parsify(1)
})
}
func TestParsifyAll(t *testing.T) {
parsers := ParsifyAll("ff", "gg")
2017-08-06 15:32:10 +02:00
result := parsers[0](InputString("ffooo"))
2017-08-07 10:25:23 +02:00
require.Equal(t, "ff", result.Token)
2017-08-06 07:43:23 +02:00
2017-08-06 15:32:10 +02:00
result = parsers[1](InputString("ffooo"))
2017-08-07 10:25:23 +02:00
require.Nil(t, result)
2017-08-06 06:31:35 +02:00
}
func TestExact(t *testing.T) {
t.Run("success", func(t *testing.T) {
2017-08-06 15:32:10 +02:00
node, ps := runParser("foobar", Exact("fo"))
2017-08-07 10:25:23 +02:00
require.Equal(t, "fo", node.Token)
2017-08-06 15:32:10 +02:00
require.Equal(t, "obar", ps.Get())
2017-08-06 06:31:35 +02:00
})
t.Run("error", func(t *testing.T) {
2017-08-06 15:32:10 +02:00
_, ps := runParser("foobar", Exact("bar"))
require.Equal(t, "bar", ps.Error.Expected)
require.Equal(t, 0, ps.Pos)
2017-08-06 06:31:35 +02:00
})
}
2017-08-06 15:32:10 +02:00
func TestChars(t *testing.T) {
2017-08-06 07:43:23 +02:00
t.Run("full match", func(t *testing.T) {
2017-08-06 15:32:10 +02:00
node, ps := runParser("foobar", Chars("a-z"))
2017-08-07 10:25:23 +02:00
require.Equal(t, "foobar", node.Token)
2017-08-06 15:32:10 +02:00
require.Equal(t, "", ps.Get())
require.False(t, ps.Errored())
2017-08-06 07:43:23 +02:00
})
t.Run("partial match", func(t *testing.T) {
2017-08-06 15:32:10 +02:00
node, ps := runParser("a1b2c3d4efg", Chars("1-4d-a"))
2017-08-07 10:25:23 +02:00
require.Equal(t, "a1b2c3d4", node.Token)
2017-08-06 15:32:10 +02:00
require.Equal(t, "efg", ps.Get())
require.False(t, ps.Errored())
2017-08-06 07:43:23 +02:00
})
t.Run("limited match", func(t *testing.T) {
2017-08-06 15:32:10 +02:00
node, ps := runParser("a1b2c3d4efg", Chars("1-4d-a", 1, 2))
2017-08-07 10:25:23 +02:00
require.Equal(t, "a1", node.Token)
2017-08-06 15:32:10 +02:00
require.Equal(t, "b2c3d4efg", ps.Get())
require.False(t, ps.Errored())
2017-08-06 07:43:23 +02:00
})
t.Run("no match", func(t *testing.T) {
2017-08-06 15:32:10 +02:00
_, ps := runParser("ffffff", Chars("0-9"))
require.Equal(t, "offset 0: Expected 0-9", ps.Error.Error())
require.Equal(t, 0, ps.Pos)
2017-08-06 07:43:23 +02:00
})
t.Run("no match with min", func(t *testing.T) {
2017-08-06 15:32:10 +02:00
_, ps := runParser("ffffff", Chars("0-9", 4))
require.Equal(t, "0-9", ps.Error.Expected)
require.Equal(t, 0, ps.Pos)
2017-08-06 07:43:23 +02:00
})
2017-08-06 15:32:10 +02:00
t.Run("test exact matches", func(t *testing.T) {
node, ps := runParser("aaff", Chars("abcd"))
2017-08-07 10:25:23 +02:00
require.Equal(t, "aa", node.Token)
2017-08-06 15:32:10 +02:00
require.Equal(t, 2, ps.Pos)
require.False(t, ps.Errored())
})
t.Run("test not matches", func(t *testing.T) {
node, ps := runParser("aaff", NotChars("ff"))
2017-08-07 10:25:23 +02:00
require.Equal(t, "aa", node.Token)
2017-08-06 15:32:10 +02:00
require.Equal(t, 2, ps.Pos)
require.False(t, ps.Errored())
2017-08-06 07:43:23 +02:00
})
require.Panics(t, func() {
2017-08-06 15:32:10 +02:00
Chars("a-b", 1, 2, 3)
2017-08-06 07:43:23 +02:00
})
}
func TestParseString(t *testing.T) {
2017-08-07 10:25:23 +02:00
Y := Map("hello", func(n *Node) *Node { return &Node{Result: n.Token} })
2017-08-06 07:43:23 +02:00
t.Run("partial match", func(t *testing.T) {
2017-08-07 10:25:23 +02:00
result, remaining, err := ParseString(Y, "hello world")
2017-08-06 09:02:39 +02:00
require.Equal(t, "hello", result)
2017-08-06 07:43:23 +02:00
require.Equal(t, " world", remaining)
require.NoError(t, err)
})
t.Run("error", func(t *testing.T) {
2017-08-07 10:25:23 +02:00
result, remaining, err := ParseString(Y, "world")
require.Nil(t, result)
require.Equal(t, "world", remaining)
2017-08-06 07:43:23 +02:00
require.Error(t, err)
2017-08-07 10:25:23 +02:00
require.Equal(t, "offset 0: Expected hello", err.Error())
2017-08-06 07:43:23 +02:00
})
2017-08-06 06:31:35 +02:00
}
2017-08-06 09:28:34 +02:00
func TestString(t *testing.T) {
t.Run("test basic match", func(t *testing.T) {
2017-08-06 15:32:10 +02:00
result, p := runParser(`"hello"`, String('"'))
2017-08-07 10:25:23 +02:00
require.Equal(t, `hello`, result.Token)
2017-08-06 09:28:34 +02:00
require.Equal(t, "", p.Get())
})
t.Run("test non match", func(t *testing.T) {
2017-08-06 15:32:10 +02:00
_, p := runParser(`1`, String('"'))
require.Equal(t, `"`, p.Error.Expected)
2017-08-06 09:28:34 +02:00
require.Equal(t, `1`, p.Get())
})
t.Run("test unterminated string", func(t *testing.T) {
2017-08-06 15:32:10 +02:00
_, p := runParser(`"hello `, String('"'))
require.Equal(t, `"`, p.Error.Expected)
2017-08-06 09:28:34 +02:00
require.Equal(t, `"hello `, p.Get())
})
t.Run("test escaping", func(t *testing.T) {
2017-08-06 15:32:10 +02:00
result, p := runParser(`"hello \"world\""`, String('"'))
2017-08-07 10:25:23 +02:00
require.Equal(t, `hello "world"`, result.Token)
2017-08-06 09:28:34 +02:00
require.Equal(t, ``, p.Get())
})
}
2017-08-06 15:32:10 +02:00
func TestWS(t *testing.T) {
t.Run("consumes all whitespace", func(t *testing.T) {
result, p := runParser(" asdf", WS)
2017-08-07 10:25:23 +02:00
require.Nil(t, result)
2017-08-06 15:32:10 +02:00
require.Equal(t, "asdf", p.Get())
require.False(t, p.Errored())
})
t.Run("never errors", func(t *testing.T) {
result, p := runParser("asdf", WS)
2017-08-07 10:25:23 +02:00
require.Nil(t, result)
2017-08-06 15:32:10 +02:00
require.Equal(t, "asdf", p.Get())
require.False(t, p.Errored())
})
}
2017-08-07 10:25:23 +02:00
func runParser(input string, parser Parser) (*Node, *State) {
2017-08-06 15:32:10 +02:00
ps := InputString(input)
result := parser(ps)
return result, ps
}