summaryrefslogtreecommitdiff
path: root/parser_test.go
diff options
context:
space:
mode:
authorAdam Scarr <adam@vektah.net>2017-08-06 23:32:10 +1000
committerAdam Scarr <adam@vektah.net>2017-08-06 23:32:10 +1000
commit666ea93dba377f267a2c8ecf97378a420db18383 (patch)
tree5efee0b6e4ccf44b854d9bb65e4e6fa5e7f86548 /parser_test.go
parent9d7779e8ca5404f26abbd8cce0314d9cee967bba (diff)
Eliminate a bunch of allocations
Diffstat (limited to 'parser_test.go')
-rw-r--r--parser_test.go171
1 files changed, 73 insertions, 98 deletions
diff --git a/parser_test.go b/parser_test.go
index 4d60781..f6122ab 100644
--- a/parser_test.go
+++ b/parser_test.go
@@ -7,31 +7,29 @@ import (
)
func TestParsify(t *testing.T) {
- p := Pointer{"ffooo", 0}
t.Run("strings", func(t *testing.T) {
- node, _ := Parsify("ff")(p)
- require.Equal(t, "ff", node)
+ require.Equal(t, "ff", Parsify("ff")(InputString("ffooo")))
})
t.Run("parsers", func(t *testing.T) {
- node, _ := Parsify(CharRun("f"))(p)
- require.Equal(t, "ff", node)
+ require.Equal(t, "ff", Parsify(Chars("f"))(InputString("ffooo")))
})
t.Run("parser funcs", func(t *testing.T) {
- node, _ := Parsify(func(p Pointer) (Node, Pointer) {
- return "hello", p
- })(p)
+ node := Parsify(func(p *State) interface{} {
+ return "hello"
+ })(InputString("ffooo"))
+
require.Equal(t, "hello", node)
})
t.Run("*parsers", func(t *testing.T) {
var parser Parser
parserfied := Parsify(&parser)
- parser = CharRun("f")
+ parser = Chars("f")
- node, _ := parserfied(p)
+ node := parserfied(InputString("ffooo"))
require.Equal(t, "ff", node)
})
@@ -43,122 +41,77 @@ func TestParsify(t *testing.T) {
func TestParsifyAll(t *testing.T) {
parsers := ParsifyAll("ff", "gg")
- result, _ := parsers[0](Pointer{"ffooo", 0})
+ result := parsers[0](InputString("ffooo"))
require.Equal(t, "ff", result)
- result, _ = parsers[1](Pointer{"ffooo", 0})
- require.Equal(t, NewError(0, "Expected gg"), result)
+ result = parsers[1](InputString("ffooo"))
+ require.Equal(t, nil, result)
}
func TestExact(t *testing.T) {
- p := Pointer{"fooo", 0}
-
t.Run("success", func(t *testing.T) {
- node, p2 := Exact("fo")(p)
+ node, ps := runParser("foobar", Exact("fo"))
require.Equal(t, "fo", node)
- require.Equal(t, p.Advance(2), p2)
- })
-
- t.Run("error", func(t *testing.T) {
- node, p2 := Exact("bar")(p)
- require.Equal(t, NewError(0, "Expected bar"), node)
- require.Equal(t, 0, p2.pos)
- })
-}
-
-func TestChar(t *testing.T) {
- p := Pointer{"foobar", 0}
-
- t.Run("success", func(t *testing.T) {
- node, p2 := Char("fo")(p)
- require.Equal(t, "f", node)
- require.Equal(t, p.Advance(1), p2)
+ require.Equal(t, "obar", ps.Get())
})
t.Run("error", func(t *testing.T) {
- node, p2 := Char("bar")(p)
- require.Equal(t, NewError(0, "Expected one of bar"), node)
- require.Equal(t, 0, p2.pos)
+ _, ps := runParser("foobar", Exact("bar"))
+ require.Equal(t, "bar", ps.Error.Expected)
+ require.Equal(t, 0, ps.Pos)
})
}
-func TestCharRun(t *testing.T) {
- p := Pointer{"foobar", 0}
-
- t.Run("success", func(t *testing.T) {
- node, p2 := CharRun("fo")(p)
- require.Equal(t, "foo", node)
- require.Equal(t, p.Advance(3), p2)
- })
-
- t.Run("error", func(t *testing.T) {
- node, p2 := CharRun("bar")(p)
- require.Equal(t, NewError(0, "Expected some of bar"), node)
- require.Equal(t, 0, p2.pos)
- })
-}
-
-func TestCharUntil(t *testing.T) {
- p := Pointer{"foobar", 0}
-
- t.Run("success", func(t *testing.T) {
- node, p2 := CharRunUntil("z")(p)
- require.Equal(t, "foobar", node)
- require.Equal(t, p.Advance(6), p2)
- })
-
- t.Run("error", func(t *testing.T) {
- node, p2 := CharRunUntil("f")(p)
- require.Equal(t, NewError(0, "Expected some of f"), node)
- require.Equal(t, 0, p2.pos)
- })
-}
-
-func TestWS(t *testing.T) {
- p := Pointer{" fooo", 0}
-
- node, p2 := WS(p)
- require.Equal(t, nil, node)
- require.Equal(t, p.Advance(2), p2)
-}
-
-func TestRange(t *testing.T) {
+func TestChars(t *testing.T) {
t.Run("full match", func(t *testing.T) {
- node, p := Range("a-z")(Pointer{"foobar", 0})
+ node, ps := runParser("foobar", Chars("a-z"))
require.Equal(t, "foobar", node)
- require.Equal(t, "", p.Get())
+ require.Equal(t, "", ps.Get())
+ require.False(t, ps.Errored())
})
t.Run("partial match", func(t *testing.T) {
- node, p := Range("1-4d-a")(Pointer{"a1b2c3d4efg", 0})
+ node, ps := runParser("a1b2c3d4efg", Chars("1-4d-a"))
require.Equal(t, "a1b2c3d4", node)
- require.Equal(t, "efg", p.Get())
+ require.Equal(t, "efg", ps.Get())
+ require.False(t, ps.Errored())
})
t.Run("limited match", func(t *testing.T) {
- node, p := Range("1-4d-a", 1, 2)(Pointer{"a1b2c3d4efg", 0})
+ node, ps := runParser("a1b2c3d4efg", Chars("1-4d-a", 1, 2))
require.Equal(t, "a1", node)
- require.Equal(t, "b2c3d4efg", p.Get())
+ require.Equal(t, "b2c3d4efg", ps.Get())
+ require.False(t, ps.Errored())
})
t.Run("no match", func(t *testing.T) {
- node, p := Range("0-9")(Pointer{"ffffff", 0})
- require.Equal(t, NewError(0, "Expected at least 1 more of 0-9"), node)
- require.Equal(t, 0, p.pos)
+ _, ps := runParser("ffffff", Chars("0-9"))
+ require.Equal(t, "offset 0: Expected 0-9", ps.Error.Error())
+ require.Equal(t, 0, ps.Pos)
})
t.Run("no match with min", func(t *testing.T) {
- node, p := Range("0-9", 4)(Pointer{"ffffff", 0})
- require.Equal(t, NewError(0, "Expected at least 4 more of 0-9"), node)
- require.Equal(t, 0, p.pos)
+ _, ps := runParser("ffffff", Chars("0-9", 4))
+ require.Equal(t, "0-9", ps.Error.Expected)
+ require.Equal(t, 0, ps.Pos)
})
- require.Panics(t, func() {
- Range("abcd")
+ t.Run("test exact matches", func(t *testing.T) {
+ node, ps := runParser("aaff", Chars("abcd"))
+ require.Equal(t, "aa", node)
+ 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"))
+ require.Equal(t, "aa", node)
+ require.Equal(t, 2, ps.Pos)
+ require.False(t, ps.Errored())
})
require.Panics(t, func() {
- Range("a-b", 1, 2, 3)
+ Chars("a-b", 1, 2, 3)
})
}
@@ -181,26 +134,48 @@ func TestParseString(t *testing.T) {
func TestString(t *testing.T) {
t.Run("test basic match", func(t *testing.T) {
- result, p := String('"')(Pointer{`"hello"`, 0})
+ result, p := runParser(`"hello"`, String('"'))
require.Equal(t, `hello`, result)
require.Equal(t, "", p.Get())
})
t.Run("test non match", func(t *testing.T) {
- result, p := String('"')(Pointer{`1`, 0})
- require.Equal(t, NewError(0, `Expected "`), result)
+ _, p := runParser(`1`, String('"'))
+ require.Equal(t, `"`, p.Error.Expected)
require.Equal(t, `1`, p.Get())
})
t.Run("test unterminated string", func(t *testing.T) {
- result, p := String('"')(Pointer{`"hello `, 0})
- require.Equal(t, NewError(0, `Unterminated string`), result)
+ _, p := runParser(`"hello `, String('"'))
+ require.Equal(t, `"`, p.Error.Expected)
require.Equal(t, `"hello `, p.Get())
})
t.Run("test escaping", func(t *testing.T) {
- result, p := String('"')(Pointer{`"hello \"world\""`, 0})
+ result, p := runParser(`"hello \"world\""`, String('"'))
require.Equal(t, `hello "world"`, result)
require.Equal(t, ``, p.Get())
})
}
+
+func TestWS(t *testing.T) {
+ t.Run("consumes all whitespace", func(t *testing.T) {
+ result, p := runParser(" asdf", WS)
+ require.Equal(t, nil, result)
+ require.Equal(t, "asdf", p.Get())
+ require.False(t, p.Errored())
+ })
+
+ t.Run("never errors", func(t *testing.T) {
+ result, p := runParser("asdf", WS)
+ require.Equal(t, nil, result)
+ require.Equal(t, "asdf", p.Get())
+ require.False(t, p.Errored())
+ })
+}
+
+func runParser(input string, parser Parser) (interface{}, *State) {
+ ps := InputString(input)
+ result := parser(ps)
+ return result, ps
+}