github.com/nya3jp/tast@v0.0.0-20230601000426-85c8e4d83a9b/src/go.chromium.org/tast/core/cmd/tast-lint/internal/check/common_test.go (about) 1 // Copyright 2018 The ChromiumOS Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package check 6 7 import ( 8 "bytes" 9 "fmt" 10 "go/ast" 11 "go/format" 12 "go/parser" 13 "go/token" 14 "io/ioutil" 15 "os" 16 "os/exec" 17 "path/filepath" 18 "strings" 19 "testing" 20 21 "github.com/google/go-cmp/cmp" 22 "github.com/google/go-cmp/cmp/cmpopts" 23 24 "go.chromium.org/tast/core/testutil" 25 ) 26 27 func parse(code, filename string) (*ast.File, *token.FileSet) { 28 fs := token.NewFileSet() 29 f, err := parser.ParseFile(fs, filename, code, parser.ParseComments) 30 if err != nil { 31 panic(err) 32 } 33 return f, fs 34 } 35 36 func verifyIssues(t *testing.T, issues []*Issue, want []string) { 37 t.Helper() 38 39 SortIssues(issues) 40 41 got := make([]string, len(issues)) 42 for i, issue := range issues { 43 got[i] = issue.String() 44 } 45 46 if diff := cmp.Diff(got, want, cmpopts.EquateEmpty()); diff != "" { 47 t.Errorf("Issues mismatch (-got +want):\n%s", diff) 48 } 49 } 50 51 func verifyAutoFix(t *testing.T, lintfunc func(*token.FileSet, *ast.File, bool) []*Issue, files, expects map[string]string) { 52 t.Helper() 53 54 tempDir := testutil.TempDir(t) 55 defer os.RemoveAll(tempDir) 56 testutil.WriteFiles(tempDir, files) 57 58 fs := token.NewFileSet() 59 for filename := range files { 60 path := filepath.Join(tempDir, filename) 61 f, err := parser.ParseFile(fs, path, nil, parser.ParseComments) 62 if err != nil { 63 t.Error(err) 64 continue 65 } 66 67 lintfunc(fs, f, true) 68 69 if err := func() error { 70 file, err := os.Create(path) 71 if err != nil { 72 return err 73 } 74 defer file.Close() 75 if err := format.Node(file, fs, f); err != nil { 76 return err 77 } 78 return nil 79 }(); err != nil { 80 t.Error(err) 81 continue 82 } 83 84 bytesread, err := ioutil.ReadFile(path) 85 if err != nil { 86 t.Error(err) 87 continue 88 } 89 if err := fmtError(bytesread); err != nil { 90 t.Error(err) 91 continue 92 } 93 } 94 95 files, err := testutil.ReadFiles(tempDir) 96 if err != nil { 97 t.Error(err) 98 } 99 100 for filename := range files { 101 got := splitLines(files[filename]) 102 want := splitLines(expects[filename]) 103 104 if len(got) > len(want) { 105 for i := range want { 106 if diff := cmp.Diff(got[i], want[i], cmpopts.EquateEmpty()); diff != "" { 107 t.Errorf("AutoFix failed (-got +want):%s:%d:\n%s", filename, i+1, diff) 108 } 109 } 110 for i := len(want); i < len(got); i++ { 111 if diff := cmp.Diff(got[i], "", cmpopts.EquateEmpty()); diff != "" { 112 t.Errorf("AutoFix failed (-got +want):%s:%d:\n%s", filename, i+1, diff) 113 } 114 } 115 } else { 116 for i := range got { 117 if diff := cmp.Diff(got[i], want[i], cmpopts.EquateEmpty()); diff != "" { 118 t.Errorf("AutoFix failed (-got +want):%s:%d:\n%s", filename, i+1, diff) 119 } 120 } 121 for i := len(got); i < len(want); i++ { 122 if diff := cmp.Diff("", want[i], cmpopts.EquateEmpty()); diff != "" { 123 t.Errorf("AutoFix failed (-got +want):%s:%d:\n%s", filename, i+1, diff) 124 } 125 } 126 } 127 } 128 } 129 130 // splitLines split given string into string slice of lines which was ended with "\n". 131 // Also, all "\t" are replaced by a white space. 132 func splitLines(s string) []string { 133 lines := strings.Split(s, "\n") 134 for i := range lines { 135 lines[i] = strings.Replace(lines[i], "\t", " ", -1) 136 } 137 return lines 138 } 139 140 // fmtError runs gofmt to see if code has any formatting error. 141 func fmtError(code []byte) error { 142 cmd := exec.Command("gofmt", "-l") 143 cmd.Stdin = bytes.NewBuffer(code) 144 out, err := cmd.Output() 145 if err != nil { 146 return fmt.Errorf("Failed gofmt: %v", err) 147 } 148 if len(out) > 0 { 149 return fmt.Errorf("File's formatting is different from gofmt's: %s", out) 150 } 151 return nil 152 }