github.com/chenfeining/golangci-lint@v1.0.2-0.20230730162517-14c6c67868df/test/linters_test.go (about) 1 package test 2 3 import ( 4 "os" 5 "os/exec" 6 "path/filepath" 7 "strings" 8 "testing" 9 "time" 10 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 14 "github.com/chenfeining/golangci-lint/pkg/logutils" 15 "github.com/chenfeining/golangci-lint/test/testshared" 16 ) 17 18 const testdataDir = "testdata" 19 20 func TestSourcesFromTestdata(t *testing.T) { 21 testSourcesFromDir(t, testdataDir) 22 } 23 24 func TestTypecheck(t *testing.T) { 25 testshared.SkipOnWindows(t) 26 27 testSourcesFromDir(t, filepath.Join(testdataDir, "notcompiles")) 28 } 29 30 func TestSourcesFromTestdataSubDir(t *testing.T) { 31 subDirs := []string{ 32 "loggercheck", 33 "ginkgolinter", 34 "zerologlint", 35 "npecheck", 36 } 37 38 for _, dir := range subDirs { 39 t.Run(dir, func(t *testing.T) { 40 testSourcesFromDir(t, filepath.Join(testdataDir, dir)) 41 }) 42 } 43 } 44 45 func testSourcesFromDir(t *testing.T, dir string) { 46 t.Helper() 47 48 t.Log(filepath.Join(dir, "*.go")) 49 50 sources := findSources(t, dir, "*.go") 51 52 binPath := testshared.InstallGolangciLint(t) 53 54 cwd, err := os.Getwd() 55 require.NoError(t, err) 56 t.Cleanup(func() { _ = os.Chdir(cwd) }) 57 58 err = os.Chdir(dir) 59 require.NoError(t, err) 60 61 log := logutils.NewStderrLog(logutils.DebugKeyTest) 62 log.SetLevel(logutils.LogLevelInfo) 63 64 for _, source := range sources { 65 source := source 66 t.Run(filepath.Base(source), func(subTest *testing.T) { 67 subTest.Parallel() 68 69 rel, err := filepath.Rel(dir, source) 70 require.NoError(t, err) 71 72 testOneSource(subTest, log, binPath, rel) 73 }) 74 } 75 } 76 77 func testOneSource(t *testing.T, log *logutils.StderrLog, binPath, sourcePath string) { 78 t.Helper() 79 80 rc := testshared.ParseTestDirectives(t, sourcePath) 81 if rc == nil { 82 t.Skipf("Skipped: %s", sourcePath) 83 } 84 85 args := []string{ 86 "--allow-parallel-runners", 87 "--disable-all", 88 "--out-format=json", 89 "--max-same-issues=100", 90 } 91 92 for _, addArg := range []string{"", "-Etypecheck"} { 93 caseArgs := append([]string{}, args...) 94 95 if addArg != "" { 96 caseArgs = append(caseArgs, addArg) 97 } 98 99 cmd := testshared.NewRunnerBuilder(t). 100 WithBinPath(binPath). 101 WithNoParallelRunners(). 102 WithArgs(caseArgs...). 103 WithRunContext(rc). 104 WithTargetPath(sourcePath). 105 Runner(). 106 Command() 107 108 startedAt := time.Now() 109 110 output, err := cmd.CombinedOutput() 111 112 log.Infof("ran [%s] in %s", strings.Join(cmd.Args, " "), time.Since(startedAt)) 113 114 // The returned error will be nil if the test file does not have any issues 115 // and thus the linter exits with exit code 0. 116 // So perform the additional assertions only if the error is non-nil. 117 if err != nil { 118 var exitErr *exec.ExitError 119 require.ErrorAs(t, err, &exitErr) 120 } 121 122 assert.Equal(t, rc.ExitCode, cmd.ProcessState.ExitCode(), "Unexpected exit code: %s", string(output)) 123 124 testshared.Analyze(t, sourcePath, output) 125 } 126 } 127 128 func findSources(t *testing.T, pathPatterns ...string) []string { 129 t.Helper() 130 131 sources, err := filepath.Glob(filepath.Join(pathPatterns...)) 132 require.NoError(t, err) 133 require.NotEmpty(t, sources) 134 135 return sources 136 }