github.com/vanstinator/golangci-lint@v0.0.0-20240223191551-cc572f00d9d1/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/vanstinator/golangci-lint/pkg/logutils" 15 "github.com/vanstinator/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 "protogetter", 36 "spancheck", 37 } 38 39 for _, dir := range subDirs { 40 t.Run(dir, func(t *testing.T) { 41 testSourcesFromDir(t, filepath.Join(testdataDir, dir)) 42 }) 43 } 44 } 45 46 func testSourcesFromDir(t *testing.T, dir string) { 47 t.Helper() 48 49 t.Log(filepath.Join(dir, "*.go")) 50 51 sources := findSources(t, dir, "*.go") 52 53 binPath := testshared.InstallGolangciLint(t) 54 55 cwd, err := os.Getwd() 56 require.NoError(t, err) 57 t.Cleanup(func() { _ = os.Chdir(cwd) }) 58 59 err = os.Chdir(dir) 60 require.NoError(t, err) 61 62 log := logutils.NewStderrLog(logutils.DebugKeyTest) 63 log.SetLevel(logutils.LogLevelInfo) 64 65 for _, source := range sources { 66 source := source 67 t.Run(filepath.Base(source), func(subTest *testing.T) { 68 subTest.Parallel() 69 70 rel, err := filepath.Rel(dir, source) 71 require.NoError(t, err) 72 73 testOneSource(subTest, log, binPath, rel) 74 }) 75 } 76 } 77 78 func testOneSource(t *testing.T, log *logutils.StderrLog, binPath, sourcePath string) { 79 t.Helper() 80 81 rc := testshared.ParseTestDirectives(t, sourcePath) 82 if rc == nil { 83 t.Skipf("Skipped: %s", sourcePath) 84 } 85 86 args := []string{ 87 "--allow-parallel-runners", 88 "--disable-all", 89 "--out-format=json", 90 "--max-same-issues=100", 91 } 92 93 for _, addArg := range []string{"", "-Etypecheck"} { 94 caseArgs := append([]string{}, args...) 95 96 if addArg != "" { 97 caseArgs = append(caseArgs, addArg) 98 } 99 100 cmd := testshared.NewRunnerBuilder(t). 101 WithBinPath(binPath). 102 WithNoParallelRunners(). 103 WithArgs(caseArgs...). 104 WithRunContext(rc). 105 WithTargetPath(sourcePath). 106 Runner(). 107 Command() 108 109 startedAt := time.Now() 110 111 output, err := cmd.CombinedOutput() 112 113 log.Infof("ran [%s] in %s", strings.Join(cmd.Args, " "), time.Since(startedAt)) 114 115 // The returned error will be nil if the test file does not have any issues 116 // and thus the linter exits with exit code 0. 117 // So perform the additional assertions only if the error is non-nil. 118 if err != nil { 119 var exitErr *exec.ExitError 120 require.ErrorAs(t, err, &exitErr) 121 } 122 123 assert.Equal(t, rc.ExitCode, cmd.ProcessState.ExitCode(), "Unexpected exit code: %s", string(output)) 124 125 testshared.Analyze(t, sourcePath, output) 126 } 127 } 128 129 func findSources(t *testing.T, pathPatterns ...string) []string { 130 t.Helper() 131 132 sources, err := filepath.Glob(filepath.Join(pathPatterns...)) 133 require.NoError(t, err) 134 require.NotEmpty(t, sources) 135 136 return sources 137 }