package test import ( "bytes" "io/ioutil" "os/exec" "path/filepath" "runtime" "strings" "testing" "github.com/golangci/golangci-lint/pkg/exitcodes" "github.com/stretchr/testify/assert" ) func runGoErrchk(c *exec.Cmd, t *testing.T) { output, err := c.CombinedOutput() assert.NoError(t, err, "Output:\n%s", output) // Can't check exit code: tool only prints to output assert.False(t, bytes.Contains(output, []byte("BUG")), "Output:\n%s", output) } const testdataDir = "testdata" const binName = "golangci-lint" func testSourcesFromDir(t *testing.T, dir string) { t.Log(filepath.Join(dir, "*.go")) sources, err := filepath.Glob(filepath.Join(dir, "*.go")) assert.NoError(t, err) assert.NotEmpty(t, sources) installBinary(t) for _, s := range sources { s := s t.Run(filepath.Base(s), func(t *testing.T) { t.Parallel() testOneSource(t, s) }) } } func TestSourcesFromTestdataWithIssuesDir(t *testing.T) { testSourcesFromDir(t, testdataDir) } func TestTypecheck(t *testing.T) { testSourcesFromDir(t, filepath.Join(testdataDir, "notcompiles")) } func testOneSource(t *testing.T, sourcePath string) { goErrchkBin := filepath.Join(runtime.GOROOT(), "test", "errchk") args := []string{ binName, "run", "--no-config", "--disable-all", "--print-issued-lines=false", "--print-linter-name=false", "--out-format=line-number", } for _, addArg := range []string{"", "-Etypecheck"} { caseArgs := append([]string{}, args...) caseArgs = append(caseArgs, getAdditionalArgs(t, sourcePath)...) if addArg != "" { caseArgs = append(caseArgs, addArg) } caseArgs = append(caseArgs, sourcePath) cmd := exec.Command(goErrchkBin, caseArgs...) t.Log(caseArgs) runGoErrchk(cmd, t) } } func getAdditionalArgs(t *testing.T, sourcePath string) []string { data, err := ioutil.ReadFile(sourcePath) assert.NoError(t, err) lines := strings.SplitN(string(data), "\n", 2) firstLine := lines[0] parts := strings.Split(firstLine, "args:") if len(parts) == 1 { return nil } return strings.Split(parts[len(parts)-1], " ") } func TestGolintConsumesXTestFiles(t *testing.T) { dir := filepath.Join(testdataDir, "withxtest") const expIssue = "if block ends with a return statement, so drop this else and outdent its block" out, ec := runGolangciLint(t, "--no-config", "--disable-all", "-Egolint", dir) assert.Equal(t, exitcodes.IssuesFound, ec) assert.Contains(t, out, expIssue) out, ec = runGolangciLint(t, "--no-config", "--disable-all", "-Egolint", filepath.Join(dir, "p_test.go")) assert.Equal(t, exitcodes.IssuesFound, ec) assert.Contains(t, out, expIssue) }