| // Copyright 2017 syzkaller project authors. All rights reserved. |
| // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. |
| |
| package ast |
| |
| import ( |
| "bytes" |
| "io/ioutil" |
| "path/filepath" |
| "reflect" |
| "strings" |
| "testing" |
| ) |
| |
| func TestParseAll(t *testing.T) { |
| files, err := filepath.Glob(filepath.Join("..", "..", "sys", "linux", "*.txt")) |
| if err != nil || len(files) == 0 { |
| t.Fatalf("failed to read sys dir: %v", err) |
| } |
| for _, file := range files { |
| data, err := ioutil.ReadFile(file) |
| if err != nil { |
| t.Fatalf("failed to read file: %v", err) |
| } |
| t.Run(file, func(t *testing.T) { |
| eh := func(pos Pos, msg string) { |
| t.Fatalf("%v: %v", pos, msg) |
| } |
| desc := Parse(data, file, eh) |
| if desc == nil { |
| t.Fatalf("parsing failed, but no error produced") |
| } |
| data2 := Format(desc) |
| desc2 := Parse(data2, file, eh) |
| if desc2 == nil { |
| t.Fatalf("parsing failed, but no error produced") |
| } |
| if len(desc.Nodes) != len(desc2.Nodes) { |
| t.Fatalf("formatting number of top level decls: %v/%v", |
| len(desc.Nodes), len(desc2.Nodes)) |
| } |
| for i := range desc.Nodes { |
| n1, n2 := desc.Nodes[i], desc2.Nodes[i] |
| if n1 == nil { |
| t.Fatalf("got nil node") |
| } |
| if !reflect.DeepEqual(n1, n2) { |
| t.Fatalf("formatting changed code:\n%#v\nvs:\n%#v", n1, n2) |
| } |
| } |
| data3 := Format(desc.Clone()) |
| if !bytes.Equal(data, data3) { |
| t.Fatalf("Clone lost data") |
| } |
| }) |
| } |
| } |
| |
| func TestParse(t *testing.T) { |
| for _, test := range parseTests { |
| t.Run(test.name, func(t *testing.T) { |
| errorHandler := func(pos Pos, msg string) { |
| t.Logf("%v: %v", pos, msg) |
| } |
| Parse([]byte(test.input), "foo", errorHandler) |
| }) |
| } |
| } |
| |
| var parseTests = []struct { |
| name string |
| input string |
| result []interface{} |
| }{ |
| { |
| "empty", |
| ``, |
| []interface{}{}, |
| }, |
| { |
| "new-line", |
| ` |
| |
| `, |
| []interface{}{}, |
| }, |
| { |
| "nil", |
| "\x00", |
| []interface{}{}, |
| }, |
| } |
| |
| func TestErrors(t *testing.T) { |
| files, err := ioutil.ReadDir("testdata") |
| if err != nil { |
| t.Fatal(err) |
| } |
| if len(files) == 0 { |
| t.Fatal("no input files") |
| } |
| for _, f := range files { |
| if !strings.HasSuffix(f.Name(), ".txt") { |
| continue |
| } |
| name := f.Name() |
| t.Run(name, func(t *testing.T) { |
| em := NewErrorMatcher(t, filepath.Join("testdata", name)) |
| desc := Parse(em.Data, name, em.ErrorHandler) |
| if desc != nil && em.Count() != 0 { |
| em.DumpErrors(t) |
| t.Fatalf("parsing succeed, but got errors") |
| } |
| if desc == nil && em.Count() == 0 { |
| t.Fatalf("parsing failed, but got no errors") |
| } |
| em.Check(t) |
| }) |
| } |
| } |