treerack/parse_test.go

750 lines
11 KiB
Go
Raw Normal View History

2017-07-15 21:49:08 +02:00
package treerack
2017-06-25 17:51:08 +02:00
2018-01-06 21:30:07 +01:00
import (
"bufio"
"bytes"
"testing"
)
2017-06-25 17:51:08 +02:00
func TestRecursion(t *testing.T) {
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" | A "a"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "recursion in choice, right, left, commit",
text: "aaa",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
Nodes: []*Node{{
Name: "A",
Nodes: []*Node{{
Name: "A",
}},
}},
},
ignorePosition: true,
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" | "a" A`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "recursion in choice, right, right, commit",
text: "aaa",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
Nodes: []*Node{{
Name: "A",
Nodes: []*Node{{
Name: "A",
}},
}},
},
ignorePosition: true,
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" A | "a"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "recursion in choice, left, right, commit",
text: "aaa",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
Nodes: []*Node{{
Name: "A",
Nodes: []*Node{{
Name: "A",
}},
}},
},
ignorePosition: true,
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = A "a" | "a"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "recursion in choice, left, left, commit",
text: "aaa",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
Nodes: []*Node{{
Name: "A",
Nodes: []*Node{{
Name: "A",
}},
}},
},
ignorePosition: true,
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A':alias = "a" | A' "a"; A = A'`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "recursion in choice, right, left, alias",
text: "aaa",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 3,
2017-06-25 17:51:08 +02:00
},
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A':alias = "a" | "a" A'; A = A'`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "recursion in choice, right, right, alias",
text: "aaa",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 3,
2017-06-25 17:51:08 +02:00
},
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A':alias = "a" A' | "a"; A = A'`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "recursion in choice, left, right, alias",
text: "aaa",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 3,
2017-06-25 17:51:08 +02:00
},
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A':alias = A' "a" | "a"; A = A'`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "recursion in choice, left, left, alias",
text: "aaa",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 3,
2017-06-25 17:51:08 +02:00
},
}},
)
runTests(
t,
`A = "a" | A*`,
[]testItem{{
title: "recursive sequence in choice",
text: "aaaa",
ignorePosition: true,
node: &Node{
Name: "A",
Nodes: []*Node{{
Name: "A",
}, {
Name: "A",
Nodes: []*Node{{
Name: "A",
}, {
Name: "A",
Nodes: []*Node{{
Name: "A",
}, {
Name: "A",
}},
}},
}},
},
}},
)
2017-06-25 17:51:08 +02:00
}
func TestSequence(t *testing.T) {
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`AB = "a" | "a"? "a"? "b" "b"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "sequence with optional items",
text: "abb",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "AB",
2017-06-26 01:21:46 +02:00
To: 3,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "sequence with optional items, none",
text: "bb",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "AB",
2017-06-26 01:21:46 +02:00
To: 2,
2017-06-25 17:51:08 +02:00
},
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" | (A?)*`,
[]testItem{{
2017-10-28 16:54:06 +02:00
title: "recursive sequence in choice with redundant quantifier",
2017-10-27 17:25:20 +02:00
text: "aaa",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
Nodes: []*Node{{
Name: "A",
}, {
Name: "A",
}, {
Name: "A",
}},
},
ignorePosition: true,
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = ("a"*)*`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "sequence with redundant quantifier",
text: "aaa",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 3,
2017-06-25 17:51:08 +02:00
},
}},
)
2017-10-28 16:54:06 +02:00
runTests(
t,
`a = "a"?; A = a | a*`,
2017-10-28 16:54:06 +02:00
[]testItem{{
title: "single or zero-or-more optional in choice",
text: "aaa",
ignorePosition: true,
2017-10-28 16:54:06 +02:00
node: &Node{
Name: "A",
Nodes: []*Node{{
Name: "a",
2017-10-28 16:54:06 +02:00
}, {
Name: "a",
2017-10-28 16:54:06 +02:00
}, {
Name: "a",
2017-10-28 16:54:06 +02:00
}},
},
}},
)
2017-11-05 03:28:36 +01:00
runTests(
t,
`a = "a"{3,5}`,
[]testItem{{
title: "less than min",
text: "aa",
fail: true,
}, {
title: "just min",
text: "aaa",
ignorePosition: true,
node: &Node{
Name: "a",
},
}, {
title: "less than max",
text: "aaaa",
ignorePosition: true,
node: &Node{
Name: "a",
},
}, {
title: "just max",
text: "aaaaa",
ignorePosition: true,
node: &Node{
Name: "a",
},
}, {
title: "more than max",
text: "aaaaaa",
fail: true,
}},
)
2017-10-28 16:54:06 +02:00
}
2017-06-25 17:51:08 +02:00
func TestQuantifiers(t *testing.T) {
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" "b"{0} "a"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "zero, considered as one",
text: "aba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 3,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "zero, fail",
text: "aa",
fail: true,
2017-06-25 17:51:08 +02:00
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" "b"{1} "a"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "one, missing",
text: "aa",
fail: true,
2017-06-25 17:51:08 +02:00
}, {
2017-10-27 17:25:20 +02:00
title: "one",
text: "aba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 3,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "one, too much",
text: "abba",
fail: true,
2017-06-25 17:51:08 +02:00
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" "b"{3} "a"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "three, missing",
text: "abba",
fail: true,
2017-06-25 17:51:08 +02:00
}, {
2017-10-27 17:25:20 +02:00
title: "three",
text: "abbba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 5,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "three, too much",
text: "abbbba",
fail: true,
2017-06-25 17:51:08 +02:00
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" "b"{0,1} "a"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "zero or one explicit, missing",
text: "aa",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 2,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "zero or one explicit",
text: "aba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 3,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "zero or one explicit, too much",
text: "abba",
fail: true,
2017-06-25 17:51:08 +02:00
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" "b"{,1} "a"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "zero or one explicit, omit zero, missing",
text: "aa",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 2,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "zero or one explicit, omit zero",
text: "aba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 3,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "zero or one explicit, omit zero, too much",
text: "abba",
fail: true,
2017-06-25 17:51:08 +02:00
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" "b"? "a"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "zero or one explicit, shortcut, missing",
text: "aa",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 2,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "zero or one explicit, shortcut",
text: "aba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 3,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "zero or one explicit, shortcut, too much",
text: "abba",
fail: true,
2017-06-25 17:51:08 +02:00
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" "b"{0,3} "a"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "zero or three, missing",
text: "aa",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 2,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "zero or three",
text: "abba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 4,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "zero or three",
text: "abbba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 5,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "zero or three, too much",
text: "abbbba",
fail: true,
2017-06-25 17:51:08 +02:00
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" "b"{,3} "a"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "zero or three, omit zero, missing",
text: "aa",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 2,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "zero or three, omit zero",
text: "abba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 4,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "zero or three, omit zero",
text: "abbba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 5,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "zero or three, omit zero, too much",
text: "abbbba",
fail: true,
2017-06-25 17:51:08 +02:00
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" "b"{1,3} "a"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "one or three, missing",
text: "aa",
fail: true,
2017-06-25 17:51:08 +02:00
}, {
2017-10-27 17:25:20 +02:00
title: "one or three",
text: "abba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 4,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "one or three",
text: "abbba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 5,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "one or three, too much",
text: "abbbba",
fail: true,
2017-06-25 17:51:08 +02:00
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" "b"{3,5} "a"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "three or five, missing",
text: "abba",
fail: true,
2017-06-25 17:51:08 +02:00
}, {
2017-10-27 17:25:20 +02:00
title: "three or five",
text: "abbbba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 6,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "three or five",
text: "abbbbba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 7,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "three or five, too much",
text: "abbbbbba",
fail: true,
2017-06-25 17:51:08 +02:00
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" "b"{0,} "a"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "zero or more, explicit, missing",
text: "aa",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 2,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "zero or more, explicit",
text: "abba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 4,
2017-06-25 17:51:08 +02:00
},
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" "b"* "a"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "zero or more, shortcut, missing",
text: "aa",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 2,
2017-06-25 17:51:08 +02:00
},
}, {
2017-10-27 17:25:20 +02:00
title: "zero or more, shortcut",
text: "abba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 4,
2017-06-25 17:51:08 +02:00
},
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" "b"{1,} "a"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "one or more, explicit, missing",
text: "aa",
fail: true,
2017-06-25 17:51:08 +02:00
}, {
2017-10-27 17:25:20 +02:00
title: "one or more, explicit",
text: "abba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 4,
2017-06-25 17:51:08 +02:00
},
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" "b"+ "a"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "one or more, shortcut, missing",
text: "aa",
fail: true,
2017-06-25 17:51:08 +02:00
}, {
2017-10-27 17:25:20 +02:00
title: "one or more, shortcut",
text: "abba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 4,
2017-06-25 17:51:08 +02:00
},
}},
)
2017-10-27 17:25:20 +02:00
runTests(
2017-06-25 17:51:08 +02:00
t,
`A = "a" "b"{3,} "a"`,
[]testItem{{
2017-10-27 17:25:20 +02:00
title: "three or more, explicit, missing",
text: "abba",
fail: true,
2017-06-25 17:51:08 +02:00
}, {
2017-10-27 17:25:20 +02:00
title: "three or more, explicit",
text: "abbbba",
2017-06-25 17:51:08 +02:00
node: &Node{
Name: "A",
2017-06-26 01:21:46 +02:00
To: 6,
2017-06-25 17:51:08 +02:00
},
}},
)
}
2017-10-28 16:54:06 +02:00
func TestEmpty(t *testing.T) {
runTests(
t,
`A = "1"`,
[]testItem{{
title: "empty primitive, fail",
fail: true,
}},
)
runTests(
t,
`A = "1"?`,
[]testItem{{
title: "empty primitive, succeed",
}},
)
runTests(
t,
`a = "1"?; A = a a`,
[]testItem{{
title: "empty document with quantifiers in the item",
node: &Node{
Name: "A",
Nodes: []*Node{{
Name: "a",
}, {
Name: "a",
}},
},
}},
)
runTests(
t,
`a = "1"; A = a? a?`,
[]testItem{{
title: "empty document with quantifiers in the reference",
node: &Node{
Name: "A",
},
}},
)
runTests(
t,
`a = [a]*; a':alias = a; a'' = a' [^a]*`,
[]testItem{{
title: "no a",
text: "b",
ignorePosition: true,
node: &Node{
Name: "a''",
Nodes: []*Node{{
Name: "a",
}},
},
}},
)
2017-10-28 16:54:06 +02:00
}
2017-10-28 23:18:53 +02:00
func TestCharAsRoot(t *testing.T) {
runTests(
t,
`A = "a"`,
[]testItem{{
title: "char as root",
text: "a",
ignorePosition: true,
node: &Node{
Name: "A",
},
}},
)
}
2017-11-05 03:28:36 +01:00
func TestPartialRead(t *testing.T) {
runTests(
t,
`A = "a"`,
[]testItem{{
title: "document finished before eof",
text: "ab",
fail: true,
}},
)
runTests(
t,
`A = "a"*`,
[]testItem{{
title: "document finished before eof with reading past",
text: "ab",
fail: true,
}},
)
}
2017-11-26 00:52:08 +01:00
func TestChoiceSequencePriority(t *testing.T) {
runTests(
t,
`A = "a" | "b" "c"`,
[]testItem{{
title: "ac",
text: "ac",
fail: true,
}},
)
runTests(
t,
`A = "a" | "b" "c"`,
[]testItem{{
title: "bc",
text: "bc",
ignorePosition: true,
node: &Node{Name: "A"},
}},
)
}
2018-01-06 21:30:07 +01:00
func TestCharBuildNoop(t *testing.T) {
c := newChar("foo", false, nil, nil)
c.init(newRegistry())
b := c.builder()
2019-02-02 18:07:10 +01:00
ctx := newContext(bufio.NewReader(bytes.NewBuffer(nil)), nil)
2018-01-06 21:30:07 +01:00
if n, ok := b.build(ctx); len(n) != 0 || ok {
t.Error("char build not noop")
}
}