Skip to content

Commit 13c4726

Browse files
authored
dev: support build tags about go version in linter tests (#2744)
1 parent a2e6c76 commit 13c4726

File tree

3 files changed

+89
-8
lines changed

3 files changed

+89
-8
lines changed

test/fix_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ func TestFix(t *testing.T) {
4949
input,
5050
}
5151
rc := extractRunContextFromComments(t, input)
52+
if rc == nil {
53+
t.Logf("Skipped: %s", input)
54+
return
55+
}
56+
5257
args = append(args, rc.args...)
5358

5459
cfg, err := yaml.Marshal(rc.config)

test/linters_test.go

+65-8
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ package test
33
import (
44
"bufio"
55
"fmt"
6+
"go/build/constraint"
67
"os"
78
"os/exec"
89
"path"
910
"path/filepath"
11+
"runtime"
1012
"strings"
1113
"testing"
1214

15+
hcversion "github.com/hashicorp/go-version"
1316
"github.com/stretchr/testify/require"
1417
"gopkg.in/yaml.v3"
1518

@@ -73,7 +76,10 @@ func TestGoimportsLocal(t *testing.T) {
7376
"--disable-all", "--print-issued-lines=false", "--print-linter-name=false", "--out-format=line-number",
7477
sourcePath,
7578
}
79+
7680
rc := extractRunContextFromComments(t, sourcePath)
81+
require.NotNil(t, rc)
82+
7783
args = append(args, rc.args...)
7884

7985
cfg, err := yaml.Marshal(rc.config)
@@ -89,7 +95,10 @@ func TestGciLocal(t *testing.T) {
8995
"--disable-all", "--print-issued-lines=false", "--print-linter-name=false", "--out-format=line-number",
9096
sourcePath,
9197
}
98+
9299
rc := extractRunContextFromComments(t, sourcePath)
100+
require.NotNil(t, rc)
101+
93102
args = append(args, rc.args...)
94103

95104
cfg, err := os.ReadFile(rc.configPath)
@@ -105,7 +114,10 @@ func TestMultipleOutputs(t *testing.T) {
105114
"--disable-all", "--print-issued-lines=false", "--print-linter-name=false", "--out-format=line-number,json:stdout",
106115
sourcePath,
107116
}
117+
108118
rc := extractRunContextFromComments(t, sourcePath)
119+
require.NotNil(t, rc)
120+
109121
args = append(args, rc.args...)
110122

111123
cfg, err := os.ReadFile(rc.configPath)
@@ -122,7 +134,10 @@ func TestStderrOutput(t *testing.T) {
122134
"--disable-all", "--print-issued-lines=false", "--print-linter-name=false", "--out-format=line-number,json:stderr",
123135
sourcePath,
124136
}
137+
125138
rc := extractRunContextFromComments(t, sourcePath)
139+
require.NotNil(t, rc)
140+
126141
args = append(args, rc.args...)
127142

128143
cfg, err := os.ReadFile(rc.configPath)
@@ -142,7 +157,10 @@ func TestFileOutput(t *testing.T) {
142157
fmt.Sprintf("--out-format=json:%s,line-number", resultPath),
143158
sourcePath,
144159
}
160+
145161
rc := extractRunContextFromComments(t, sourcePath)
162+
require.NotNil(t, rc)
163+
146164
args = append(args, rc.args...)
147165

148166
cfg, err := os.ReadFile(rc.configPath)
@@ -188,8 +206,11 @@ func testOneSource(t *testing.T, sourcePath string) {
188206
}
189207

190208
rc := extractRunContextFromComments(t, sourcePath)
191-
var cfgPath string
209+
if rc == nil {
210+
t.Skipf("Skipped: %s", sourcePath)
211+
}
192212

213+
var cfgPath string
193214
if rc.config != nil {
194215
p, finish := saveConfig(t, rc.config)
195216
defer finish()
@@ -254,6 +275,7 @@ func skipMultilineComment(scanner *bufio.Scanner) {
254275
}
255276
}
256277

278+
//nolint:gocyclo,funlen
257279
func extractRunContextFromComments(t *testing.T, sourcePath string) *runContext {
258280
f, err := os.Open(sourcePath)
259281
require.NoError(t, err)
@@ -275,6 +297,17 @@ func extractRunContextFromComments(t *testing.T, sourcePath string) *runContext
275297
break
276298
}
277299

300+
if strings.HasPrefix(line, "//go:build") || strings.HasPrefix(line, "// +build") {
301+
parse, err := constraint.Parse(line)
302+
require.NoError(t, err)
303+
304+
if !parse.Eval(buildTagGoVersion) {
305+
return nil
306+
}
307+
308+
continue
309+
}
310+
278311
line = strings.TrimLeft(strings.TrimPrefix(line, "//"), " ")
279312
if strings.HasPrefix(line, "args: ") {
280313
require.Nil(t, rc.args)
@@ -315,10 +348,7 @@ func extractRunContextFromComments(t *testing.T, sourcePath string) *runContext
315348
if rc.expectedLinter == "" {
316349
for _, arg := range rc.args {
317350
if strings.HasPrefix(arg, "-E") && !strings.Contains(arg, ",") {
318-
if rc.expectedLinter != "" {
319-
require.Fail(t, "could not infer expected linter for errors because multiple linters are enabled. Please use the `expected_linter: ` directive in your test to indicate the linter-under-test.") //nolint:lll
320-
break
321-
}
351+
require.Empty(t, rc.expectedLinter, "could not infer expected linter for errors because multiple linters are enabled. Please use the `expected_linter: ` directive in your test to indicate the linter-under-test.") //nolint:lll
322352
rc.expectedLinter = arg[2:]
323353
}
324354
}
@@ -327,19 +357,38 @@ func extractRunContextFromComments(t *testing.T, sourcePath string) *runContext
327357
return rc
328358
}
329359

360+
func buildTagGoVersion(tag string) bool {
361+
vRuntime, err := hcversion.NewVersion(strings.TrimPrefix(runtime.Version(), "go"))
362+
if err != nil {
363+
return false
364+
}
365+
366+
vTag, err := hcversion.NewVersion(strings.TrimPrefix(tag, "go"))
367+
if err != nil {
368+
return false
369+
}
370+
371+
return vRuntime.GreaterThanOrEqual(vTag)
372+
}
373+
330374
func TestExtractRunContextFromComments(t *testing.T) {
331375
rc := extractRunContextFromComments(t, filepath.Join(testdataDir, "goimports", "goimports.go"))
376+
require.NotNil(t, rc)
332377
require.Equal(t, []string{"-Egoimports"}, rc.args)
333378
}
334379

335380
func TestTparallel(t *testing.T) {
336381
t.Run("should fail on missing top-level Parallel()", func(t *testing.T) {
337382
sourcePath := filepath.Join(testdataDir, "tparallel", "missing_toplevel_test.go")
338383
args := []string{
339-
"--disable-all", "--print-issued-lines=false", "--print-linter-name=false", "--out-format=line-number", "--enable", "tparallel",
384+
"--disable-all", "--enable", "tparallel",
385+
"--print-issued-lines=false", "--print-linter-name=false", "--out-format=line-number",
340386
sourcePath,
341387
}
388+
342389
rc := extractRunContextFromComments(t, sourcePath)
390+
require.NotNil(t, rc)
391+
343392
args = append(args, rc.args...)
344393

345394
cfg, err := yaml.Marshal(rc.config)
@@ -354,10 +403,14 @@ func TestTparallel(t *testing.T) {
354403
t.Run("should fail on missing subtest Parallel()", func(t *testing.T) {
355404
sourcePath := filepath.Join(testdataDir, "tparallel", "missing_subtest_test.go")
356405
args := []string{
357-
"--disable-all", "--print-issued-lines=false", "--print-linter-name=false", "--out-format=line-number", "--enable", "tparallel",
406+
"--disable-all", "--enable", "tparallel",
407+
"--print-issued-lines=false", "--print-linter-name=false", "--out-format=line-number",
358408
sourcePath,
359409
}
410+
360411
rc := extractRunContextFromComments(t, sourcePath)
412+
require.NotNil(t, rc)
413+
361414
args = append(args, rc.args...)
362415

363416
cfg, err := yaml.Marshal(rc.config)
@@ -372,10 +425,14 @@ func TestTparallel(t *testing.T) {
372425
t.Run("should pass on parallel test with no subtests", func(t *testing.T) {
373426
sourcePath := filepath.Join(testdataDir, "tparallel", "happy_path_test.go")
374427
args := []string{
375-
"--disable-all", "--print-issued-lines=false", "--print-linter-name=false", "--out-format=line-number", "--enable", "tparallel",
428+
"--disable-all", "--enable", "tparallel",
429+
"--print-issued-lines=false", "--print-linter-name=false", "--out-format=line-number",
376430
sourcePath,
377431
}
432+
378433
rc := extractRunContextFromComments(t, sourcePath)
434+
require.NotNil(t, rc)
435+
379436
args = append(args, rc.args...)
380437

381438
cfg, err := yaml.Marshal(rc.config)

test/testdata/tenv_go118.go

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//go:build go1.18
2+
// +build go1.18
3+
4+
// args: -Etenv
5+
package testdata
6+
7+
import (
8+
"os"
9+
"testing"
10+
)
11+
12+
func FuzzF(f *testing.F) {
13+
os.Setenv("a", "b") // ERROR "os\\.Setenv\\(\\) can be replaced by `f\\.Setenv\\(\\)` in FuzzF"
14+
err := os.Setenv("a", "b") // ERROR "os\\.Setenv\\(\\) can be replaced by `f\\.Setenv\\(\\)` in FuzzF"
15+
_ = err
16+
if err := os.Setenv("a", "b"); err != nil { // ERROR "os\\.Setenv\\(\\) can be replaced by `f\\.Setenv\\(\\)` in FuzzF"
17+
_ = err
18+
}
19+
}

0 commit comments

Comments
 (0)