OSDN Git Service

d153533b588b45c7882ead30bc38da7876d982b1
[pf3gnuchains/gcc-fork.git] / libgo / go / html / parse_test.go
1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package html
6
7 import (
8         "bufio"
9         "bytes"
10         "fmt"
11         "io"
12         "io/ioutil"
13         "os"
14         "strings"
15         "testing"
16 )
17
18 type devNull struct{}
19
20 func (devNull) Write(p []byte) (int, os.Error) {
21         return len(p), nil
22 }
23
24 func pipeErr(err os.Error) io.Reader {
25         pr, pw := io.Pipe()
26         pw.CloseWithError(err)
27         return pr
28 }
29
30 func readDat(filename string, c chan io.Reader) {
31         f, err := os.Open("testdata/webkit/"+filename, os.O_RDONLY, 0600)
32         if err != nil {
33                 c <- pipeErr(err)
34                 return
35         }
36         defer f.Close()
37
38         // Loop through the lines of the file. Each line beginning with "#" denotes
39         // a new section, which is returned as a separate io.Reader.
40         r := bufio.NewReader(f)
41         var pw *io.PipeWriter
42         for {
43                 line, err := r.ReadSlice('\n')
44                 if err != nil {
45                         if pw != nil {
46                                 pw.CloseWithError(err)
47                                 pw = nil
48                         } else {
49                                 c <- pipeErr(err)
50                         }
51                         return
52                 }
53                 if len(line) == 0 {
54                         continue
55                 }
56                 if line[0] == '#' {
57                         if pw != nil {
58                                 pw.Close()
59                         }
60                         var pr *io.PipeReader
61                         pr, pw = io.Pipe()
62                         c <- pr
63                         continue
64                 }
65                 if line[0] != '|' {
66                         // Strip the trailing '\n'.
67                         line = line[:len(line)-1]
68                 }
69                 if pw != nil {
70                         if _, err := pw.Write(line); err != nil {
71                                 pw.CloseWithError(err)
72                                 pw = nil
73                         }
74                 }
75         }
76 }
77
78 func dumpLevel(w io.Writer, n *Node, level int) os.Error {
79         io.WriteString(w, "| ")
80         for i := 0; i < level; i++ {
81                 io.WriteString(w, "  ")
82         }
83         switch n.Type {
84         case ErrorNode:
85                 return os.NewError("unexpected ErrorNode")
86         case DocumentNode:
87                 return os.NewError("unexpected DocumentNode")
88         case ElementNode:
89                 fmt.Fprintf(w, "<%s>", EscapeString(n.Data))
90         case TextNode:
91                 fmt.Fprintf(w, "%q", EscapeString(n.Data))
92         case CommentNode:
93                 return os.NewError("COMMENT")
94         default:
95                 return os.NewError("unknown node type")
96         }
97         io.WriteString(w, "\n")
98         for _, c := range n.Child {
99                 if err := dumpLevel(w, c, level+1); err != nil {
100                         return err
101                 }
102         }
103         return nil
104 }
105
106 func dump(n *Node) (string, os.Error) {
107         if n == nil || len(n.Child) == 0 {
108                 return "", nil
109         }
110         b := bytes.NewBuffer(nil)
111         for _, child := range n.Child {
112                 if err := dumpLevel(b, child, 0); err != nil {
113                         return "", err
114                 }
115         }
116         return b.String(), nil
117 }
118
119 func TestParser(t *testing.T) {
120         // TODO(nigeltao): Process all the .dat files, not just the first one.
121         filenames := []string{
122                 "tests1.dat",
123         }
124         for _, filename := range filenames {
125                 rc := make(chan io.Reader)
126                 go readDat(filename, rc)
127                 // TODO(nigeltao): Process all test cases, not just a subset.
128                 for i := 0; i < 22; i++ {
129                         // Parse the #data section.
130                         b, err := ioutil.ReadAll(<-rc)
131                         if err != nil {
132                                 t.Fatal(err)
133                         }
134                         text := string(b)
135                         doc, err := Parse(strings.NewReader(text))
136                         if err != nil {
137                                 t.Fatal(err)
138                         }
139                         actual, err := dump(doc)
140                         if err != nil {
141                                 t.Fatal(err)
142                         }
143                         // Skip the #error section.
144                         if _, err := io.Copy(devNull{}, <-rc); err != nil {
145                                 t.Fatal(err)
146                         }
147                         // Compare the parsed tree to the #document section.
148                         b, err = ioutil.ReadAll(<-rc)
149                         if err != nil {
150                                 t.Fatal(err)
151                         }
152                         expected := string(b)
153                         if actual != expected {
154                                 t.Errorf("%s test #%d %q, actual vs expected:\n----\n%s----\n%s----", filename, i, text, actual, expected)
155                         }
156                 }
157         }
158 }