github.com/thrasher-corp/golangci-lint@v1.17.3/test/run_test.go (about) 1 package test 2 3 import ( 4 "path/filepath" 5 "strings" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 10 "github.com/golangci/golangci-lint/test/testshared" 11 12 "github.com/golangci/golangci-lint/pkg/exitcodes" 13 14 _ "github.com/valyala/quicktemplate" 15 ) 16 17 func getCommonRunArgs() []string { 18 return []string{"--skip-dirs", "testdata_etc/,pkg/golinters/goanalysis/(checker|passes)"} 19 } 20 21 func withCommonRunArgs(args ...string) []string { 22 return append(getCommonRunArgs(), args...) 23 } 24 25 func TestAutogeneratedNoIssues(t *testing.T) { 26 testshared.NewLintRunner(t).Run(getTestDataDir("autogenerated")).ExpectNoIssues() 27 } 28 29 func TestEmptyDirRun(t *testing.T) { 30 testshared.NewLintRunner(t, "GO111MODULE=off").Run(getTestDataDir("nogofiles")). 31 ExpectExitCode(exitcodes.NoGoFiles). 32 ExpectOutputContains(": no go files to analyze") 33 } 34 35 func TestNotExistingDirRun(t *testing.T) { 36 testshared.NewLintRunner(t, "GO111MODULE=off").Run(getTestDataDir("no_such_dir")). 37 ExpectExitCode(exitcodes.Failure). 38 ExpectOutputContains(`cannot find package \"./testdata/no_such_dir\"`) 39 } 40 41 func TestSymlinkLoop(t *testing.T) { 42 testshared.NewLintRunner(t).Run(getTestDataDir("symlink_loop", "...")).ExpectNoIssues() 43 } 44 45 func TestDeadline(t *testing.T) { 46 testshared.NewLintRunner(t).Run("--deadline=1ms", getProjectRoot()). 47 ExpectExitCode(exitcodes.Timeout). 48 ExpectOutputContains(`Deadline exceeded: try increase it by passing --deadline option`) 49 } 50 51 func TestTestsAreLintedByDefault(t *testing.T) { 52 testshared.NewLintRunner(t).Run(getTestDataDir("withtests")). 53 ExpectHasIssue("`if` block ends with a `return`") 54 } 55 56 func TestCgoOk(t *testing.T) { 57 testshared.NewLintRunner(t).Run("--enable-all", getTestDataDir("cgo")).ExpectNoIssues() 58 } 59 60 func TestCgoWithIssues(t *testing.T) { 61 testshared.NewLintRunner(t).Run("--enable-all", getTestDataDir("cgo_with_issues")). 62 ExpectHasIssue("Printf format %t has arg cs of wrong type") 63 } 64 65 func TestUnsafeOk(t *testing.T) { 66 testshared.NewLintRunner(t).Run("--enable-all", getTestDataDir("unsafe")).ExpectNoIssues() 67 } 68 69 func TestGovetCustomFormatter(t *testing.T) { 70 testshared.NewLintRunner(t).Run(getTestDataDir("govet_custom_formatter")).ExpectNoIssues() 71 } 72 73 func TestLineDirectiveProcessedFilesLiteLoading(t *testing.T) { 74 r := testshared.NewLintRunner(t).Run("--print-issued-lines=false", "--no-config", 75 "--exclude-use-default=false", "-Egolint", getTestDataDir("quicktemplate")) 76 77 output := strings.Join([]string{ 78 "testdata/quicktemplate/hello.qtpl.go:26:1: exported function `StreamHello` should have comment or be unexported (golint)", 79 "testdata/quicktemplate/hello.qtpl.go:50:1: exported function `Hello` should have comment or be unexported (golint)", 80 "testdata/quicktemplate/hello.qtpl.go:39:1: exported function `WriteHello` should have comment or be unexported (golint)", 81 }, "\n") 82 r.ExpectExitCode(exitcodes.IssuesFound).ExpectOutputEq(output + "\n") 83 } 84 85 func TestLineDirectiveProcessedFilesFullLoading(t *testing.T) { 86 r := testshared.NewLintRunner(t).Run("--print-issued-lines=false", "--no-config", 87 "--exclude-use-default=false", "-Egolint,govet", getTestDataDir("quicktemplate")) 88 89 output := strings.Join([]string{ 90 "testdata/quicktemplate/hello.qtpl.go:26:1: exported function `StreamHello` should have comment or be unexported (golint)", 91 "testdata/quicktemplate/hello.qtpl.go:50:1: exported function `Hello` should have comment or be unexported (golint)", 92 "testdata/quicktemplate/hello.qtpl.go:39:1: exported function `WriteHello` should have comment or be unexported (golint)", 93 }, "\n") 94 r.ExpectExitCode(exitcodes.IssuesFound).ExpectOutputEq(output + "\n") 95 } 96 97 func TestSkippedDirsNoMatchArg(t *testing.T) { 98 dir := getTestDataDir("skipdirs", "skip_me", "nested") 99 r := testshared.NewLintRunner(t).Run("--print-issued-lines=false", "--no-config", "--skip-dirs", dir, "-Egolint", dir) 100 101 r.ExpectExitCode(exitcodes.IssuesFound). 102 ExpectOutputEq("testdata/skipdirs/skip_me/nested/with_issue.go:8:9: `if` block ends with " + 103 "a `return` statement, so drop this `else` and outdent its block (golint)\n") 104 } 105 106 func TestSkippedDirsTestdata(t *testing.T) { 107 r := testshared.NewLintRunner(t).Run("--print-issued-lines=false", "--no-config", "-Egolint", getTestDataDir("skipdirs", "...")) 108 109 r.ExpectNoIssues() // all was skipped because in testdata 110 } 111 112 func TestDeadcodeNoFalsePositivesInMainPkg(t *testing.T) { 113 testshared.NewLintRunner(t).Run("--no-config", "--disable-all", "-Edeadcode", getTestDataDir("deadcode_main_pkg")).ExpectNoIssues() 114 } 115 116 func TestIdentifierUsedOnlyInTests(t *testing.T) { 117 testshared.NewLintRunner(t).Run("--no-config", "--disable-all", "-Eunused", getTestDataDir("used_only_in_tests")).ExpectNoIssues() 118 } 119 120 func TestConfigFileIsDetected(t *testing.T) { 121 checkGotConfig := func(r *testshared.RunResult) { 122 r.ExpectExitCode(exitcodes.Success). 123 ExpectOutputEq("test\n") // test config contains InternalTest: true, it triggers such output 124 } 125 126 r := testshared.NewLintRunner(t) 127 checkGotConfig(r.Run(getTestDataDir("withconfig", "pkg"))) 128 checkGotConfig(r.Run(getTestDataDir("withconfig", "..."))) 129 } 130 131 func TestEnableAllFastAndEnableCanCoexist(t *testing.T) { 132 r := testshared.NewLintRunner(t) 133 r.Run(withCommonRunArgs("--fast", "--enable-all", "--enable=typecheck")...).ExpectNoIssues() 134 r.Run(withCommonRunArgs("--enable-all", "--enable=typecheck")...).ExpectExitCode(exitcodes.Failure) 135 } 136 137 func TestEnabledPresetsAreNotDuplicated(t *testing.T) { 138 testshared.NewLintRunner(t).Run("--no-config", "-v", "-p", "style,bugs"). 139 ExpectOutputContains("Active presets: [bugs style]") 140 } 141 142 func TestAbsPathDirAnalysis(t *testing.T) { 143 dir := filepath.Join("testdata_etc", "abspath") // abs paths don't work with testdata dir 144 absDir, err := filepath.Abs(dir) 145 assert.NoError(t, err) 146 147 r := testshared.NewLintRunner(t).Run("--print-issued-lines=false", "--no-config", "-Egolint", absDir) 148 r.ExpectHasIssue("`if` block ends with a `return` statement") 149 } 150 151 func TestAbsPathFileAnalysis(t *testing.T) { 152 dir := filepath.Join("testdata_etc", "abspath", "with_issue.go") // abs paths don't work with testdata dir 153 absDir, err := filepath.Abs(dir) 154 assert.NoError(t, err) 155 156 r := testshared.NewLintRunner(t).Run("--print-issued-lines=false", "--no-config", "-Egolint", absDir) 157 r.ExpectHasIssue("`if` block ends with a `return` statement") 158 } 159 160 func TestDisallowedOptionsInConfig(t *testing.T) { 161 type tc struct { 162 cfg string 163 option string 164 } 165 166 cases := []tc{ 167 { 168 cfg: ` 169 ruN: 170 Args: 171 - 1 172 `, 173 }, 174 { 175 cfg: ` 176 run: 177 CPUProfilePath: path 178 `, 179 option: "--cpu-profile-path=path", 180 }, 181 { 182 cfg: ` 183 run: 184 MemProfilePath: path 185 `, 186 option: "--mem-profile-path=path", 187 }, 188 { 189 cfg: ` 190 run: 191 Verbose: true 192 `, 193 option: "-v", 194 }, 195 } 196 197 r := testshared.NewLintRunner(t) 198 for _, c := range cases { 199 // Run with disallowed option set only in config 200 r.RunWithYamlConfig(c.cfg, getCommonRunArgs()...).ExpectExitCode(exitcodes.Failure) 201 202 if c.option == "" { 203 continue 204 } 205 206 args := []string{c.option, "--fast"} 207 208 // Run with disallowed option set only in command-line 209 r.Run(withCommonRunArgs(args...)...).ExpectExitCode(exitcodes.Success) 210 211 // Run with disallowed option set both in command-line and in config 212 r.RunWithYamlConfig(c.cfg, withCommonRunArgs(args...)...).ExpectExitCode(exitcodes.Failure) 213 } 214 }