github.com/pankona/gometalinter@v2.0.11+incompatible/regressiontests/support.go (about) 1 package regressiontests 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "os" 9 "os/exec" 10 "path/filepath" 11 "strings" 12 "testing" 13 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/require" 16 "gotest.tools/fs" 17 ) 18 19 type Issue struct { 20 Linter string `json:"linter"` 21 Severity string `json:"severity"` 22 Path string `json:"path"` 23 Line int `json:"line"` 24 Col int `json:"col"` 25 Message string `json:"message"` 26 } 27 28 func (i *Issue) String() string { 29 col := "" 30 if i.Col != 0 { 31 col = fmt.Sprintf("%d", i.Col) 32 } 33 return fmt.Sprintf("%s:%d:%s:%s: %s (%s)", strings.TrimSpace(i.Path), i.Line, col, i.Severity, strings.TrimSpace(i.Message), i.Linter) 34 } 35 36 type Issues []Issue 37 38 // ExpectIssues runs gometalinter and expects it to generate exactly the 39 // issues provided. 40 func ExpectIssues(t *testing.T, linter string, source string, expected Issues, extraFlags ...string) { 41 // Write source to temporary directory. 42 dir, err := ioutil.TempDir(".", "gometalinter-") 43 require.NoError(t, err) 44 defer os.RemoveAll(dir) 45 46 testFile := filepath.Join(dir, "test.go") 47 err = ioutil.WriteFile(testFile, []byte(source), 0644) 48 require.NoError(t, err) 49 50 actual := RunLinter(t, linter, dir, extraFlags...) 51 assert.Equal(t, expected, actual) 52 } 53 54 // RunLinter runs the gometalinter as a binary against the files at path and 55 // returns the issues it encountered 56 func RunLinter(t *testing.T, linter string, path string, extraFlags ...string) Issues { 57 binary, cleanup := buildBinary(t) 58 defer cleanup() 59 60 args := []string{ 61 "-d", "--no-config", "--disable-all", "--enable", linter, "--json", 62 "--sort=path", "--sort=line", "--sort=column", "--sort=message", 63 "./...", 64 } 65 args = append(args, extraFlags...) 66 cmd := exec.Command(binary, args...) 67 cmd.Dir = path 68 69 errBuffer := new(bytes.Buffer) 70 cmd.Stderr = errBuffer 71 72 output, _ := cmd.Output() 73 74 var actual Issues 75 err := json.Unmarshal(output, &actual) 76 if !assert.NoError(t, err) { 77 fmt.Printf("Stderr: %s\n", errBuffer) 78 fmt.Printf("Output: %s\n", output) 79 return nil 80 } 81 return filterIssues(actual, linter, path) 82 } 83 84 func buildBinary(t *testing.T) (string, func()) { 85 tmpdir := fs.NewDir(t, "regression-test-binary") 86 path := tmpdir.Join("gometalinter") 87 cmd := exec.Command("go", "build", "-o", path, "..") 88 require.NoError(t, cmd.Run()) 89 return path, tmpdir.Remove 90 } 91 92 // filterIssues to just the issues relevant for the current linter and normalize 93 // the error message by removing the directory part of the path from both Path 94 // and Message 95 func filterIssues(issues Issues, linterName string, dir string) Issues { 96 filtered := Issues{} 97 for _, issue := range issues { 98 if issue.Linter == linterName || linterName == "" { 99 issue.Path = strings.Replace(issue.Path, dir+string(os.PathSeparator), "", -1) 100 issue.Message = strings.Replace(issue.Message, dir+string(os.PathSeparator), "", -1) 101 issue.Message = strings.Replace(issue.Message, dir, "", -1) 102 filtered = append(filtered, issue) 103 } 104 } 105 return filtered 106 }