Commit 05d8d112 authored by Andrew Balholm's avatar Andrew Balholm Committed by Nigel Tao

html: refactor parse test infrastructure

My excuse for doing this is that test cases with newlines in them didn't
work. But instead of just fixing that, I rearranged everything in
parse_test.go to use fewer channels and pipes, and just call a
straightforward function to read test cases from a file.

R=nigeltao
CC=golang-dev
https://golang.org/cl/5410049
parent dbb591d8
...@@ -10,65 +10,65 @@ import ( ...@@ -10,65 +10,65 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"os" "os"
"strings" "strings"
"testing" "testing"
) )
func pipeErr(err error) io.Reader { // readParseTest reads a single test case from r.
pr, pw := io.Pipe() func readParseTest(r *bufio.Reader) (text, want string, err error) {
pw.CloseWithError(err) line, err := r.ReadSlice('\n')
return pr
}
func readDat(filename string, c chan io.Reader) {
defer close(c)
f, err := os.Open("testdata/webkit/" + filename)
if err != nil { if err != nil {
c <- pipeErr(err) return "", "", err
return
} }
defer f.Close() var b []byte
// Loop through the lines of the file. Each line beginning with "#" denotes // Read the HTML.
// a new section, which is returned as a separate io.Reader. if string(line) != "#data\n" {
r := bufio.NewReader(f) return "", "", fmt.Errorf(`got %q want "#data\n"`, line)
var pw *io.PipeWriter }
for { for {
line, err := r.ReadSlice('\n') line, err = r.ReadSlice('\n')
if err != nil { if err != nil {
if pw != nil { return "", "", err
pw.CloseWithError(err)
pw = nil
} else {
c <- pipeErr(err)
} }
return if line[0] == '#' {
break
} }
if len(line) == 0 { b = append(b, line...)
continue }
text = strings.TrimRight(string(b), "\n")
b = b[:0]
// Skip the error list.
if string(line) != "#errors\n" {
return "", "", fmt.Errorf(`got %q want "#errors\n"`, line)
}
for {
line, err = r.ReadSlice('\n')
if err != nil {
return "", "", err
} }
if line[0] == '#' { if line[0] == '#' {
if pw != nil { break
pw.Close()
} }
var pr *io.PipeReader
pr, pw = io.Pipe()
c <- pr
continue
} }
if line[0] != '|' {
// Strip the trailing '\n'. // Read the dump of what the parse tree should be.
line = line[:len(line)-1] if string(line) != "#document\n" {
return "", "", fmt.Errorf(`got %q want "#document\n"`, line)
} }
if pw != nil { for {
if _, err := pw.Write(line); err != nil { line, err = r.ReadSlice('\n')
pw.CloseWithError(err) if err != nil && err != io.EOF {
pw = nil return "", "", err
} }
if len(line) == 0 || len(line) == 1 && line[0] == '\n' {
break
} }
b = append(b, line...)
} }
return text, string(b), nil
} }
func dumpIndent(w io.Writer, level int) { func dumpIndent(w io.Writer, level int) {
...@@ -93,7 +93,7 @@ func dumpLevel(w io.Writer, n *Node, level int) error { ...@@ -93,7 +93,7 @@ func dumpLevel(w io.Writer, n *Node, level int) error {
fmt.Fprintf(w, `%s="%s"`, a.Key, a.Val) fmt.Fprintf(w, `%s="%s"`, a.Key, a.Val)
} }
case TextNode: case TextNode:
fmt.Fprintf(w, "%q", n.Data) fmt.Fprintf(w, `"%s"`, n.Data)
case CommentNode: case CommentNode:
fmt.Fprintf(w, "<!-- %s -->", n.Data) fmt.Fprintf(w, "<!-- %s -->", n.Data)
case DoctypeNode: case DoctypeNode:
...@@ -134,23 +134,24 @@ func TestParser(t *testing.T) { ...@@ -134,23 +134,24 @@ func TestParser(t *testing.T) {
}{ }{
// TODO(nigeltao): Process all the test cases from all the .dat files. // TODO(nigeltao): Process all the test cases from all the .dat files.
{"tests1.dat", -1}, {"tests1.dat", -1},
{"tests2.dat", 43}, {"tests2.dat", 47},
{"tests3.dat", 0}, {"tests3.dat", 0},
} }
for _, tf := range testFiles { for _, tf := range testFiles {
rc := make(chan io.Reader) f, err := os.Open("testdata/webkit/" + tf.filename)
go readDat(tf.filename, rc) if err != nil {
t.Fatal(err)
}
defer f.Close()
r := bufio.NewReader(f)
for i := 0; i != tf.n; i++ { for i := 0; i != tf.n; i++ {
// Parse the #data section. text, want, err := readParseTest(r)
dataReader := <-rc if err == io.EOF && tf.n == -1 {
if dataReader == nil {
break break
} }
b, err := ioutil.ReadAll(dataReader)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
text := string(b)
doc, err := Parse(strings.NewReader(text)) doc, err := Parse(strings.NewReader(text))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
...@@ -159,16 +160,8 @@ func TestParser(t *testing.T) { ...@@ -159,16 +160,8 @@ func TestParser(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
// Skip the #error section.
if _, err := io.Copy(ioutil.Discard, <-rc); err != nil {
t.Fatal(err)
}
// Compare the parsed tree to the #document section. // Compare the parsed tree to the #document section.
b, err = ioutil.ReadAll(<-rc) if got != want {
if err != nil {
t.Fatal(err)
}
if want := string(b); got != want {
t.Errorf("%s test #%d %q, got vs want:\n----\n%s----\n%s----", tf.filename, i, text, got, want) t.Errorf("%s test #%d %q, got vs want:\n----\n%s----\n%s----", tf.filename, i, text, got, want)
continue continue
} }
...@@ -193,12 +186,6 @@ func TestParser(t *testing.T) { ...@@ -193,12 +186,6 @@ func TestParser(t *testing.T) {
continue continue
} }
} }
// Drain any untested cases for the test file.
for r := range rc {
if _, err := ioutil.ReadAll(r); err != nil {
t.Fatal(err)
}
}
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment