github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/go/doc/example_test.go (about) 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 const exampleInspectSignature = `package foo_test 355 356 import ( 357 "bytes" 358 "io" 359 ) 360 361 func getReader() io.Reader { return nil } 362 363 func do(b bytes.Reader) {} 364 365 func Example() { 366 getReader() 367 do() 368 // Output: 369 } 370 371 func ExampleIgnored() { 372 } 373 ` 374 375 const exampleInspectSignatureOutput = `package main 376 377 import ( 378 "bytes" 379 "io" 380 ) 381 382 func getReader() io.Reader { return nil } 383 384 func do(b bytes.Reader) {} 385 386 func main() { 387 getReader() 388 do() 389 } 390 ` 391 392 func TestExampleInspectSignature(t *testing.T) { 393 // Verify that "bytes" and "io" are imported. See issue #28492. 394 fset := token.NewFileSet() 395 file, err := parser.ParseFile(fset, "test.go", strings.NewReader(exampleInspectSignature), parser.ParseComments) 396 if err != nil { 397 t.Fatal(err) 398 } 399 es := doc.Examples(file) 400 if len(es) != 2 { 401 t.Fatalf("wrong number of examples; got %d want 2", len(es)) 402 } 403 // We are interested in the first example only. 404 e := es[0] 405 if e.Name != "" { 406 t.Errorf("got Name == %q, want %q", e.Name, "") 407 } 408 if g, w := formatFile(t, fset, e.Play), exampleInspectSignatureOutput; g != w { 409 t.Errorf("got Play == %q, want %q", g, w) 410 } 411 if g, w := e.Output, ""; g != w { 412 t.Errorf("got Output == %q, want %q", g, w) 413 } 414 } 415 416 const exampleEmpty = ` 417 package p 418 func Example() {} 419 func Example_a() 420 ` 421 422 const exampleEmptyOutput = `package main 423 424 func main() {} 425 func main() 426 ` 427 428 func TestExampleEmpty(t *testing.T) { 429 fset := token.NewFileSet() 430 file, err := parser.ParseFile(fset, "test.go", strings.NewReader(exampleEmpty), parser.ParseComments) 431 if err != nil { 432 t.Fatal(err) 433 } 434 435 es := doc.Examples(file) 436 if len(es) != 1 { 437 t.Fatalf("wrong number of examples; got %d want 1", len(es)) 438 } 439 e := es[0] 440 if e.Name != "" { 441 t.Errorf("got Name == %q, want %q", e.Name, "") 442 } 443 if g, w := formatFile(t, fset, e.Play), exampleEmptyOutput; g != w { 444 t.Errorf("got Play == %q, want %q", g, w) 445 } 446 if g, w := e.Output, ""; g != w { 447 t.Errorf("got Output == %q, want %q", g, w) 448 } 449 } 450 451 func formatFile(t *testing.T, fset *token.FileSet, n *ast.File) string { 452 if n == nil { 453 return "<nil>" 454 } 455 var buf bytes.Buffer 456 if err := format.Node(&buf, fset, n); err != nil { 457 t.Fatal(err) 458 } 459 return buf.String() 460 }