...
Run Format

Source file src/go/doc/doc_test.go

Documentation: go/doc

  // Copyright 2012 The Go Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  package doc
  
  import (
  	"bytes"
  	"flag"
  	"fmt"
  	"go/parser"
  	"go/printer"
  	"go/token"
  	"io/ioutil"
  	"os"
  	"path/filepath"
  	"regexp"
  	"strings"
  	"testing"
  	"text/template"
  )
  
  var update = flag.Bool("update", false, "update golden (.out) files")
  var files = flag.String("files", "", "consider only Go test files matching this regular expression")
  
  const dataDir = "testdata"
  
  var templateTxt = readTemplate("template.txt")
  
  func readTemplate(filename string) *template.Template {
  	t := template.New(filename)
  	t.Funcs(template.FuncMap{
  		"node":     nodeFmt,
  		"synopsis": synopsisFmt,
  		"indent":   indentFmt,
  	})
  	return template.Must(t.ParseFiles(filepath.Join(dataDir, filename)))
  }
  
  func nodeFmt(node interface{}, fset *token.FileSet) string {
  	var buf bytes.Buffer
  	printer.Fprint(&buf, fset, node)
  	return strings.Replace(strings.TrimSpace(buf.String()), "\n", "\n\t", -1)
  }
  
  func synopsisFmt(s string) string {
  	const n = 64
  	if len(s) > n {
  		// cut off excess text and go back to a word boundary
  		s = s[0:n]
  		if i := strings.LastIndexAny(s, "\t\n "); i >= 0 {
  			s = s[0:i]
  		}
  		s = strings.TrimSpace(s) + " ..."
  	}
  	return "// " + strings.Replace(s, "\n", " ", -1)
  }
  
  func indentFmt(indent, s string) string {
  	end := ""
  	if strings.HasSuffix(s, "\n") {
  		end = "\n"
  		s = s[:len(s)-1]
  	}
  	return indent + strings.Replace(s, "\n", "\n"+indent, -1) + end
  }
  
  func isGoFile(fi os.FileInfo) bool {
  	name := fi.Name()
  	return !fi.IsDir() &&
  		len(name) > 0 && name[0] != '.' && // ignore .files
  		filepath.Ext(name) == ".go"
  }
  
  type bundle struct {
  	*Package
  	FSet *token.FileSet
  }
  
  func test(t *testing.T, mode Mode) {
  	// determine file filter
  	filter := isGoFile
  	if *files != "" {
  		rx, err := regexp.Compile(*files)
  		if err != nil {
  			t.Fatal(err)
  		}
  		filter = func(fi os.FileInfo) bool {
  			return isGoFile(fi) && rx.MatchString(fi.Name())
  		}
  	}
  
  	// get packages
  	fset := token.NewFileSet()
  	pkgs, err := parser.ParseDir(fset, dataDir, filter, parser.ParseComments)
  	if err != nil {
  		t.Fatal(err)
  	}
  
  	// test packages
  	for _, pkg := range pkgs {
  		importpath := dataDir + "/" + pkg.Name
  		doc := New(pkg, importpath, mode)
  
  		// golden files always use / in filenames - canonicalize them
  		for i, filename := range doc.Filenames {
  			doc.Filenames[i] = filepath.ToSlash(filename)
  		}
  
  		// print documentation
  		var buf bytes.Buffer
  		if err := templateTxt.Execute(&buf, bundle{doc, fset}); err != nil {
  			t.Error(err)
  			continue
  		}
  		got := buf.Bytes()
  
  		// update golden file if necessary
  		golden := filepath.Join(dataDir, fmt.Sprintf("%s.%d.golden", pkg.Name, mode))
  		if *update {
  			err := ioutil.WriteFile(golden, got, 0644)
  			if err != nil {
  				t.Error(err)
  			}
  			continue
  		}
  
  		// get golden file
  		want, err := ioutil.ReadFile(golden)
  		if err != nil {
  			t.Error(err)
  			continue
  		}
  
  		// compare
  		if !bytes.Equal(got, want) {
  			t.Errorf("package %s\n\tgot:\n%s\n\twant:\n%s", pkg.Name, got, want)
  		}
  	}
  }
  
  func Test(t *testing.T) {
  	test(t, 0)
  	test(t, AllDecls)
  	test(t, AllMethods)
  }
  

View as plain text