aboutsummaryrefslogtreecommitdiff
path: root/go/analysis/analysistest/analysistest.go
diff options
context:
space:
mode:
Diffstat (limited to 'go/analysis/analysistest/analysistest.go')
-rw-r--r--go/analysis/analysistest/analysistest.go96
1 files changed, 49 insertions, 47 deletions
diff --git a/go/analysis/analysistest/analysistest.go b/go/analysis/analysistest/analysistest.go
index df79a4419..be016e7e9 100644
--- a/go/analysis/analysistest/analysistest.go
+++ b/go/analysis/analysistest/analysistest.go
@@ -19,14 +19,13 @@ import (
"sort"
"strconv"
"strings"
+ "testing"
"text/scanner"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/internal/checker"
"golang.org/x/tools/go/packages"
- "golang.org/x/tools/internal/lsp/diff"
- "golang.org/x/tools/internal/lsp/diff/myers"
- "golang.org/x/tools/internal/span"
+ "golang.org/x/tools/internal/diff"
"golang.org/x/tools/internal/testenv"
"golang.org/x/tools/txtar"
)
@@ -81,23 +80,24 @@ type Testing interface {
// Each section in the archive corresponds to a single message.
//
// A golden file using txtar may look like this:
-// -- turn into single negation --
-// package pkg
//
-// func fn(b1, b2 bool) {
-// if !b1 { // want `negating a boolean twice`
-// println()
-// }
-// }
+// -- turn into single negation --
+// package pkg
//
-// -- remove double negation --
-// package pkg
+// func fn(b1, b2 bool) {
+// if !b1 { // want `negating a boolean twice`
+// println()
+// }
+// }
//
-// func fn(b1, b2 bool) {
-// if b1 { // want `negating a boolean twice`
-// println()
-// }
-// }
+// -- remove double negation --
+// package pkg
+//
+// func fn(b1, b2 bool) {
+// if b1 { // want `negating a boolean twice`
+// println()
+// }
+// }
func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns ...string) []*Result {
r := Run(t, dir, a, patterns...)
@@ -113,7 +113,7 @@ func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns
// should match up.
for _, act := range r {
// file -> message -> edits
- fileEdits := make(map[*token.File]map[string][]diff.TextEdit)
+ fileEdits := make(map[*token.File]map[string][]diff.Edit)
fileContents := make(map[*token.File][]byte)
// Validate edits, prepare the fileEdits map and read the file contents.
@@ -141,17 +141,13 @@ func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns
}
fileContents[file] = contents
}
- spn, err := span.NewRange(act.Pass.Fset, edit.Pos, edit.End).Span()
- if err != nil {
- t.Errorf("error converting edit to span %s: %v", file.Name(), err)
- }
-
if _, ok := fileEdits[file]; !ok {
- fileEdits[file] = make(map[string][]diff.TextEdit)
+ fileEdits[file] = make(map[string][]diff.Edit)
}
- fileEdits[file][sf.Message] = append(fileEdits[file][sf.Message], diff.TextEdit{
- Span: spn,
- NewText: string(edit.NewText),
+ fileEdits[file][sf.Message] = append(fileEdits[file][sf.Message], diff.Edit{
+ Start: file.Offset(edit.Pos),
+ End: file.Offset(edit.End),
+ New: string(edit.NewText),
})
}
}
@@ -188,23 +184,24 @@ func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns
for _, vf := range ar.Files {
if vf.Name == sf {
found = true
- out := diff.ApplyEdits(string(orig), edits)
+ out, err := diff.ApplyBytes(orig, edits)
+ if err != nil {
+ t.Errorf("%s: error applying fixes: %v", file.Name(), err)
+ continue
+ }
// the file may contain multiple trailing
// newlines if the user places empty lines
// between files in the archive. normalize
// this to a single newline.
want := string(bytes.TrimRight(vf.Data, "\n")) + "\n"
- formatted, err := format.Source([]byte(out))
+ formatted, err := format.Source(out)
if err != nil {
t.Errorf("%s: error formatting edited source: %v\n%s", file.Name(), err, out)
continue
}
- if want != string(formatted) {
- d, err := myers.ComputeEdits("", want, string(formatted))
- if err != nil {
- t.Errorf("failed to compute suggested fix diff: %v", err)
- }
- t.Errorf("suggested fixes failed for %s:\n%s", file.Name(), diff.ToUnified(fmt.Sprintf("%s.golden [%s]", file.Name(), sf), "actual", want, d))
+ if got := string(formatted); got != want {
+ unified := diff.Unified(fmt.Sprintf("%s.golden [%s]", file.Name(), sf), "actual", want, got)
+ t.Errorf("suggested fixes failed for %s:\n%s", file.Name(), unified)
}
break
}
@@ -216,25 +213,26 @@ func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns
} else {
// all suggested fixes are represented by a single file
- var catchallEdits []diff.TextEdit
+ var catchallEdits []diff.Edit
for _, edits := range fixes {
catchallEdits = append(catchallEdits, edits...)
}
- out := diff.ApplyEdits(string(orig), catchallEdits)
+ out, err := diff.ApplyBytes(orig, catchallEdits)
+ if err != nil {
+ t.Errorf("%s: error applying fixes: %v", file.Name(), err)
+ continue
+ }
want := string(ar.Comment)
- formatted, err := format.Source([]byte(out))
+ formatted, err := format.Source(out)
if err != nil {
t.Errorf("%s: error formatting resulting source: %v\n%s", file.Name(), err, out)
continue
}
- if want != string(formatted) {
- d, err := myers.ComputeEdits("", want, string(formatted))
- if err != nil {
- t.Errorf("%s: failed to compute suggested fix diff: %s", file.Name(), err)
- }
- t.Errorf("suggested fixes failed for %s:\n%s", file.Name(), diff.ToUnified(file.Name()+".golden", "actual", want, d))
+ if got := string(formatted); got != want {
+ unified := diff.Unified(file.Name()+".golden", "actual", want, got)
+ t.Errorf("suggested fixes failed for %s:\n%s", file.Name(), unified)
}
}
}
@@ -248,7 +246,8 @@ func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns
// directory using golang.org/x/tools/go/packages, runs the analysis on
// them, and checks that each analysis emits the expected diagnostics
// and facts specified by the contents of '// want ...' comments in the
-// package's source files.
+// package's source files. It treats a comment of the form
+// "//...// want..." or "/*...// want... */" as if it starts at 'want'
//
// An expectation of a Diagnostic is specified by a string literal
// containing a regular expression that must match the diagnostic
@@ -280,7 +279,7 @@ func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns
// attempted, even if unsuccessful. It is safe for a test to ignore all
// the results, but a test may use it to perform additional checks.
func Run(t Testing, dir string, a *analysis.Analyzer, patterns ...string) []*Result {
- if t, ok := t.(testenv.Testing); ok {
+ if t, ok := t.(testing.TB); ok {
testenv.NeedsGoPackages(t)
}
@@ -316,8 +315,11 @@ func loadPackages(a *analysis.Analyzer, dir string, patterns ...string) ([]*pack
// a list of packages we generate and then do the parsing and
// typechecking, though this feature seems to be a recurring need.
+ mode := packages.NeedName | packages.NeedFiles | packages.NeedCompiledGoFiles | packages.NeedImports |
+ packages.NeedTypes | packages.NeedTypesSizes | packages.NeedSyntax | packages.NeedTypesInfo |
+ packages.NeedDeps
cfg := &packages.Config{
- Mode: packages.LoadAllSyntax,
+ Mode: mode,
Dir: dir,
Tests: true,
Env: append(os.Environ(), "GOPATH="+dir, "GO111MODULE=off", "GOPROXY=off"),