diff options
| author | Rob Pike <r@golang.org> | 2015-06-19 12:39:02 +1000 |
|---|---|---|
| committer | Rob Pike <r@golang.org> | 2015-06-19 21:56:59 +0000 |
| commit | d0652e7f82da12e84fb143c4ad6c19e39f238f05 (patch) | |
| tree | a51e213ea5f835e1cfbbcc577905ab8aa8e9d337 /src/cmd/doc/doc_test.go | |
| parent | 5ac5a9856288d20634ac21b457ec458f19ea0a37 (diff) | |
| download | go-d0652e7f82da12e84fb143c4ad6c19e39f238f05.tar.xz | |
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>
Diffstat (limited to 'src/cmd/doc/doc_test.go')
| -rw-r--r-- | src/cmd/doc/doc_test.go | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/src/cmd/doc/doc_test.go b/src/cmd/doc/doc_test.go new file mode 100644 index 0000000000..0936d4d2d4 --- /dev/null +++ b/src/cmd/doc/doc_test.go @@ -0,0 +1,343 @@ +// Copyright 2015 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 main + +import ( + "bytes" + "flag" + "os" + "os/exec" + "regexp" + "testing" +) + +const ( + dataDir = "testdata" + binary = "testdoc" +) + +type test struct { + name string + args []string // Arguments to "[go] doc". + yes []string // Regular expressions that should match. + no []string // Regular expressions that should not match. +} + +const p = "cmd/doc/testdata" + +var tests = []test{ + // Sanity check. + { + "fmt", + []string{`fmt`}, + []string{`type Formatter interface`}, + nil, + }, + + // Package dump includes import, package statement. + { + "package clause", + []string{p}, + []string{`package pkg.*cmd/doc/testdata`}, + nil, + }, + + // Constants. + // Package dump + { + "full package", + []string{p}, + []string{ + `Package comment`, + `const ExportedConstant = 1`, // Simple constant. + `ConstOne = 1`, // First entry in constant block. + `const ExportedVariable = 1`, // Simple variable. + `VarOne = 1`, // First entry in variable block. + `func ExportedFunc\(a int\) bool`, // Function. + `type ExportedType struct { ... }`, // Exported type. + `const ExportedTypedConstant ExportedType = iota`, // Typed constant. + `const ExportedTypedConstant_unexported unexportedType`, // Typed constant, exported for unexported type. + }, + []string{ + `const internalConstant = 2`, // No internal constants. + `const internalVariable = 2`, // No internal variables. + `func internalFunc(a int) bool`, // No internal functions. + `Comment about exported constant`, // No comment for single constant. + `Comment about exported variable`, // No comment for single variable. + `Comment about block of constants.`, // No comment for constant block. + `Comment about block of variables.`, // No comment for variable block. + `Comment before ConstOne`, // No comment for first entry in constant block. + `Comment before VarOne`, // No comment for first entry in variable block. + `ConstTwo = 2`, // No second entry in constant block. + `VarTwo = 2`, // No second entry in variable block. + `type unexportedType`, // No unexported type. + `unexportedTypedConstant`, // No unexported typed constant. + `Field`, // No fields. + `Method`, // No methods. + }, + }, + // Package dump -u + { + "full package with u", + []string{`-u`, p}, + []string{ + `const ExportedConstant = 1`, // Simple constant. + `const internalConstant = 2`, // Internal constants. + `func internalFunc\(a int\) bool`, // Internal functions. + }, + []string{ + `Comment about exported constant`, // No comment for simple constant. + `Comment about block of constants`, // No comment for constant block. + `Comment about internal function`, // No comment for internal function. + }, + }, + + // Single constant. + { + "single constant", + []string{p, `ExportedConstant`}, + []string{ + `Comment about exported constant`, // Include comment. + `const ExportedConstant = 1`, + }, + nil, + }, + // Single constant -u. + { + "single constant with -u", + []string{`-u`, p, `internalConstant`}, + []string{ + `Comment about internal constant`, // Include comment. + `const internalConstant = 2`, + }, + nil, + }, + // Block of constants. + { + "block of constants", + []string{p, `ConstTwo`}, + []string{ + `Comment before ConstOne.\n.*ConstOne = 1`, // First... + `ConstTwo = 2.*Comment on line with ConstTwo`, // And second show up. + `Comment about block of constants`, // Comment does too. + }, + []string{ + `constThree`, // No unexported constant. + }, + }, + // Block of constants -u. + { + "block of constants with -u", + []string{"-u", p, `constThree`}, + []string{ + `constThree = 3.*Comment on line with constThree`, + }, + nil, + }, + + // Single variable. + { + "single variable", + []string{p, `ExportedVariable`}, + []string{ + `ExportedVariable`, // Include comment. + `const ExportedVariable = 1`, + }, + nil, + }, + // Single variable -u. + { + "single variable with -u", + []string{`-u`, p, `internalVariable`}, + []string{ + `Comment about internal variable`, // Include comment. + `const internalVariable = 2`, + }, + nil, + }, + // Block of variables. + { + "block of variables", + []string{p, `VarTwo`}, + []string{ + `Comment before VarOne.\n.*VarOne = 1`, // First... + `VarTwo = 2.*Comment on line with VarTwo`, // And second show up. + `Comment about block of variables`, // Comment does too. + }, + []string{ + `varThree= 3`, // No unexported variable. + }, + }, + // Block of variables -u. + { + "block of variables with -u", + []string{"-u", p, `varThree`}, + []string{ + `varThree = 3.*Comment on line with varThree`, + }, + nil, + }, + + // Function. + { + "function", + []string{p, `ExportedFunc`}, + []string{ + `Comment about exported function`, // Include comment. + `func ExportedFunc\(a int\) bool`, + }, + nil, + }, + // Function -u. + { + "function with -u", + []string{"-u", p, `internalFunc`}, + []string{ + `Comment about internal function`, // Include comment. + `func internalFunc\(a int\) bool`, + }, + nil, + }, + + // Type. + { + "type", + []string{p, `ExportedType`}, + []string{ + `Comment about exported type`, // Include comment. + `type ExportedType struct`, // Type definition. + `Comment before exported field.*\n.*ExportedField +int`, + `Has unexported fields`, + `func \(ExportedType\) ExportedMethod\(a int\) bool`, + `const ExportedTypedConstant ExportedType = iota`, // Must include associated constant. + }, + []string{ + `unexportedField`, // No unexported field. + `Comment about exported method.`, // No comment about exported method. + `unexportedMethod`, // No unexported method. + `unexportedTypedConstant`, // No unexported constant. + }, + }, + // Type -u with unexported fields. + { + "type with unexported fields and -u", + []string{"-u", p, `ExportedType`}, + []string{ + `Comment about exported type`, // Include comment. + `type ExportedType struct`, // Type definition. + `Comment before exported field.*\n.*ExportedField +int`, + `unexportedField int.*Comment on line with unexported field.`, + `func \(ExportedType\) unexportedMethod\(a int\) bool`, + `unexportedTypedConstant`, + }, + []string{ + `Has unexported fields`, + }, + }, + // Unexported type with -u. + { + "unexported type with -u", + []string{"-u", p, `unexportedType`}, + []string{ + `Comment about unexported type`, // Include comment. + `type unexportedType int`, // Type definition. + `func \(unexportedType\) ExportedMethod\(\) bool`, + `func \(unexportedType\) unexportedMethod\(\) bool`, + `ExportedTypedConstant_unexported unexportedType = iota`, + `const unexportedTypedConstant unexportedType = 1`, + }, + nil, + }, + + // Method. + { + "method", + []string{p, `ExportedType.ExportedMethod`}, + []string{ + `func \(ExportedType\) ExportedMethod\(a int\) bool`, + `Comment about exported method.`, + }, + nil, + }, + // Method with -u. + { + "method with -u", + []string{"-u", p, `ExportedType.unexportedMethod`}, + []string{ + `func \(ExportedType\) unexportedMethod\(a int\) bool`, + `Comment about unexported method.`, + }, + nil, + }, + + // Case matching off. + { + "case matching off", + []string{p, `casematch`}, + []string{ + `CaseMatch`, + `Casematch`, + }, + nil, + }, + + // Case matching on. + { + "case matching on", + []string{"-c", p, `Casematch`}, + []string{ + `Casematch`, + }, + []string{ + `CaseMatch`, + }, + }, +} + +func TestDoc(t *testing.T) { + for _, test := range tests { + var b bytes.Buffer + var flagSet flag.FlagSet + err := do(&b, &flagSet, test.args) + if err != nil { + t.Fatalf("%s: %s\n", test.name, err) + } + output := b.Bytes() + failed := false + for j, yes := range test.yes { + re, err := regexp.Compile(yes) + if err != nil { + t.Fatalf("%s.%d: compiling %#q: %s", test.name, j, yes, err) + } + if !re.Match(output) { + t.Errorf("%s.%d: no match for %s %#q", test.name, j, test.args, yes) + failed = true + } + } + for j, no := range test.no { + re, err := regexp.Compile(no) + if err != nil { + t.Fatalf("%s.%d: compiling %#q: %s", test.name, j, no, err) + } + if re.Match(output) { + t.Errorf("%s.%d: incorrect match for %s %#q", test.name, j, test.args, no) + failed = true + } + } + if failed { + t.Logf("\n%s", output) + } + } +} + +// run runs the command, but calls t.Fatal if there is an error. +func run(c *exec.Cmd, t *testing.T) []byte { + output, err := c.CombinedOutput() + if err != nil { + os.Stdout.Write(output) + t.Fatal(err) + } + return output +} |
