mirror of
https://github.com/scratchfoundation/golangci-lint.git
synced 2025-08-02 01:20:52 -04:00
ed64e33c8c8bc9a919e2b85a1a08225b5ae59d70. Also add tests for local mode of goimports and do refactoring of tests.
This commit is contained in:
parent
7836034ecf
commit
ac77eaac68
47 changed files with 582 additions and 12171 deletions
test
|
@ -1,17 +1,21 @@
|
|||
package test
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/golangci/golangci-lint/test/testshared"
|
||||
|
||||
assert "github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/golangci/golangci-lint/pkg/exitcodes"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
func runGoErrchk(c *exec.Cmd, t *testing.T) {
|
||||
|
@ -22,16 +26,18 @@ func runGoErrchk(c *exec.Cmd, t *testing.T) {
|
|||
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)
|
||||
findSources := func(pathPatterns ...string) []string {
|
||||
sources, err := filepath.Glob(filepath.Join(pathPatterns...))
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, sources)
|
||||
return sources
|
||||
}
|
||||
sources := findSources(dir, "*.go")
|
||||
|
||||
testshared.NewLintRunner(t).Install()
|
||||
|
||||
for _, s := range sources {
|
||||
s := s
|
||||
|
@ -50,23 +56,71 @@ func TestTypecheck(t *testing.T) {
|
|||
testSourcesFromDir(t, filepath.Join(testdataDir, "notcompiles"))
|
||||
}
|
||||
|
||||
func TestGoimportsLocal(t *testing.T) {
|
||||
t.Skipf("strange travis and go bug, enable it when it will be fixed: https://travis-ci.com/golangci/golangci-lint/jobs/157695743")
|
||||
|
||||
sourcePath := filepath.Join(testdataDir, "goimports", "goimports.go")
|
||||
args := []string{
|
||||
"--disable-all", "--print-issued-lines=false", "--print-linter-name=false", "--out-format=line-number",
|
||||
sourcePath,
|
||||
}
|
||||
rc := extractRunContextFromComments(t, sourcePath)
|
||||
args = append(args, rc.args...)
|
||||
|
||||
cfg, err := yaml.Marshal(rc.config)
|
||||
assert.NoError(t, err)
|
||||
|
||||
testshared.NewLintRunner(t).RunWithYamlConfig(string(cfg), args...).
|
||||
ExpectHasIssue("testdata/goimports/goimports.go:8: File is not `goimports`-ed")
|
||||
}
|
||||
|
||||
func saveConfig(t *testing.T, cfg map[string]interface{}) (cfgPath string, finishFunc func()) {
|
||||
f, err := ioutil.TempFile("", "golangci_lint_test")
|
||||
assert.NoError(t, err)
|
||||
|
||||
cfgPath = f.Name() + ".yml"
|
||||
err = os.Rename(f.Name(), cfgPath)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = yaml.NewEncoder(f).Encode(cfg)
|
||||
assert.NoError(t, err)
|
||||
|
||||
return cfgPath, func() {
|
||||
assert.NoError(t, f.Close())
|
||||
assert.NoError(t, os.Remove(cfgPath))
|
||||
}
|
||||
}
|
||||
|
||||
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",
|
||||
}
|
||||
|
||||
rc := extractRunContextFromComments(t, sourcePath)
|
||||
var cfgPath string
|
||||
|
||||
if rc.config != nil {
|
||||
p, finish := saveConfig(t, rc.config)
|
||||
defer finish()
|
||||
cfgPath = p
|
||||
}
|
||||
|
||||
for _, addArg := range []string{"", "-Etypecheck"} {
|
||||
caseArgs := append([]string{}, args...)
|
||||
caseArgs = append(caseArgs, getAdditionalArgs(t, sourcePath)...)
|
||||
caseArgs = append(caseArgs, rc.args...)
|
||||
if addArg != "" {
|
||||
caseArgs = append(caseArgs, addArg)
|
||||
}
|
||||
if cfgPath == "" {
|
||||
caseArgs = append(caseArgs, "--no-config")
|
||||
} else {
|
||||
caseArgs = append(caseArgs, "-c", cfgPath)
|
||||
}
|
||||
|
||||
caseArgs = append(caseArgs, sourcePath)
|
||||
|
||||
|
@ -76,30 +130,81 @@ func testOneSource(t *testing.T, sourcePath string) {
|
|||
}
|
||||
}
|
||||
|
||||
func getAdditionalArgs(t *testing.T, sourcePath string) []string {
|
||||
data, err := ioutil.ReadFile(sourcePath)
|
||||
assert.NoError(t, err)
|
||||
type runContext struct {
|
||||
args []string
|
||||
config map[string]interface{}
|
||||
}
|
||||
|
||||
lines := strings.SplitN(string(data), "\n", 2)
|
||||
firstLine := lines[0]
|
||||
func buildConfigFromShortRepr(t *testing.T, repr string, config map[string]interface{}) {
|
||||
kv := strings.Split(repr, "=")
|
||||
assert.Len(t, kv, 2)
|
||||
|
||||
parts := strings.Split(firstLine, "args:")
|
||||
if len(parts) == 1 {
|
||||
return nil
|
||||
keyParts := strings.Split(kv[0], ".")
|
||||
assert.True(t, len(keyParts) >= 2, len(keyParts))
|
||||
|
||||
lastObj := config
|
||||
for _, k := range keyParts[:len(keyParts)-1] {
|
||||
var v map[string]interface{}
|
||||
if lastObj[k] == nil {
|
||||
v = map[string]interface{}{}
|
||||
} else {
|
||||
v = lastObj[k].(map[string]interface{})
|
||||
}
|
||||
|
||||
lastObj[k] = v
|
||||
lastObj = v
|
||||
}
|
||||
|
||||
return strings.Split(parts[len(parts)-1], " ")
|
||||
lastObj[keyParts[len(keyParts)-1]] = kv[1]
|
||||
}
|
||||
|
||||
func extractRunContextFromComments(t *testing.T, sourcePath string) *runContext {
|
||||
f, err := os.Open(sourcePath)
|
||||
assert.NoError(t, err)
|
||||
defer f.Close()
|
||||
|
||||
rc := &runContext{}
|
||||
|
||||
scanner := bufio.NewScanner(f)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if !strings.HasPrefix(line, "//") {
|
||||
return rc
|
||||
}
|
||||
|
||||
line = strings.TrimPrefix(line, "//")
|
||||
if strings.HasPrefix(line, "args: ") {
|
||||
assert.Nil(t, rc.args)
|
||||
args := strings.TrimPrefix(line, "args: ")
|
||||
assert.NotEmpty(t, args)
|
||||
rc.args = strings.Split(args, " ")
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasPrefix(line, "config: ") {
|
||||
repr := strings.TrimPrefix(line, "config: ")
|
||||
assert.NotEmpty(t, repr)
|
||||
if rc.config == nil {
|
||||
rc.config = map[string]interface{}{}
|
||||
}
|
||||
buildConfigFromShortRepr(t, repr, rc.config)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return rc
|
||||
}
|
||||
|
||||
func TestExtractRunContextFromComments(t *testing.T) {
|
||||
rc := extractRunContextFromComments(t, filepath.Join(testdataDir, "goimports", "goimports.go"))
|
||||
assert.Equal(t, []string{"-Egoimports"}, rc.args)
|
||||
}
|
||||
|
||||
func TestGolintConsumesXTestFiles(t *testing.T) {
|
||||
dir := filepath.Join(testdataDir, "withxtest")
|
||||
dir := getTestDataDir("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, out)
|
||||
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, out)
|
||||
assert.Contains(t, out, expIssue)
|
||||
r := testshared.NewLintRunner(t)
|
||||
r.Run("--no-config", "--disable-all", "-Egolint", dir).ExpectHasIssue(expIssue)
|
||||
r.Run("--no-config", "--disable-all", "-Egolint", filepath.Join(dir, "p_test.go")).ExpectHasIssue(expIssue)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue