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