main_test.go (4262B)
1 package main 2 3 import ( 4 "encoding/json" 5 "strings" 6 "testing" 7 ) 8 9 const fixture = `// Package fixture is read by the test. 10 package fixture 11 12 import ( 13 "fmt" 14 yaml "go.yaml.in/yaml/v4" 15 "path/filepath" 16 ) 17 18 // Limit bounds the work. 19 const Limit = 3 20 21 var ( 22 // count is kept between calls. 23 count int 24 name = "x" 25 ) 26 27 // Point is a place. 28 type Point struct { 29 // X is across. 30 X, Y int 31 label string 32 } 33 34 // Move shifts the point. 35 func (p *Point) Move(dx int) { p.X += dx } 36 37 func helper() { 38 const inner = 1 39 type pair struct{ a, b int } 40 f := func() { 41 var deep = 2 42 _ = deep 43 } 44 f() 45 _ = inner 46 fmt.Println(yaml.Marshal, filepath.Join) 47 } 48 49 func TestHelper(t *testing.T) { helper() } 50 51 /* block 52 comment */ 53 func BenchmarkHelper(b *testing.B) {} 54 ` 55 56 func TestReadFileListsEverything(t *testing.T) { 57 file := readFile("fixture.go", []byte(fixture)) 58 if file.Error != "" { 59 t.Fatal(file.Error) 60 } 61 if file.Package != "fixture" { 62 t.Errorf("package %q", file.Package) 63 } 64 if got := strings.Join(file.Imports, ","); got != "fmt,yaml,filepath" { 65 t.Errorf("imports %q", got) 66 } 67 want := map[string]Decl{ 68 "Limit": {Kind: "const", Line: 11, Exported: true, Doc: "Limit bounds the work.", Text: "const Limit = 3"}, 69 "count": {Kind: "var", Line: 15, Doc: "count is kept between calls.", Text: "count int"}, 70 "name": {Kind: "var", Line: 16, Text: `name = "x"`}, 71 "Point": {Kind: "type", Line: 20, Exported: true, Doc: "Point is a place.", Text: "type Point struct {"}, 72 "X": {Kind: "field", Line: 22, Exported: true, Doc: "X is across.", Text: "X, Y int"}, 73 "Y": {Kind: "field", Line: 22, Exported: true, Doc: "X is across.", Text: "X, Y int"}, 74 "label": {Kind: "field", Line: 23, Text: "label string"}, 75 "Move": {Kind: "func", Line: 27, Exported: true, Doc: "Move shifts the point.", Text: "func (p *Point) Move(dx int) { p.X += dx }"}, 76 "helper": {Kind: "func", Line: 29, Text: "func helper() {"}, 77 "inner": {Kind: "const", Line: 30, Local: true, Text: "const inner = 1"}, 78 "pair": {Kind: "type", Line: 31, Local: true, Text: "type pair struct{ a, b int }"}, 79 "a": {Kind: "field", Line: 31, Local: true, Text: "type pair struct{ a, b int }"}, 80 "b": {Kind: "field", Line: 31, Local: true, Text: "type pair struct{ a, b int }"}, 81 "deep": {Kind: "var", Line: 33, Local: true, Text: "var deep = 2"}, 82 "TestHelper": {Kind: "func", Line: 41, Exported: true, Test: true, Text: "func TestHelper(t *testing.T) { helper() }"}, 83 "BenchmarkHelper": {Kind: "func", Line: 45, Exported: true, Test: true, Doc: "block\ncomment", Text: "func BenchmarkHelper(b *testing.B) {}"}, 84 } 85 if len(file.Decls) != len(want) { 86 names := []string{} 87 for _, d := range file.Decls { 88 names = append(names, d.Name) 89 } 90 t.Errorf("%d declarations %v, want %d", len(file.Decls), names, len(want)) 91 } 92 for _, got := range file.Decls { 93 w, ok := want[got.Name] 94 if !ok { 95 t.Errorf("unexpected %+v", got) 96 continue 97 } 98 w.Name = got.Name 99 w.EndLine = got.EndLine 100 if got != w { 101 t.Errorf("%s:\n got %+v\nwant %+v", got.Name, got, w) 102 } 103 if got.EndLine < got.Line { 104 t.Errorf("%s ends on %d before it starts on %d", got.Name, got.EndLine, got.Line) 105 } 106 } 107 for _, d := range file.Decls { 108 if d.Name == "helper" && d.EndLine != 39 { 109 t.Errorf("helper ends on %d, want 39", d.EndLine) 110 } 111 } 112 comments := map[int]string{} 113 for _, c := range file.Comments { 114 comments[c.Line] = c.Text 115 } 116 for line, text := range map[int]string{1: "Package fixture is read by the test.", 14: "count is kept between calls.", 43: "/* block\ncomment */"} { 117 if comments[line] != text { 118 t.Errorf("comment on %d: %q, want %q", line, comments[line], text) 119 } 120 } 121 } 122 123 func TestReadFileReportsAParseError(t *testing.T) { 124 file := readFile("broken.go", []byte("package x\nfunc {")) 125 if file.Error == "" || len(file.Decls) != 0 { 126 t.Errorf("%+v", file) 127 } 128 data, err := json.Marshal(Output{Files: []File{file}}) 129 if err != nil { 130 t.Fatal(err) 131 } 132 for _, key := range []string{`"imports":[]`, `"decls":[]`, `"comments":[]`, `"error":`} { 133 if !strings.Contains(string(data), key) { 134 t.Errorf("%s missing from %s", key, data) 135 } 136 } 137 }