From: Jonathan Amsterdam Date: Fri, 22 Apr 2022 13:13:48 +0000 (-0400) Subject: go/doc: move example tests into files X-Git-Tag: go1.19beta1~333 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=30a2750a91616f8120266b79ea52d293a2398b86;p=gostls13.git go/doc: move example tests into files Move the test cases for doc.Examples from example_test.go into their own files under testdata/examples. This makes example_test.go easier to read and collapses several similar test functions into one. It will also make it less cumbersome to add large examples later. Change-Id: Id220c1205e94027d14291898e541b69344842686 Reviewed-on: https://go-review.googlesource.com/c/go/+/401756 Run-TryBot: Jonathan Amsterdam TryBot-Result: Gopher Robot Reviewed-by: Robert Findley --- diff --git a/src/go/doc/example_test.go b/src/go/doc/example_test.go index 4d87a654c9..7919c3a2c0 100644 --- a/src/go/doc/example_test.go +++ b/src/go/doc/example_test.go @@ -12,512 +12,79 @@ import ( "go/format" "go/parser" "go/token" + "internal/diff" + "internal/txtar" + "path/filepath" "reflect" "strings" "testing" ) -const exampleTestFile = ` -package foo_test - -import ( - "flag" - "fmt" - "log" - "sort" - "os/exec" -) - -func ExampleHello() { - fmt.Println("Hello, world!") - // Output: Hello, world! -} - -func ExampleImport() { - out, err := exec.Command("date").Output() - if err != nil { - log.Fatal(err) - } - fmt.Printf("The date is %s\n", out) -} - -func ExampleKeyValue() { - v := struct { - a string - b int - }{ - a: "A", - b: 1, - } - fmt.Print(v) - // Output: a: "A", b: 1 -} - -func ExampleKeyValueImport() { - f := flag.Flag{ - Name: "play", - } - fmt.Print(f) - // Output: Name: "play" -} - -var keyValueTopDecl = struct { - a string - b int -}{ - a: "B", - b: 2, -} - -func ExampleKeyValueTopDecl() { - fmt.Print(keyValueTopDecl) - // Output: a: "B", b: 2 -} - -// Person represents a person by name and age. -type Person struct { - Name string - Age int -} - -// String returns a string representation of the Person. -func (p Person) String() string { - return fmt.Sprintf("%s: %d", p.Name, p.Age) -} - -// ByAge implements sort.Interface for []Person based on -// the Age field. -type ByAge []Person - -// Len returns the number of elements in ByAge. -func (a (ByAge)) Len() int { return len(a) } - -// Swap swaps the elements in ByAge. -func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age } - -// people is the array of Person -var people = []Person{ - {"Bob", 31}, - {"John", 42}, - {"Michael", 17}, - {"Jenny", 26}, -} - -func ExampleSort() { - fmt.Println(people) - sort.Sort(ByAge(people)) - fmt.Println(people) - // Output: - // [Bob: 31 John: 42 Michael: 17 Jenny: 26] - // [Michael: 17 Jenny: 26 Bob: 31 John: 42] -} -` - -var exampleTestCases = []struct { - Name, Play, Output string -}{ - { - Name: "Hello", - Play: exampleHelloPlay, - Output: "Hello, world!\n", - }, - { - Name: "Import", - Play: exampleImportPlay, - }, - { - Name: "KeyValue", - Play: exampleKeyValuePlay, - Output: "a: \"A\", b: 1\n", - }, - { - Name: "KeyValueImport", - Play: exampleKeyValueImportPlay, - Output: "Name: \"play\"\n", - }, - { - Name: "KeyValueTopDecl", - Play: exampleKeyValueTopDeclPlay, - Output: "a: \"B\", b: 2\n", - }, - { - Name: "Sort", - Play: exampleSortPlay, - Output: "[Bob: 31 John: 42 Michael: 17 Jenny: 26]\n[Michael: 17 Jenny: 26 Bob: 31 John: 42]\n", - }, -} - -const exampleHelloPlay = `package main - -import ( - "fmt" -) - -func main() { - fmt.Println("Hello, world!") -} -` -const exampleImportPlay = `package main - -import ( - "fmt" - "log" - "os/exec" -) - -func main() { - out, err := exec.Command("date").Output() - if err != nil { - log.Fatal(err) - } - fmt.Printf("The date is %s\n", out) -} -` - -const exampleKeyValuePlay = `package main - -import ( - "fmt" -) - -func main() { - v := struct { - a string - b int - }{ - a: "A", - b: 1, - } - fmt.Print(v) -} -` - -const exampleKeyValueImportPlay = `package main - -import ( - "flag" - "fmt" -) - -func main() { - f := flag.Flag{ - Name: "play", - } - fmt.Print(f) -} -` - -const exampleKeyValueTopDeclPlay = `package main - -import ( - "fmt" -) - -var keyValueTopDecl = struct { - a string - b int -}{ - a: "B", - b: 2, -} - -func main() { - fmt.Print(keyValueTopDecl) -} -` - -const exampleSortPlay = `package main - -import ( - "fmt" - "sort" -) - -// Person represents a person by name and age. -type Person struct { - Name string - Age int -} - -// String returns a string representation of the Person. -func (p Person) String() string { - return fmt.Sprintf("%s: %d", p.Name, p.Age) -} - -// ByAge implements sort.Interface for []Person based on -// the Age field. -type ByAge []Person - -// Len returns the number of elements in ByAge. -func (a ByAge) Len() int { return len(a) } - -// Swap swaps the elements in ByAge. -func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age } - -// people is the array of Person -var people = []Person{ - {"Bob", 31}, - {"John", 42}, - {"Michael", 17}, - {"Jenny", 26}, -} - -func main() { - fmt.Println(people) - sort.Sort(ByAge(people)) - fmt.Println(people) -} -` - func TestExamples(t *testing.T) { - fset := token.NewFileSet() - file, err := parser.ParseFile(fset, "test.go", strings.NewReader(exampleTestFile), parser.ParseComments) + dir := filepath.Join("testdata", "examples") + filenames, err := filepath.Glob(filepath.Join(dir, "*.go")) if err != nil { t.Fatal(err) } - for i, e := range doc.Examples(file) { - c := exampleTestCases[i] - if e.Name != c.Name { - t.Errorf("got Name == %q, want %q", e.Name, c.Name) - } - if w := c.Play; w != "" { - g := formatFile(t, fset, e.Play) - if g != w { - t.Errorf("%s: got Play == %q, want %q", c.Name, g, w) + for _, filename := range filenames { + t.Run(strings.TrimSuffix(filepath.Base(filename), ".go"), func(t *testing.T) { + fset := token.NewFileSet() + astFile, err := parser.ParseFile(fset, filename, nil, parser.ParseComments) + if err != nil { + t.Fatal(err) + } + goldenFilename := strings.TrimSuffix(filename, ".go") + ".golden" + archive, err := txtar.ParseFile(goldenFilename) + if err != nil { + t.Fatal(err) + } + golden := map[string]string{} + for _, f := range archive.Files { + golden[f.Name] = strings.TrimSpace(string(f.Data)) } - } - if g, w := e.Output, c.Output; g != w { - t.Errorf("%s: got Output == %q, want %q", c.Name, g, w) - } - } -} - -const exampleWholeFile = `package foo_test - -type X int - -func (X) Foo() { -} - -func (X) TestBlah() { -} - -func (X) BenchmarkFoo() { -} - -func (X) FuzzFoo() { -} - -func Example() { - fmt.Println("Hello, world!") - // Output: Hello, world! -} -` - -const exampleWholeFileOutput = `package main - -type X int - -func (X) Foo() { -} - -func (X) TestBlah() { -} - -func (X) BenchmarkFoo() { -} - -func (X) FuzzFoo() { -} - -func main() { - fmt.Println("Hello, world!") -} -` - -const exampleWholeFileFunction = `package foo_test - -func Foo(x int) { -} - -func Example() { - fmt.Println("Hello, world!") - // Output: Hello, world! -} -` - -const exampleWholeFileFunctionOutput = `package main - -func Foo(x int) { -} - -func main() { - fmt.Println("Hello, world!") -} -` - -const exampleWholeFileExternalFunction = `package foo_test - -func foo(int) - -func Example() { - foo(42) - // Output: -} -` - -const exampleWholeFileExternalFunctionOutput = `package main - -func foo(int) - -func main() { - foo(42) -} -` - -var exampleWholeFileTestCases = []struct { - Title, Source, Play, Output string -}{ - { - "Methods", - exampleWholeFile, - exampleWholeFileOutput, - "Hello, world!\n", - }, - { - "Function", - exampleWholeFileFunction, - exampleWholeFileFunctionOutput, - "Hello, world!\n", - }, - { - "ExternalFunction", - exampleWholeFileExternalFunction, - exampleWholeFileExternalFunctionOutput, - "", - }, -} - -func TestExamplesWholeFile(t *testing.T) { - for _, c := range exampleWholeFileTestCases { - fset := token.NewFileSet() - file, err := parser.ParseFile(fset, "test.go", strings.NewReader(c.Source), parser.ParseComments) - if err != nil { - t.Fatal(err) - } - es := doc.Examples(file) - if len(es) != 1 { - t.Fatalf("%s: wrong number of examples; got %d want 1", c.Title, len(es)) - } - e := es[0] - if e.Name != "" { - t.Errorf("%s: got Name == %q, want %q", c.Title, e.Name, "") - } - if g, w := formatFile(t, fset, e.Play), c.Play; g != w { - t.Errorf("%s: got Play == %q, want %q", c.Title, g, w) - } - if g, w := e.Output, c.Output; g != w { - t.Errorf("%s: got Output == %q, want %q", c.Title, g, w) - } - } -} - -const exampleInspectSignature = `package foo_test - -import ( - "bytes" - "io" -) - -func getReader() io.Reader { return nil } - -func do(b bytes.Reader) {} - -func Example() { - getReader() - do() - // Output: -} - -func ExampleIgnored() { -} -` - -const exampleInspectSignatureOutput = `package main - -import ( - "bytes" - "io" -) - -func getReader() io.Reader { return nil } - -func do(b bytes.Reader) {} - -func main() { - getReader() - do() -} -` - -func TestExampleInspectSignature(t *testing.T) { - // Verify that "bytes" and "io" are imported. See issue #28492. - fset := token.NewFileSet() - file, err := parser.ParseFile(fset, "test.go", strings.NewReader(exampleInspectSignature), parser.ParseComments) - if err != nil { - t.Fatal(err) - } - es := doc.Examples(file) - if len(es) != 2 { - t.Fatalf("wrong number of examples; got %d want 2", len(es)) - } - // We are interested in the first example only. - e := es[0] - if e.Name != "" { - t.Errorf("got Name == %q, want %q", e.Name, "") - } - if g, w := formatFile(t, fset, e.Play), exampleInspectSignatureOutput; g != w { - t.Errorf("got Play == %q, want %q", g, w) - } - if g, w := e.Output, ""; g != w { - t.Errorf("got Output == %q, want %q", g, w) - } -} - -const exampleEmpty = ` -package p -func Example() {} -func Example_a() -` - -const exampleEmptyOutput = `package main - -func main() {} -func main() -` -func TestExampleEmpty(t *testing.T) { - fset := token.NewFileSet() - file, err := parser.ParseFile(fset, "test.go", strings.NewReader(exampleEmpty), parser.ParseComments) - if err != nil { - t.Fatal(err) - } + // Collect the results of doc.Examples in a map keyed by example name. + examples := map[string]*doc.Example{} + for _, e := range doc.Examples(astFile) { + examples[e.Name] = e + // Treat missing sections in the golden as empty. + for _, kind := range []string{"Play", "Output"} { + key := e.Name + "." + kind + if _, ok := golden[key]; !ok { + golden[key] = "" + } + } + } - es := doc.Examples(file) - if len(es) != 1 { - t.Fatalf("wrong number of examples; got %d want 1", len(es)) - } - e := es[0] - if e.Name != "" { - t.Errorf("got Name == %q, want %q", e.Name, "") - } - if g, w := formatFile(t, fset, e.Play), exampleEmptyOutput; g != w { - t.Errorf("got Play == %q, want %q", g, w) - } - if g, w := e.Output, ""; g != w { - t.Errorf("got Output == %q, want %q", g, w) + // Each section in the golden file corresponds to an example we expect + // to see. + for sectionName, want := range golden { + name, kind, found := strings.Cut(sectionName, ".") + if !found { + t.Fatalf("bad section name %q, want EXAMPLE_NAME.KIND", sectionName) + } + ex := examples[name] + if ex == nil { + t.Fatalf("no example named %q", name) + } + + var got string + switch kind { + case "Play": + got = strings.TrimSpace(formatFile(t, fset, ex.Play)) + + case "Output": + got = strings.TrimSpace(ex.Output) + default: + t.Fatalf("bad section kind %q", kind) + } + + if got != want { + t.Errorf("%s mismatch:\n%s", sectionName, + diff.Diff("want", []byte(want), "got", []byte(got))) + } + } + }) } } diff --git a/src/go/doc/testdata/examples/README.md b/src/go/doc/testdata/examples/README.md new file mode 100644 index 0000000000..a1c18e88ec --- /dev/null +++ b/src/go/doc/testdata/examples/README.md @@ -0,0 +1,12 @@ +These files are processed by example_test.go:TestExamples. + +A .golden file is a txtar file with two sections for each example that should be +created by doc.Examples from the corresponding .go file. + +One section, named EXAMPLE_NAME.Output, contains the example's output, +the value of the field Example.Output. + +The other, named EXAMPLE_NAME.Play, contains the formatted code for a playable +version of the example, the value of the field Example.Play. + +If a section is missing, it is treated as being empty. diff --git a/src/go/doc/testdata/examples/empty.go b/src/go/doc/testdata/examples/empty.go new file mode 100644 index 0000000000..0b10420f42 --- /dev/null +++ b/src/go/doc/testdata/examples/empty.go @@ -0,0 +1,8 @@ +// Copyright 2021 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 p + +func Example() {} +func Example_a() diff --git a/src/go/doc/testdata/examples/empty.golden b/src/go/doc/testdata/examples/empty.golden new file mode 100644 index 0000000000..2aafd20435 --- /dev/null +++ b/src/go/doc/testdata/examples/empty.golden @@ -0,0 +1,6 @@ +-- .Play -- +package main + +func main() {} +func main() + diff --git a/src/go/doc/testdata/examples/import_groups.go b/src/go/doc/testdata/examples/import_groups.go new file mode 100644 index 0000000000..05f21caaaa --- /dev/null +++ b/src/go/doc/testdata/examples/import_groups.go @@ -0,0 +1,23 @@ +// Copyright 2022 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 foo_test + +import ( + "fmt" + "time" + + "golang.org/x/time/rate" +) + +func Example() { + fmt.Println("Hello, world!") + // Output: Hello, world! +} + +func ExampleLimiter() { + // Uses fmt, time and rate. + l := rate.NewLimiter(rate.Every(time.Second), 1) + fmt.Println(l) +} diff --git a/src/go/doc/testdata/examples/import_groups.golden b/src/go/doc/testdata/examples/import_groups.golden new file mode 100644 index 0000000000..efe2cc1df5 --- /dev/null +++ b/src/go/doc/testdata/examples/import_groups.golden @@ -0,0 +1,27 @@ +-- .Play -- +package main + +import ( + "fmt" +) + +func main() { + fmt.Println("Hello, world!") +} +-- .Output -- +Hello, world! +-- Limiter.Play -- +package main + +import ( + "fmt" + "time" + + "golang.org/x/time/rate" +) + +func main() { + // Uses fmt, time and rate. + l := rate.NewLimiter(rate.Every(time.Second), 1) + fmt.Println(l) +} diff --git a/src/go/doc/testdata/examples/import_groups_named.go b/src/go/doc/testdata/examples/import_groups_named.go new file mode 100644 index 0000000000..377022b22a --- /dev/null +++ b/src/go/doc/testdata/examples/import_groups_named.go @@ -0,0 +1,23 @@ +// Copyright 2022 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 foo_test + +import ( + "fmt" + tm "time" + + r "golang.org/x/time/rate" +) + +func Example() { + fmt.Println("Hello, world!") + // Output: Hello, world! +} + +func ExampleLimiter() { + // Uses fmt, time and rate. + l := r.NewLimiter(r.Every(tm.Second), 1) + fmt.Println(l) +} diff --git a/src/go/doc/testdata/examples/import_groups_named.golden b/src/go/doc/testdata/examples/import_groups_named.golden new file mode 100644 index 0000000000..9baf373cd8 --- /dev/null +++ b/src/go/doc/testdata/examples/import_groups_named.golden @@ -0,0 +1,27 @@ +-- .Play -- +package main + +import ( + "fmt" +) + +func main() { + fmt.Println("Hello, world!") +} +-- .Output -- +Hello, world! +-- Limiter.Play -- +package main + +import ( + "fmt" + tm "time" + + r "golang.org/x/time/rate" +) + +func main() { + // Uses fmt, time and rate. + l := r.NewLimiter(r.Every(tm.Second), 1) + fmt.Println(l) +} diff --git a/src/go/doc/testdata/examples/inspect_signature.go b/src/go/doc/testdata/examples/inspect_signature.go new file mode 100644 index 0000000000..c4a36e758d --- /dev/null +++ b/src/go/doc/testdata/examples/inspect_signature.go @@ -0,0 +1,23 @@ +// Copyright 2021 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 foo_test + +import ( + "bytes" + "io" +) + +func getReader() io.Reader { return nil } + +func do(b bytes.Reader) {} + +func Example() { + getReader() + do() + // Output: +} + +func ExampleIgnored() { +} diff --git a/src/go/doc/testdata/examples/inspect_signature.golden b/src/go/doc/testdata/examples/inspect_signature.golden new file mode 100644 index 0000000000..c0d9b2ecc8 --- /dev/null +++ b/src/go/doc/testdata/examples/inspect_signature.golden @@ -0,0 +1,24 @@ +-- .Play -- +package main + +import ( + "bytes" + "io" +) + +func getReader() io.Reader { return nil } + +func do(b bytes.Reader) {} + +func main() { + getReader() + do() +} +-- Ignored.Play -- +package main + +import () + +func main() { +} + diff --git a/src/go/doc/testdata/examples/multiple.go b/src/go/doc/testdata/examples/multiple.go new file mode 100644 index 0000000000..27282644d8 --- /dev/null +++ b/src/go/doc/testdata/examples/multiple.go @@ -0,0 +1,98 @@ +// Copyright 2021 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 foo_test + +import ( + "flag" + "fmt" + "log" + "os/exec" + "sort" +) + +func ExampleHello() { + fmt.Println("Hello, world!") + // Output: Hello, world! +} + +func ExampleImport() { + out, err := exec.Command("date").Output() + if err != nil { + log.Fatal(err) + } + fmt.Printf("The date is %s\n", out) +} + +func ExampleKeyValue() { + v := struct { + a string + b int + }{ + a: "A", + b: 1, + } + fmt.Print(v) + // Output: a: "A", b: 1 +} + +func ExampleKeyValueImport() { + f := flag.Flag{ + Name: "play", + } + fmt.Print(f) + // Output: Name: "play" +} + +var keyValueTopDecl = struct { + a string + b int +}{ + a: "B", + b: 2, +} + +func ExampleKeyValueTopDecl() { + fmt.Print(keyValueTopDecl) + // Output: a: "B", b: 2 +} + +// Person represents a person by name and age. +type Person struct { + Name string + Age int +} + +// String returns a string representation of the Person. +func (p Person) String() string { + return fmt.Sprintf("%s: %d", p.Name, p.Age) +} + +// ByAge implements sort.Interface for []Person based on +// the Age field. +type ByAge []Person + +// Len returns the number of elements in ByAge. +func (a ByAge) Len() int { return len(a) } + +// Swap swaps the elements in ByAge. +func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age } + +// people is the array of Person +var people = []Person{ + {"Bob", 31}, + {"John", 42}, + {"Michael", 17}, + {"Jenny", 26}, +} + +func ExampleSort() { + fmt.Println(people) + sort.Sort(ByAge(people)) + fmt.Println(people) + // Output: + // [Bob: 31 John: 42 Michael: 17 Jenny: 26] + // [Michael: 17 Jenny: 26 Bob: 31 John: 42] +} diff --git a/src/go/doc/testdata/examples/multiple.golden b/src/go/doc/testdata/examples/multiple.golden new file mode 100644 index 0000000000..d2d791effa --- /dev/null +++ b/src/go/doc/testdata/examples/multiple.golden @@ -0,0 +1,129 @@ +-- Hello.Play -- +package main + +import ( + "fmt" +) + +func main() { + fmt.Println("Hello, world!") +} +-- Hello.Output -- +Hello, world! +-- Import.Play -- +package main + +import ( + "fmt" + "log" + "os/exec" +) + +func main() { + out, err := exec.Command("date").Output() + if err != nil { + log.Fatal(err) + } + fmt.Printf("The date is %s\n", out) +} +-- KeyValue.Play -- +package main + +import ( + "fmt" +) + +func main() { + v := struct { + a string + b int + }{ + a: "A", + b: 1, + } + fmt.Print(v) +} +-- KeyValue.Output -- +a: "A", b: 1 +-- KeyValueImport.Play -- +package main + +import ( + "flag" + "fmt" +) + +func main() { + f := flag.Flag{ + Name: "play", + } + fmt.Print(f) +} +-- KeyValueImport.Output -- +Name: "play" +-- KeyValueTopDecl.Play -- +package main + +import ( + "fmt" +) + +var keyValueTopDecl = struct { + a string + b int +}{ + a: "B", + b: 2, +} + +func main() { + fmt.Print(keyValueTopDecl) +} +-- KeyValueTopDecl.Output -- +a: "B", b: 2 +-- Sort.Play -- +package main + +import ( + "fmt" + "sort" +) + +// Person represents a person by name and age. +type Person struct { + Name string + Age int +} + +// String returns a string representation of the Person. +func (p Person) String() string { + return fmt.Sprintf("%s: %d", p.Name, p.Age) +} + +// ByAge implements sort.Interface for []Person based on +// the Age field. +type ByAge []Person + +// Len returns the number of elements in ByAge. +func (a ByAge) Len() int { return len(a) } + +// Swap swaps the elements in ByAge. +func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age } + +// people is the array of Person +var people = []Person{ + {"Bob", 31}, + {"John", 42}, + {"Michael", 17}, + {"Jenny", 26}, +} + +func main() { + fmt.Println(people) + sort.Sort(ByAge(people)) + fmt.Println(people) +} +-- Sort.Output -- +[Bob: 31 John: 42 Michael: 17 Jenny: 26] +[Michael: 17 Jenny: 26 Bob: 31 John: 42] diff --git a/src/go/doc/testdata/examples/whole_file.go b/src/go/doc/testdata/examples/whole_file.go new file mode 100644 index 0000000000..61954cecea --- /dev/null +++ b/src/go/doc/testdata/examples/whole_file.go @@ -0,0 +1,23 @@ +// Copyright 2021 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 foo_test + +import "fmt" + +type X int + +func (X) Foo() { +} + +func (X) TestBlah() { +} + +func (X) BenchmarkFoo() { +} + +func Example() { + fmt.Println("Hello, world!") + // Output: Hello, world! +} diff --git a/src/go/doc/testdata/examples/whole_file.golden b/src/go/doc/testdata/examples/whole_file.golden new file mode 100644 index 0000000000..74a2291f51 --- /dev/null +++ b/src/go/doc/testdata/examples/whole_file.golden @@ -0,0 +1,21 @@ +-- .Play -- +package main + +import "fmt" + +type X int + +func (X) Foo() { +} + +func (X) TestBlah() { +} + +func (X) BenchmarkFoo() { +} + +func main() { + fmt.Println("Hello, world!") +} +-- .Output -- +Hello, world! diff --git a/src/go/doc/testdata/examples/whole_function.go b/src/go/doc/testdata/examples/whole_function.go new file mode 100644 index 0000000000..1754ee3412 --- /dev/null +++ b/src/go/doc/testdata/examples/whole_function.go @@ -0,0 +1,13 @@ +// Copyright 2021 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 foo_test + +func Foo(x int) { +} + +func Example() { + fmt.Println("Hello, world!") + // Output: Hello, world! +} diff --git a/src/go/doc/testdata/examples/whole_function.golden b/src/go/doc/testdata/examples/whole_function.golden new file mode 100644 index 0000000000..7d5b5cbd7f --- /dev/null +++ b/src/go/doc/testdata/examples/whole_function.golden @@ -0,0 +1,11 @@ +-- .Play -- +package main + +func Foo(x int) { +} + +func main() { + fmt.Println("Hello, world!") +} +-- .Output -- +Hello, world! diff --git a/src/go/doc/testdata/examples/whole_function_external.go b/src/go/doc/testdata/examples/whole_function_external.go new file mode 100644 index 0000000000..0e0e2f5856 --- /dev/null +++ b/src/go/doc/testdata/examples/whole_function_external.go @@ -0,0 +1,12 @@ +// Copyright 2021 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 foo_test + +func foo(int) + +func Example() { + foo(42) + // Output: +} diff --git a/src/go/doc/testdata/examples/whole_function_external.golden b/src/go/doc/testdata/examples/whole_function_external.golden new file mode 100644 index 0000000000..ec8f114abe --- /dev/null +++ b/src/go/doc/testdata/examples/whole_function_external.golden @@ -0,0 +1,8 @@ +-- .Play -- +package main + +func foo(int) + +func main() { + foo(42) +}