.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.1.0 / go / callgraph / cha / cha_test.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.1.0/go/callgraph/cha/cha_test.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.1.0/go/callgraph/cha/cha_test.go
new file mode 100644 (file)
index 0000000..cb2d585
--- /dev/null
@@ -0,0 +1,111 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// No testdata on Android.
+
+// +build !android
+
+package cha_test
+
+import (
+       "bytes"
+       "fmt"
+       "go/ast"
+       "go/parser"
+       "go/token"
+       "go/types"
+       "io/ioutil"
+       "sort"
+       "strings"
+       "testing"
+
+       "golang.org/x/tools/go/callgraph"
+       "golang.org/x/tools/go/callgraph/cha"
+       "golang.org/x/tools/go/loader"
+       "golang.org/x/tools/go/ssa/ssautil"
+)
+
+var inputs = []string{
+       "testdata/func.go",
+       "testdata/iface.go",
+       "testdata/recv.go",
+       "testdata/issue23925.go",
+}
+
+func expectation(f *ast.File) (string, token.Pos) {
+       for _, c := range f.Comments {
+               text := strings.TrimSpace(c.Text())
+               if t := strings.TrimPrefix(text, "WANT:\n"); t != text {
+                       return t, c.Pos()
+               }
+       }
+       return "", token.NoPos
+}
+
+// TestCHA runs CHA on each file in inputs, prints the dynamic edges of
+// the call graph, and compares it with the golden results embedded in
+// the WANT comment at the end of the file.
+//
+func TestCHA(t *testing.T) {
+       for _, filename := range inputs {
+               content, err := ioutil.ReadFile(filename)
+               if err != nil {
+                       t.Errorf("couldn't read file '%s': %s", filename, err)
+                       continue
+               }
+
+               conf := loader.Config{
+                       ParserMode: parser.ParseComments,
+               }
+               f, err := conf.ParseFile(filename, content)
+               if err != nil {
+                       t.Error(err)
+                       continue
+               }
+
+               want, pos := expectation(f)
+               if pos == token.NoPos {
+                       t.Errorf("No WANT: comment in %s", filename)
+                       continue
+               }
+
+               conf.CreateFromFiles("main", f)
+               iprog, err := conf.Load()
+               if err != nil {
+                       t.Error(err)
+                       continue
+               }
+
+               prog := ssautil.CreateProgram(iprog, 0)
+               mainPkg := prog.Package(iprog.Created[0].Pkg)
+               prog.Build()
+
+               cg := cha.CallGraph(prog)
+
+               if got := printGraph(cg, mainPkg.Pkg); got != want {
+                       t.Errorf("%s: got:\n%s\nwant:\n%s",
+                               prog.Fset.Position(pos), got, want)
+               }
+       }
+}
+
+func printGraph(cg *callgraph.Graph, from *types.Package) string {
+       var edges []string
+       callgraph.GraphVisitEdges(cg, func(e *callgraph.Edge) error {
+               if strings.Contains(e.Description(), "dynamic") {
+                       edges = append(edges, fmt.Sprintf("%s --> %s",
+                               e.Caller.Func.RelString(from),
+                               e.Callee.Func.RelString(from)))
+               }
+               return nil
+       })
+       sort.Strings(edges)
+
+       var buf bytes.Buffer
+       buf.WriteString("Dynamic calls\n")
+       for _, edge := range edges {
+               fmt.Fprintf(&buf, "  %s\n", edge)
+       }
+       return strings.TrimSpace(buf.String())
+}