Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / internal / apidiff / apidiff_test.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/internal/apidiff/apidiff_test.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201028153306-37f0764111ff/internal/apidiff/apidiff_test.go
new file mode 100644 (file)
index 0000000..7910096
--- /dev/null
@@ -0,0 +1,171 @@
+package apidiff
+
+import (
+       "bufio"
+       "fmt"
+       "go/types"
+       "io/ioutil"
+       "os"
+       "path/filepath"
+       "reflect"
+       "sort"
+       "strings"
+       "testing"
+
+       "golang.org/x/tools/go/packages"
+       "golang.org/x/tools/internal/testenv"
+)
+
+func TestChanges(t *testing.T) {
+       dir, err := ioutil.TempDir("", "apidiff_test")
+       if err != nil {
+               t.Fatal(err)
+       }
+       dir = filepath.Join(dir, "go")
+       wanti, wantc := splitIntoPackages(t, dir)
+       defer os.RemoveAll(dir)
+       sort.Strings(wanti)
+       sort.Strings(wantc)
+
+       oldpkg, err := load(t, "apidiff/old", dir)
+       if err != nil {
+               t.Fatal(err)
+       }
+       newpkg, err := load(t, "apidiff/new", dir)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       report := Changes(oldpkg.Types, newpkg.Types)
+
+       got := report.messages(false)
+       if !reflect.DeepEqual(got, wanti) {
+               t.Errorf("incompatibles: got %v\nwant %v\n", got, wanti)
+       }
+       got = report.messages(true)
+       if !reflect.DeepEqual(got, wantc) {
+               t.Errorf("compatibles: got %v\nwant %v\n", got, wantc)
+       }
+}
+
+func splitIntoPackages(t *testing.T, dir string) (incompatibles, compatibles []string) {
+       // Read the input file line by line.
+       // Write a line into the old or new package,
+       // dependent on comments.
+       // Also collect expected messages.
+       f, err := os.Open("testdata/tests.go")
+       if err != nil {
+               t.Fatal(err)
+       }
+       defer f.Close()
+
+       if err := os.MkdirAll(filepath.Join(dir, "src", "apidiff"), 0700); err != nil {
+               t.Fatal(err)
+       }
+       if err := ioutil.WriteFile(filepath.Join(dir, "src", "apidiff", "go.mod"), []byte("module apidiff\n"), 0666); err != nil {
+               t.Fatal(err)
+       }
+
+       oldd := filepath.Join(dir, "src/apidiff/old")
+       newd := filepath.Join(dir, "src/apidiff/new")
+       if err := os.MkdirAll(oldd, 0700); err != nil {
+               t.Fatal(err)
+       }
+       if err := os.Mkdir(newd, 0700); err != nil && !os.IsExist(err) {
+               t.Fatal(err)
+       }
+
+       oldf, err := os.Create(filepath.Join(oldd, "old.go"))
+       if err != nil {
+               t.Fatal(err)
+       }
+       newf, err := os.Create(filepath.Join(newd, "new.go"))
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       wl := func(f *os.File, line string) {
+               if _, err := fmt.Fprintln(f, line); err != nil {
+                       t.Fatal(err)
+               }
+       }
+       writeBoth := func(line string) { wl(oldf, line); wl(newf, line) }
+       writeln := writeBoth
+       s := bufio.NewScanner(f)
+       for s.Scan() {
+               line := s.Text()
+               tl := strings.TrimSpace(line)
+               switch {
+               case tl == "// old":
+                       writeln = func(line string) { wl(oldf, line) }
+               case tl == "// new":
+                       writeln = func(line string) { wl(newf, line) }
+               case tl == "// both":
+                       writeln = writeBoth
+               case strings.HasPrefix(tl, "// i "):
+                       incompatibles = append(incompatibles, strings.TrimSpace(tl[4:]))
+               case strings.HasPrefix(tl, "// c "):
+                       compatibles = append(compatibles, strings.TrimSpace(tl[4:]))
+               default:
+                       writeln(line)
+               }
+       }
+       if s.Err() != nil {
+               t.Fatal(s.Err())
+       }
+       return
+}
+
+func load(t *testing.T, importPath, goPath string) (*packages.Package, error) {
+       testenv.NeedsGoPackages(t)
+
+       cfg := &packages.Config{
+               Mode: packages.LoadTypes,
+       }
+       if goPath != "" {
+               cfg.Env = append(os.Environ(), "GOPATH="+goPath)
+               cfg.Dir = filepath.Join(goPath, "src", filepath.FromSlash(importPath))
+       }
+       pkgs, err := packages.Load(cfg, importPath)
+       if err != nil {
+               return nil, err
+       }
+       if len(pkgs[0].Errors) > 0 {
+               return nil, pkgs[0].Errors[0]
+       }
+       return pkgs[0], nil
+}
+
+func TestExportedFields(t *testing.T) {
+       pkg, err := load(t, "golang.org/x/tools/internal/apidiff/testdata/exported_fields", "")
+       if err != nil {
+               t.Fatal(err)
+       }
+       typeof := func(name string) types.Type {
+               return pkg.Types.Scope().Lookup(name).Type()
+       }
+
+       s := typeof("S")
+       su := s.(*types.Named).Underlying().(*types.Struct)
+
+       ef := exportedSelectableFields(su)
+       wants := []struct {
+               name string
+               typ  types.Type
+       }{
+               {"A1", typeof("A1")},
+               {"D", types.Typ[types.Bool]},
+               {"E", types.Typ[types.Int]},
+               {"F", typeof("F")},
+               {"S", types.NewPointer(s)},
+       }
+
+       if got, want := len(ef), len(wants); got != want {
+               t.Errorf("got %d fields, want %d\n%+v", got, want, ef)
+       }
+       for _, w := range wants {
+               if got := ef[w.name]; got != nil && !types.Identical(got.Type(), w.typ) {
+                       t.Errorf("%s: got %v, want %v", w.name, got.Type(), w.typ)
+               }
+       }
+}