let's try file-based tests here too
parent
734d72c9a8
commit
45f56933a7
@ -1,151 +1,65 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
var parseTests = []parseTest{
|
func runParseTest(t *testing.T, basepath, inpath, outpath string) {
|
||||||
{
|
in, err := os.Open(inpath)
|
||||||
source: ``,
|
if err != nil {
|
||||||
root: &rootNode{
|
t.Errorf("unable to open input file %s: %s", inpath, err)
|
||||||
children: []node{},
|
return
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
source: `# just a comment`,
|
|
||||||
root: &rootNode{
|
|
||||||
children: []node{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
source: `name: "jordan"`,
|
|
||||||
root: &rootNode{
|
|
||||||
children: []node{
|
|
||||||
&assignmentNode{"name", "jordan"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
source: `
|
|
||||||
hostname: "jordanorelli.com"
|
|
||||||
port: 9000
|
|
||||||
freq: 1e9
|
|
||||||
duty: 0.2
|
|
||||||
neg: -2
|
|
||||||
neg2: -2.3
|
|
||||||
imag: 1+2i
|
|
||||||
`,
|
|
||||||
root: &rootNode{
|
|
||||||
children: []node{
|
|
||||||
&assignmentNode{"hostname", "jordanorelli.com"},
|
|
||||||
&assignmentNode{"port", 9000},
|
|
||||||
&assignmentNode{"freq", 1e9},
|
|
||||||
&assignmentNode{"duty", 0.2},
|
|
||||||
&assignmentNode{"neg", -2},
|
|
||||||
&assignmentNode{"neg2", -2.3},
|
|
||||||
&assignmentNode{"imag", 1 + 2i},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
source: `
|
|
||||||
first_name: "jordan" # yep, that's my name
|
|
||||||
last_name: "orelli" # comments should be able to follow other shit
|
|
||||||
`,
|
|
||||||
root: &rootNode{
|
|
||||||
children: []node{
|
|
||||||
&assignmentNode{"first_name", "jordan"},
|
|
||||||
&assignmentNode{"last_name", "orelli"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
source: `
|
|
||||||
heroes: ["lina" "cm"]
|
|
||||||
`,
|
|
||||||
root: &rootNode{
|
|
||||||
children: []node{
|
|
||||||
&assignmentNode{"heroes", list{"lina", "cm"}},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
source: `
|
|
||||||
nested: [["one" "two"] ["three" "four"]]
|
|
||||||
`,
|
|
||||||
root: &rootNode{
|
|
||||||
children: []node{
|
|
||||||
&assignmentNode{"nested", list{list{"one", "two"}, list{"three", "four"}}},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
source: `
|
|
||||||
nested: [
|
|
||||||
["one" "two"]
|
|
||||||
["three" "four"]
|
|
||||||
]
|
|
||||||
`,
|
|
||||||
root: &rootNode{
|
|
||||||
children: []node{
|
|
||||||
&assignmentNode{"nested", list{list{"one", "two"}, list{"three", "four"}}},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
source: `
|
|
||||||
admin: {first_name: "jordan" last_name: "orelli"}
|
|
||||||
`,
|
|
||||||
root: &rootNode{
|
|
||||||
children: []node{
|
|
||||||
&assignmentNode{"admin", object{
|
|
||||||
"first_name": "jordan",
|
|
||||||
"last_name": "orelli",
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
source: `
|
|
||||||
http: {
|
|
||||||
port: 9000
|
|
||||||
routes: "/path/to/some/file"
|
|
||||||
}
|
}
|
||||||
`,
|
defer in.Close()
|
||||||
root: &rootNode{
|
|
||||||
children: []node{
|
expected, err := ioutil.ReadFile(outpath)
|
||||||
&assignmentNode{"http", object{
|
if err != nil {
|
||||||
"port": 9000,
|
t.Errorf("unable to read expected output for %s: %s", outpath, err)
|
||||||
"routes": "/path/to/some/file",
|
return
|
||||||
}},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type parseTest struct {
|
r_inpath := filepath.Base(inpath)
|
||||||
source string
|
n, err := strconv.ParseInt(strings.TrimSuffix(r_inpath, ".in"), 0, 64)
|
||||||
root node
|
if err != nil {
|
||||||
|
t.Errorf("unable to get test number for path %s: %s", inpath, err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parseTest) run(t *testing.T) {
|
var buf bytes.Buffer
|
||||||
r := strings.NewReader(p.source)
|
root, err := parse(in)
|
||||||
n, err := parse(r)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("parse error: %v", err)
|
t.Logf("test %d: in: %s out: %s", n, inpath, outpath)
|
||||||
|
t.Errorf("parse error in test %d: %s", n, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(p.root, n) {
|
if err := root.pretty(&buf, ""); err != nil {
|
||||||
t.Errorf("trees are not equal. expected:\n%v\nsaw:\n%v", p.root, n)
|
t.Logf("test %d: in: %s out: %s", n, inpath, outpath)
|
||||||
} else {
|
t.Errorf("output error in test %d: %s", n, err)
|
||||||
t.Logf("OK trees are equal: %v = %v", p.root, n)
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal(buf.Bytes(), expected) {
|
||||||
|
t.Logf("test %d: in: %s out: %s", n, inpath, outpath)
|
||||||
|
t.Errorf("lex output does not match expected result for test %d", n)
|
||||||
|
t.Logf("expected output:\n%s", expected)
|
||||||
|
t.Logf("received output:\n%s", buf.Bytes())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParse(t *testing.T) {
|
func TestParse(t *testing.T) {
|
||||||
for _, test := range parseTests {
|
files, err := filepath.Glob("tests/parse/*.in")
|
||||||
test.run(t)
|
if err != nil {
|
||||||
|
t.Errorf("unable to find test files: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, fname := range files {
|
||||||
|
runParseTest(t, "tests/parse/", fname, strings.Replace(fname, "in", "out", -1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue