github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/src/cmd/compile/internal/syntax/parser_test.go (about) 1 // Copyright 2016 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 syntax 6 7 import ( 8 "bytes" 9 "flag" 10 "fmt" 11 "io/ioutil" 12 "path/filepath" 13 "runtime" 14 "strings" 15 "sync" 16 "testing" 17 "time" 18 ) 19 20 var fast = flag.Bool("fast", false, "parse package files in parallel") 21 var src = flag.String("src", "parser.go", "source file to parse") 22 var verify = flag.Bool("verify", false, "verify idempotent printing") 23 24 func TestParse(t *testing.T) { 25 _, err := ParseFile(*src, nil, nil, 0) 26 if err != nil { 27 t.Fatal(err) 28 } 29 } 30 31 func TestStdLib(t *testing.T) { 32 if testing.Short() { 33 t.Skip("skipping test in short mode") 34 } 35 36 var m1 runtime.MemStats 37 runtime.ReadMemStats(&m1) 38 start := time.Now() 39 40 type parseResult struct { 41 filename string 42 lines int 43 } 44 45 results := make(chan parseResult) 46 go func() { 47 defer close(results) 48 for _, dir := range []string{ 49 runtime.GOROOT(), 50 } { 51 walkDirs(t, dir, func(filename string) { 52 if debug { 53 fmt.Printf("parsing %s\n", filename) 54 } 55 ast, err := ParseFile(filename, nil, nil, 0) 56 if err != nil { 57 t.Error(err) 58 return 59 } 60 if *verify { 61 verifyPrint(filename, ast) 62 } 63 results <- parseResult{filename, ast.Lines} 64 }) 65 } 66 }() 67 68 var count, lines int 69 for res := range results { 70 count++ 71 lines += res.lines 72 if testing.Verbose() { 73 fmt.Printf("%5d %s (%d lines)\n", count, res.filename, res.lines) 74 } 75 } 76 77 dt := time.Since(start) 78 var m2 runtime.MemStats 79 runtime.ReadMemStats(&m2) 80 dm := float64(m2.TotalAlloc-m1.TotalAlloc) / 1e6 81 82 fmt.Printf("parsed %d lines (%d files) in %v (%d lines/s)\n", lines, count, dt, int64(float64(lines)/dt.Seconds())) 83 fmt.Printf("allocated %.3fMb (%.3fMb/s)\n", dm, dm/dt.Seconds()) 84 } 85 86 func walkDirs(t *testing.T, dir string, action func(string)) { 87 fis, err := ioutil.ReadDir(dir) 88 if err != nil { 89 t.Error(err) 90 return 91 } 92 93 var files, dirs []string 94 for _, fi := range fis { 95 if fi.Mode().IsRegular() { 96 if strings.HasSuffix(fi.Name(), ".go") { 97 path := filepath.Join(dir, fi.Name()) 98 files = append(files, path) 99 } 100 } else if fi.IsDir() && fi.Name() != "testdata" { 101 path := filepath.Join(dir, fi.Name()) 102 if !strings.HasSuffix(path, "/test") { 103 dirs = append(dirs, path) 104 } 105 } 106 } 107 108 if *fast { 109 var wg sync.WaitGroup 110 wg.Add(len(files)) 111 for _, filename := range files { 112 go func(filename string) { 113 defer wg.Done() 114 action(filename) 115 }(filename) 116 } 117 wg.Wait() 118 } else { 119 for _, filename := range files { 120 action(filename) 121 } 122 } 123 124 for _, dir := range dirs { 125 walkDirs(t, dir, action) 126 } 127 } 128 129 func verifyPrint(filename string, ast1 *File) { 130 var buf1 bytes.Buffer 131 _, err := Fprint(&buf1, ast1, true) 132 if err != nil { 133 panic(err) 134 } 135 136 ast2, err := ParseBytes(buf1.Bytes(), nil, nil, 0) 137 if err != nil { 138 panic(err) 139 } 140 141 var buf2 bytes.Buffer 142 _, err = Fprint(&buf2, ast2, true) 143 if err != nil { 144 panic(err) 145 } 146 147 if bytes.Compare(buf1.Bytes(), buf2.Bytes()) != 0 { 148 fmt.Printf("--- %s ---\n", filename) 149 fmt.Printf("%s\n", buf1.Bytes()) 150 fmt.Println() 151 152 fmt.Printf("--- %s ---\n", filename) 153 fmt.Printf("%s\n", buf2.Bytes()) 154 fmt.Println() 155 panic("not equal") 156 } 157 } 158 159 func TestIssue17697(t *testing.T) { 160 _, err := ParseBytes(nil, nil, nil, 0) // return with parser error, don't panic 161 if err == nil { 162 t.Errorf("no error reported") 163 } 164 } 165 166 func TestParseFile(t *testing.T) { 167 _, err := ParseFile("", nil, nil, 0) 168 if err == nil { 169 t.Error("missing io error") 170 } 171 172 var first error 173 _, err = ParseFile("", func(err error) { 174 if first == nil { 175 first = err 176 } 177 }, nil, 0) 178 if err == nil || first == nil { 179 t.Error("missing io error") 180 } 181 if err != first { 182 t.Errorf("got %v; want first error %v", err, first) 183 } 184 }