...
Run Format

Source file src/go/doc/example_test.go

Documentation: go/doc

     1  // Copyright 2013 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 doc_test
     6  
     7  import (
     8  	"bytes"
     9  	"go/ast"
    10  	"go/doc"
    11  	"go/format"
    12  	"go/parser"
    13  	"go/token"
    14  	"strings"
    15  	"testing"
    16  )
    17  
    18  const exampleTestFile = `
    19  package foo_test
    20  
    21  import (
    22  	"flag"
    23  	"fmt"
    24  	"log"
    25  	"sort"
    26  	"os/exec"
    27  )
    28  
    29  func ExampleHello() {
    30  	fmt.Println("Hello, world!")
    31  	// Output: Hello, world!
    32  }
    33  
    34  func ExampleImport() {
    35  	out, err := exec.Command("date").Output()
    36  	if err != nil {
    37  		log.Fatal(err)
    38  	}
    39  	fmt.Printf("The date is %s\n", out)
    40  }
    41  
    42  func ExampleKeyValue() {
    43  	v := struct {
    44  		a string
    45  		b int
    46  	}{
    47  		a: "A",
    48  		b: 1,
    49  	}
    50  	fmt.Print(v)
    51  	// Output: a: "A", b: 1
    52  }
    53  
    54  func ExampleKeyValueImport() {
    55  	f := flag.Flag{
    56  		Name: "play",
    57  	}
    58  	fmt.Print(f)
    59  	// Output: Name: "play"
    60  }
    61  
    62  var keyValueTopDecl = struct {
    63  	a string
    64  	b int
    65  }{
    66  	a: "B",
    67  	b: 2,
    68  }
    69  
    70  func ExampleKeyValueTopDecl() {
    71  	fmt.Print(keyValueTopDecl)
    72  	// Output: a: "B", b: 2
    73  }
    74  
    75  // Person represents a person by name and age.
    76  type Person struct {
    77      Name string
    78      Age  int
    79  }
    80  
    81  // String returns a string representation of the Person.
    82  func (p Person) String() string {
    83      return fmt.Sprintf("%s: %d", p.Name, p.Age)
    84  }
    85  
    86  // ByAge implements sort.Interface for []Person based on
    87  // the Age field.
    88  type ByAge []Person
    89  
    90  // Len returns the number of elements in ByAge.
    91  func (a (ByAge)) Len() int { return len(a) }
    92  
    93  // Swap swaps the elements in ByAge.
    94  func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
    95  func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
    96  
    97  // people is the array of Person
    98  var people = []Person{
    99  	{"Bob", 31},
   100  	{"John", 42},
   101  	{"Michael", 17},
   102  	{"Jenny", 26},
   103  }
   104  
   105  func ExampleSort() {
   106      fmt.Println(people)
   107      sort.Sort(ByAge(people))
   108      fmt.Println(people)
   109      // Output:
   110      // [Bob: 31 John: 42 Michael: 17 Jenny: 26]
   111      // [Michael: 17 Jenny: 26 Bob: 31 John: 42]
   112  }
   113  `
   114  
   115  var exampleTestCases = []struct {
   116  	Name, Play, Output string
   117  }{
   118  	{
   119  		Name:   "Hello",
   120  		Play:   exampleHelloPlay,
   121  		Output: "Hello, world!\n",
   122  	},
   123  	{
   124  		Name: "Import",
   125  		Play: exampleImportPlay,
   126  	},
   127  	{
   128  		Name:   "KeyValue",
   129  		Play:   exampleKeyValuePlay,
   130  		Output: "a: \"A\", b: 1\n",
   131  	},
   132  	{
   133  		Name:   "KeyValueImport",
   134  		Play:   exampleKeyValueImportPlay,
   135  		Output: "Name: \"play\"\n",
   136  	},
   137  	{
   138  		Name:   "KeyValueTopDecl",
   139  		Play:   exampleKeyValueTopDeclPlay,
   140  		Output: "a: \"B\", b: 2\n",
   141  	},
   142  	{
   143  		Name:   "Sort",
   144  		Play:   exampleSortPlay,
   145  		Output: "[Bob: 31 John: 42 Michael: 17 Jenny: 26]\n[Michael: 17 Jenny: 26 Bob: 31 John: 42]\n",
   146  	},
   147  }
   148  
   149  const exampleHelloPlay = `package main
   150  
   151  import (
   152  	"fmt"
   153  )
   154  
   155  func main() {
   156  	fmt.Println("Hello, world!")
   157  }
   158  `
   159  const exampleImportPlay = `package main
   160  
   161  import (
   162  	"fmt"
   163  	"log"
   164  	"os/exec"
   165  )
   166  
   167  func main() {
   168  	out, err := exec.Command("date").Output()
   169  	if err != nil {
   170  		log.Fatal(err)
   171  	}
   172  	fmt.Printf("The date is %s\n", out)
   173  }
   174  `
   175  
   176  const exampleKeyValuePlay = `package main
   177  
   178  import (
   179  	"fmt"
   180  )
   181  
   182  func main() {
   183  	v := struct {
   184  		a string
   185  		b int
   186  	}{
   187  		a: "A",
   188  		b: 1,
   189  	}
   190  	fmt.Print(v)
   191  }
   192  `
   193  
   194  const exampleKeyValueImportPlay = `package main
   195  
   196  import (
   197  	"flag"
   198  	"fmt"
   199  )
   200  
   201  func main() {
   202  	f := flag.Flag{
   203  		Name: "play",
   204  	}
   205  	fmt.Print(f)
   206  }
   207  `
   208  
   209  const exampleKeyValueTopDeclPlay = `package main
   210  
   211  import (
   212  	"fmt"
   213  )
   214  
   215  var keyValueTopDecl = struct {
   216  	a string
   217  	b int
   218  }{
   219  	a: "B",
   220  	b: 2,
   221  }
   222  
   223  func main() {
   224  	fmt.Print(keyValueTopDecl)
   225  }
   226  `
   227  
   228  const exampleSortPlay = `package main
   229  
   230  import (
   231  	"fmt"
   232  	"sort"
   233  )
   234  
   235  // Person represents a person by name and age.
   236  type Person struct {
   237  	Name string
   238  	Age  int
   239  }
   240  
   241  // String returns a string representation of the Person.
   242  func (p Person) String() string {
   243  	return fmt.Sprintf("%s: %d", p.Name, p.Age)
   244  }
   245  
   246  // ByAge implements sort.Interface for []Person based on
   247  // the Age field.
   248  type ByAge []Person
   249  
   250  // Len returns the number of elements in ByAge.
   251  func (a ByAge) Len() int { return len(a) }
   252  
   253  // Swap swaps the elements in ByAge.
   254  func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
   255  func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
   256  
   257  // people is the array of Person
   258  var people = []Person{
   259  	{"Bob", 31},
   260  	{"John", 42},
   261  	{"Michael", 17},
   262  	{"Jenny", 26},
   263  }
   264  
   265  func main() {
   266  	fmt.Println(people)
   267  	sort.Sort(ByAge(people))
   268  	fmt.Println(people)
   269  }
   270  `
   271  
   272  func TestExamples(t *testing.T) {
   273  	fset := token.NewFileSet()
   274  	file, err := parser.ParseFile(fset, "test.go", strings.NewReader(exampleTestFile), parser.ParseComments)
   275  	if err != nil {
   276  		t.Fatal(err)
   277  	}
   278  	for i, e := range doc.Examples(file) {
   279  		c := exampleTestCases[i]
   280  		if e.Name != c.Name {
   281  			t.Errorf("got Name == %q, want %q", e.Name, c.Name)
   282  		}
   283  		if w := c.Play; w != "" {
   284  			g := formatFile(t, fset, e.Play)
   285  			if g != w {
   286  				t.Errorf("%s: got Play == %q, want %q", c.Name, g, w)
   287  			}
   288  		}
   289  		if g, w := e.Output, c.Output; g != w {
   290  			t.Errorf("%s: got Output == %q, want %q", c.Name, g, w)
   291  		}
   292  	}
   293  }
   294  
   295  const exampleWholeFile = `package foo_test
   296  
   297  type X int
   298  
   299  func (X) Foo() {
   300  }
   301  
   302  func (X) TestBlah() {
   303  }
   304  
   305  func (X) BenchmarkFoo() {
   306  }
   307  
   308  func Example() {
   309  	fmt.Println("Hello, world!")
   310  	// Output: Hello, world!
   311  }
   312  `
   313  
   314  const exampleWholeFileOutput = `package main
   315  
   316  type X int
   317  
   318  func (X) Foo() {
   319  }
   320  
   321  func (X) TestBlah() {
   322  }
   323  
   324  func (X) BenchmarkFoo() {
   325  }
   326  
   327  func main() {
   328  	fmt.Println("Hello, world!")
   329  }
   330  `
   331  
   332  func TestExamplesWholeFile(t *testing.T) {
   333  	fset := token.NewFileSet()
   334  	file, err := parser.ParseFile(fset, "test.go", strings.NewReader(exampleWholeFile), parser.ParseComments)
   335  	if err != nil {
   336  		t.Fatal(err)
   337  	}
   338  	es := doc.Examples(file)
   339  	if len(es) != 1 {
   340  		t.Fatalf("wrong number of examples; got %d want 1", len(es))
   341  	}
   342  	e := es[0]
   343  	if e.Name != "" {
   344  		t.Errorf("got Name == %q, want %q", e.Name, "")
   345  	}
   346  	if g, w := formatFile(t, fset, e.Play), exampleWholeFileOutput; g != w {
   347  		t.Errorf("got Play == %q, want %q", g, w)
   348  	}
   349  	if g, w := e.Output, "Hello, world!\n"; g != w {
   350  		t.Errorf("got Output == %q, want %q", g, w)
   351  	}
   352  }
   353  
   354  func formatFile(t *testing.T, fset *token.FileSet, n *ast.File) string {
   355  	if n == nil {
   356  		return "<nil>"
   357  	}
   358  	var buf bytes.Buffer
   359  	if err := format.Node(&buf, fset, n); err != nil {
   360  		t.Fatal(err)
   361  	}
   362  	return buf.String()
   363  }
   364  

View as plain text