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  }