github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/go/analysis/internal/checker/checker_test.go (about) 1 // Copyright 2019 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package checker_test 6 7 import ( 8 "fmt" 9 "go/ast" 10 "io/ioutil" 11 "path/filepath" 12 "testing" 13 14 "github.com/powerman/golang-tools/go/analysis" 15 "github.com/powerman/golang-tools/go/analysis/analysistest" 16 "github.com/powerman/golang-tools/go/analysis/internal/checker" 17 "github.com/powerman/golang-tools/go/analysis/passes/inspect" 18 "github.com/powerman/golang-tools/go/ast/inspector" 19 "github.com/powerman/golang-tools/internal/testenv" 20 ) 21 22 var from, to string 23 24 func TestApplyFixes(t *testing.T) { 25 testenv.NeedsGoPackages(t) 26 27 from = "bar" 28 to = "baz" 29 30 files := map[string]string{ 31 "rename/test.go": `package rename 32 33 func Foo() { 34 bar := 12 35 _ = bar 36 } 37 38 // the end 39 `} 40 want := `package rename 41 42 func Foo() { 43 baz := 12 44 _ = baz 45 } 46 47 // the end 48 ` 49 50 testdata, cleanup, err := analysistest.WriteFiles(files) 51 if err != nil { 52 t.Fatal(err) 53 } 54 path := filepath.Join(testdata, "src/rename/test.go") 55 checker.Fix = true 56 checker.Run([]string{"file=" + path}, []*analysis.Analyzer{analyzer}) 57 58 contents, err := ioutil.ReadFile(path) 59 if err != nil { 60 t.Fatal(err) 61 } 62 63 got := string(contents) 64 if got != want { 65 t.Errorf("contents of rewritten file\ngot: %s\nwant: %s", got, want) 66 } 67 68 defer cleanup() 69 } 70 71 var analyzer = &analysis.Analyzer{ 72 Name: "rename", 73 Requires: []*analysis.Analyzer{inspect.Analyzer}, 74 Run: run, 75 } 76 77 func run(pass *analysis.Pass) (interface{}, error) { 78 inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) 79 nodeFilter := []ast.Node{(*ast.Ident)(nil)} 80 inspect.Preorder(nodeFilter, func(n ast.Node) { 81 ident := n.(*ast.Ident) 82 if ident.Name == from { 83 msg := fmt.Sprintf("renaming %q to %q", from, to) 84 pass.Report(analysis.Diagnostic{ 85 Pos: ident.Pos(), 86 End: ident.End(), 87 Message: msg, 88 SuggestedFixes: []analysis.SuggestedFix{{ 89 Message: msg, 90 TextEdits: []analysis.TextEdit{{ 91 Pos: ident.Pos(), 92 End: ident.End(), 93 NewText: []byte(to), 94 }}, 95 }}, 96 }) 97 } 98 }) 99 100 return nil, nil 101 } 102 103 func TestRunDespiteErrors(t *testing.T) { 104 testenv.NeedsGoPackages(t) 105 106 files := map[string]string{ 107 "rderr/test.go": `package rderr 108 109 // Foo deliberately has a type error 110 func Foo(s string) int { 111 return s + 1 112 } 113 `} 114 115 testdata, cleanup, err := analysistest.WriteFiles(files) 116 if err != nil { 117 t.Fatal(err) 118 } 119 path := filepath.Join(testdata, "src/rderr/test.go") 120 121 // A no-op analyzer that should finish regardless of 122 // parse or type errors in the code. 123 noop := &analysis.Analyzer{ 124 Name: "noop", 125 Requires: []*analysis.Analyzer{inspect.Analyzer}, 126 Run: func(pass *analysis.Pass) (interface{}, error) { 127 return nil, nil 128 }, 129 RunDespiteErrors: true, 130 } 131 132 for _, test := range []struct { 133 name string 134 pattern []string 135 analyzers []*analysis.Analyzer 136 code int 137 }{ 138 // parse/type errors 139 {name: "skip-error", pattern: []string{"file=" + path}, analyzers: []*analysis.Analyzer{analyzer}, code: 1}, 140 {name: "despite-error", pattern: []string{"file=" + path}, analyzers: []*analysis.Analyzer{noop}, code: 0}, 141 // combination of parse/type errors and no errors 142 {name: "despite-error-and-no-error", pattern: []string{"file=" + path, "sort"}, analyzers: []*analysis.Analyzer{analyzer, noop}, code: 1}, 143 // non-existing package error 144 {name: "no-package", pattern: []string{"xyz"}, analyzers: []*analysis.Analyzer{analyzer}, code: 1}, 145 {name: "no-package-despite-error", pattern: []string{"abc"}, analyzers: []*analysis.Analyzer{noop}, code: 1}, 146 {name: "no-multi-package-despite-error", pattern: []string{"xyz", "abc"}, analyzers: []*analysis.Analyzer{noop}, code: 1}, 147 // combination of type/parsing and different errors 148 {name: "different-errors", pattern: []string{"file=" + path, "xyz"}, analyzers: []*analysis.Analyzer{analyzer, noop}, code: 1}, 149 // non existing dir error 150 {name: "no-match-dir", pattern: []string{"file=non/existing/dir"}, analyzers: []*analysis.Analyzer{analyzer, noop}, code: 1}, 151 // no errors 152 {name: "no-errors", pattern: []string{"sort"}, analyzers: []*analysis.Analyzer{analyzer, noop}, code: 0}, 153 } { 154 if got := checker.Run(test.pattern, test.analyzers); got != test.code { 155 t.Errorf("got incorrect exit code %d for test %s; want %d", got, test.name, test.code) 156 } 157 } 158 159 defer cleanup() 160 }