review

review patchsets using your default editor
Log | Files | Refs

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 }