.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.1.0 / go / ast / astutil / enclosing_test.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.1.0/go/ast/astutil/enclosing_test.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.1.0/go/ast/astutil/enclosing_test.go
new file mode 100644 (file)
index 0000000..107f87c
--- /dev/null
@@ -0,0 +1,195 @@
+// Copyright 2013 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.
+
+package astutil_test
+
+// This file defines tests of PathEnclosingInterval.
+
+// TODO(adonovan): exhaustive tests that run over the whole input
+// tree, not just handcrafted examples.
+
+import (
+       "bytes"
+       "fmt"
+       "go/ast"
+       "go/parser"
+       "go/token"
+       "strings"
+       "testing"
+
+       "golang.org/x/tools/go/ast/astutil"
+)
+
+// pathToString returns a string containing the concrete types of the
+// nodes in path.
+func pathToString(path []ast.Node) string {
+       var buf bytes.Buffer
+       fmt.Fprint(&buf, "[")
+       for i, n := range path {
+               if i > 0 {
+                       fmt.Fprint(&buf, " ")
+               }
+               fmt.Fprint(&buf, strings.TrimPrefix(fmt.Sprintf("%T", n), "*ast."))
+       }
+       fmt.Fprint(&buf, "]")
+       return buf.String()
+}
+
+// findInterval parses input and returns the [start, end) positions of
+// the first occurrence of substr in input.  f==nil indicates failure;
+// an error has already been reported in that case.
+//
+func findInterval(t *testing.T, fset *token.FileSet, input, substr string) (f *ast.File, start, end token.Pos) {
+       f, err := parser.ParseFile(fset, "<input>", input, 0)
+       if err != nil {
+               t.Errorf("parse error: %s", err)
+               return
+       }
+
+       i := strings.Index(input, substr)
+       if i < 0 {
+               t.Errorf("%q is not a substring of input", substr)
+               f = nil
+               return
+       }
+
+       filePos := fset.File(f.Package)
+       return f, filePos.Pos(i), filePos.Pos(i + len(substr))
+}
+
+// Common input for following tests.
+const input = `
+// Hello.
+package main
+import "fmt"
+func f() {}
+func main() {
+       z := (x + y) // add them
+        f() // NB: ExprStmt and its CallExpr have same Pos/End
+}
+`
+
+func TestPathEnclosingInterval_Exact(t *testing.T) {
+       // For the exact tests, we check that a substring is mapped to
+       // the canonical string for the node it denotes.
+       tests := []struct {
+               substr string // first occurrence of this string indicates interval
+               node   string // complete text of expected containing node
+       }{
+               {"package",
+                       input[11 : len(input)-1]},
+               {"\npack",
+                       input[11 : len(input)-1]},
+               {"main",
+                       "main"},
+               {"import",
+                       "import \"fmt\""},
+               {"\"fmt\"",
+                       "\"fmt\""},
+               {"\nfunc f() {}\n",
+                       "func f() {}"},
+               {"x ",
+                       "x"},
+               {" y",
+                       "y"},
+               {"z",
+                       "z"},
+               {" + ",
+                       "x + y"},
+               {" :=",
+                       "z := (x + y)"},
+               {"x + y",
+                       "x + y"},
+               {"(x + y)",
+                       "(x + y)"},
+               {" (x + y) ",
+                       "(x + y)"},
+               {" (x + y) // add",
+                       "(x + y)"},
+               {"func",
+                       "func f() {}"},
+               {"func f() {}",
+                       "func f() {}"},
+               {"\nfun",
+                       "func f() {}"},
+               {" f",
+                       "f"},
+       }
+       for _, test := range tests {
+               f, start, end := findInterval(t, new(token.FileSet), input, test.substr)
+               if f == nil {
+                       continue
+               }
+
+               path, exact := astutil.PathEnclosingInterval(f, start, end)
+               if !exact {
+                       t.Errorf("PathEnclosingInterval(%q) not exact", test.substr)
+                       continue
+               }
+
+               if len(path) == 0 {
+                       if test.node != "" {
+                               t.Errorf("PathEnclosingInterval(%q).path: got [], want %q",
+                                       test.substr, test.node)
+                       }
+                       continue
+               }
+
+               if got := input[path[0].Pos():path[0].End()]; got != test.node {
+                       t.Errorf("PathEnclosingInterval(%q): got %q, want %q (path was %s)",
+                               test.substr, got, test.node, pathToString(path))
+                       continue
+               }
+       }
+}
+
+func TestPathEnclosingInterval_Paths(t *testing.T) {
+       // For these tests, we check only the path of the enclosing
+       // node, but not its complete text because it's often quite
+       // large when !exact.
+       tests := []struct {
+               substr string // first occurrence of this string indicates interval
+               path   string // the pathToString(),exact of the expected path
+       }{
+               {"// add",
+                       "[BlockStmt FuncDecl File],false"},
+               {"(x + y",
+                       "[ParenExpr AssignStmt BlockStmt FuncDecl File],false"},
+               {"x +",
+                       "[BinaryExpr ParenExpr AssignStmt BlockStmt FuncDecl File],false"},
+               {"z := (x",
+                       "[AssignStmt BlockStmt FuncDecl File],false"},
+               {"func f",
+                       "[FuncDecl File],false"},
+               {"func f()",
+                       "[FuncDecl File],false"},
+               {" f()",
+                       "[FuncDecl File],false"},
+               {"() {}",
+                       "[FuncDecl File],false"},
+               {"// Hello",
+                       "[File],false"},
+               {" f",
+                       "[Ident FuncDecl File],true"},
+               {"func ",
+                       "[FuncDecl File],true"},
+               {"mai",
+                       "[Ident File],true"},
+               {"f() // NB",
+                       "[CallExpr ExprStmt BlockStmt FuncDecl File],true"},
+       }
+       for _, test := range tests {
+               f, start, end := findInterval(t, new(token.FileSet), input, test.substr)
+               if f == nil {
+                       continue
+               }
+
+               path, exact := astutil.PathEnclosingInterval(f, start, end)
+               if got := fmt.Sprintf("%s,%v", pathToString(path), exact); got != test.path {
+                       t.Errorf("PathEnclosingInterval(%q): got %q, want %q",
+                               test.substr, got, test.path)
+                       continue
+               }
+       }
+}