github.com/sbinet/go@v0.0.0-20160827155028-54d7de7dd62b/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 := ReadFile(*src, 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  		for _, dir := range []string{
    48  			runtime.GOROOT(),
    49  			//"/Users/gri/src",
    50  		} {
    51  			walkDirs(t, dir, func(filename string) {
    52  				if debug {
    53  					fmt.Printf("parsing %s\n", filename)
    54  				}
    55  				ast, err := ReadFile(filename, nil, 0)
    56  				if err != nil {
    57  					t.Fatal(err)
    58  				}
    59  				if *verify {
    60  					verifyPrint(filename, ast)
    61  				}
    62  				results <- parseResult{filename, ast.Lines}
    63  			})
    64  		}
    65  		close(results)
    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.Contains(path, "go/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 := ReadBytes(buf1.Bytes(), 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  }