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  }