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  }