mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/doc: add test
Refactor main a bit to make it possible to run tests without an exec every time. (Makes a huge difference in run time.) Add a silver test. Not quite golden, since it looks for pieces rather than the full output, and also includes tests for what should not appear. Fixes #10920. Change-Id: I6a4951cc14e61763379754a10b0cc3484d30c267 Reviewed-on: https://go-review.googlesource.com/11272 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Rob Pike <r@golang.org>
This commit is contained in:
parent
5ac5a98562
commit
d0652e7f82
5 changed files with 514 additions and 28 deletions
|
|
@ -13,6 +13,7 @@ import (
|
|||
"go/format"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"unicode"
|
||||
|
|
@ -20,19 +21,36 @@ import (
|
|||
)
|
||||
|
||||
type Package struct {
|
||||
name string // Package name, json for encoding/json.
|
||||
userPath string // String the user used to find this package.
|
||||
pkg *ast.Package // Parsed package.
|
||||
file *ast.File // Merged from all files in the package
|
||||
doc *doc.Package
|
||||
build *build.Package
|
||||
fs *token.FileSet // Needed for printing.
|
||||
buf bytes.Buffer
|
||||
writer io.Writer // Destination for output.
|
||||
name string // Package name, json for encoding/json.
|
||||
userPath string // String the user used to find this package.
|
||||
unexported bool
|
||||
matchCase bool
|
||||
pkg *ast.Package // Parsed package.
|
||||
file *ast.File // Merged from all files in the package
|
||||
doc *doc.Package
|
||||
build *build.Package
|
||||
fs *token.FileSet // Needed for printing.
|
||||
buf bytes.Buffer
|
||||
}
|
||||
|
||||
type PackageError string // type returned by pkg.Fatalf.
|
||||
|
||||
func (p PackageError) Error() string {
|
||||
return string(p)
|
||||
}
|
||||
|
||||
// pkg.Fatalf is like log.Fatalf, but panics so it can be recovered in the
|
||||
// main do function, so it doesn't cause an exit. Allows testing to work
|
||||
// without running a subprocess. The log prefix will be added when
|
||||
// logged in main; it is not added here.
|
||||
func (pkg *Package) Fatalf(format string, args ...interface{}) {
|
||||
panic(PackageError(fmt.Sprintf(format, args...)))
|
||||
}
|
||||
|
||||
// parsePackage turns the build package we found into a parsed package
|
||||
// we can then use to generate documentation.
|
||||
func parsePackage(pkg *build.Package, userPath string) *Package {
|
||||
func parsePackage(writer io.Writer, pkg *build.Package, userPath string) *Package {
|
||||
fs := token.NewFileSet()
|
||||
// include tells parser.ParseDir which files to include.
|
||||
// That means the file must be in the build package's GoFiles or CgoFiles
|
||||
|
|
@ -56,7 +74,7 @@ func parsePackage(pkg *build.Package, userPath string) *Package {
|
|||
}
|
||||
// Make sure they are all in one package.
|
||||
if len(pkgs) != 1 {
|
||||
log.Fatalf("multiple packages directory %s", pkg.Dir)
|
||||
log.Fatalf("multiple packages in directory %s", pkg.Dir)
|
||||
}
|
||||
astPkg := pkgs[pkg.Name]
|
||||
|
||||
|
|
@ -76,6 +94,7 @@ func parsePackage(pkg *build.Package, userPath string) *Package {
|
|||
}
|
||||
|
||||
return &Package{
|
||||
writer: writer,
|
||||
name: pkg.Name,
|
||||
userPath: userPath,
|
||||
pkg: astPkg,
|
||||
|
|
@ -91,7 +110,7 @@ func (pkg *Package) Printf(format string, args ...interface{}) {
|
|||
}
|
||||
|
||||
func (pkg *Package) flush() {
|
||||
_, err := os.Stdout.Write(pkg.buf.Bytes())
|
||||
_, err := pkg.writer.Write(pkg.buf.Bytes())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
|
@ -391,7 +410,7 @@ func (pkg *Package) symbolDoc(symbol string) {
|
|||
// trimUnexportedElems modifies spec in place to elide unexported fields from
|
||||
// structs and methods from interfaces (unless the unexported flag is set).
|
||||
func trimUnexportedElems(spec *ast.TypeSpec) {
|
||||
if *unexported {
|
||||
if unexported {
|
||||
return
|
||||
}
|
||||
switch typ := spec.Type.(type) {
|
||||
|
|
@ -450,7 +469,7 @@ func (pkg *Package) printMethodDoc(symbol, method string) bool {
|
|||
if symbol == "" {
|
||||
return false
|
||||
}
|
||||
log.Fatalf("symbol %s is not a type in package %s installed in %q", symbol, pkg.name, pkg.build.ImportPath)
|
||||
pkg.Fatalf("symbol %s is not a type in package %s installed in %q", symbol, pkg.name, pkg.build.ImportPath)
|
||||
}
|
||||
found := false
|
||||
for _, typ := range types {
|
||||
|
|
@ -470,7 +489,7 @@ func (pkg *Package) printMethodDoc(symbol, method string) bool {
|
|||
func (pkg *Package) methodDoc(symbol, method string) {
|
||||
defer pkg.flush()
|
||||
if !pkg.printMethodDoc(symbol, method) {
|
||||
log.Fatalf("no method %s.%s in package %s installed in %q", symbol, method, pkg.name, pkg.build.ImportPath)
|
||||
pkg.Fatalf("no method %s.%s in package %s installed in %q", symbol, method, pkg.name, pkg.build.ImportPath)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -481,7 +500,7 @@ func match(user, program string) bool {
|
|||
if !isExported(program) {
|
||||
return false
|
||||
}
|
||||
if *matchCase {
|
||||
if matchCase {
|
||||
return user == program
|
||||
}
|
||||
for _, u := range user {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue