From ec46f42e0182e6dcf6d2ba31a5b63078f9088b02 Mon Sep 17 00:00:00 2001 From: Andrew Shannon Brown Date: Fri, 15 Jan 2021 12:37:56 -0800 Subject: [PATCH] Verify linter name in integration tests (#1595) --- pkg/printers/text.go | 3 +- test/errchk.go | 113 ++++++++++--------- test/linters_test.go | 36 ++++-- test/testdata/asciicheck.go | 2 +- test/testdata/default_exclude.go | 4 +- test/testdata/exportloopref.go | 8 +- test/testdata/forbidigo.go | 2 +- test/testdata/funlen.go | 4 +- test/testdata/go-header_bad.go | 2 +- test/testdata/gocritic.go | 2 +- test/testdata/godox.go | 14 +-- test/testdata/goerr113.go | 6 +- test/testdata/gofmt_no_simplify.go | 2 +- test/testdata/gomnd.go | 4 +- test/testdata/gomodguard.go | 2 +- test/testdata/govet.go | 2 +- test/testdata/nestif.go | 10 +- test/testdata/noctx.go | 48 ++++---- test/testdata/nolintlint_unused.go | 1 + test/testdata/staticcheck_in_megacheck.go | 8 +- test/testdata/stylecheck_not_in_megacheck.go | 8 -- test/testdata/thelper.go | 8 +- 22 files changed, 158 insertions(+), 131 deletions(-) diff --git a/pkg/printers/text.go b/pkg/printers/text.go index 283499205334..1814528884c4 100644 --- a/pkg/printers/text.go +++ b/pkg/printers/text.go @@ -3,6 +3,7 @@ package printers import ( "context" "fmt" + "strings" "github.com/fatih/color" @@ -52,7 +53,7 @@ func (p *Text) Print(ctx context.Context, issues []result.Issue) error { } func (p Text) printIssue(i *result.Issue) { - text := p.SprintfColored(color.FgRed, "%s", i.Text) + text := p.SprintfColored(color.FgRed, "%s", strings.TrimSpace(i.Text)) if p.printLinterName { text += fmt.Sprintf(" (%s)", i.FromLinter) } diff --git a/test/errchk.go b/test/errchk.go index ae2c42d759d9..b84d7b9ce5ea 100644 --- a/test/errchk.go +++ b/test/errchk.go @@ -11,6 +11,8 @@ import ( "strings" ) +var errorLineRx = regexp.MustCompile(`^\S+?: (.*)\((\S+?)\)$`) + // errorCheck matches errors in outStr against comments in source files. // For each line of the source files which should generate an error, // there should be a comment of the form // ERROR "regexp". @@ -22,8 +24,8 @@ import ( // // Sources files are supplied as fullshort slice. // It consists of pairs: full path to source file and its base name. -//nolint:gocyclo -func errorCheck(outStr string, wantAuto bool, fullshort ...string) (err error) { +//nolint:gocyclo,funlen +func errorCheck(outStr string, wantAuto bool, defaultWantedLinter string, fullshort ...string) (err error) { var errs []error out := splitOutput(outStr, wantAuto) // Cut directory name. @@ -37,9 +39,16 @@ func errorCheck(outStr string, wantAuto bool, fullshort ...string) (err error) { var want []wantedError for j := 0; j < len(fullshort); j += 2 { full, short := fullshort[j], fullshort[j+1] - want = append(want, wantedErrors(full, short)...) + want = append(want, wantedErrors(full, short, defaultWantedLinter)...) } for _, we := range want { + if we.linter == "" { + err := fmt.Errorf("%s:%d: no expected linter indicated for test", + we.file, we.lineNum) + errs = append(errs, err) + continue + } + var errmsgs []string if we.auto { errmsgs, out = partitionStrings("", out) @@ -51,25 +60,35 @@ func errorCheck(outStr string, wantAuto bool, fullshort ...string) (err error) { continue } matched := false - n := len(out) var textsToMatch []string for _, errmsg := range errmsgs { - // Assume errmsg says "file:line: foo". - // Cut leading "file:line: " to avoid accidental matching of file name instead of message. - text := errmsg - if i := strings.Index(text, " "); i >= 0 { - text = text[i+1:] + // Assume errmsg says "file:line: foo ()". + matches := errorLineRx.FindStringSubmatch(errmsg) + if len(matches) == 0 { + err := fmt.Errorf("%s:%d: unexpected error line: %s", + we.file, we.lineNum, errmsg) + errs = append(errs, err) + continue } + + text, actualLinter := matches[1], matches[2] + if we.re.MatchString(text) { matched = true } else { out = append(out, errmsg) textsToMatch = append(textsToMatch, text) } + + if actualLinter != we.linter { + err := fmt.Errorf("%s:%d: expected error from %q but got error from %q in:\n\t%s", + we.file, we.lineNum, we.linter, actualLinter, strings.Join(out, "\n\t")) + errs = append(errs, err) + } } if !matched { err := fmt.Errorf("%s:%d: no match for %#q vs %q in:\n\t%s", - we.file, we.lineNum, we.reStr, textsToMatch, strings.Join(out[n:], "\n\t")) + we.file, we.lineNum, we.reStr, textsToMatch, strings.Join(out, "\n\t")) errs = append(errs, err) continue } @@ -150,18 +169,18 @@ type wantedError struct { auto bool // match line file string prefix string + linter string } var ( - errRx = regexp.MustCompile(`// (?:GC_)?ERROR (.*)`) - errAutoRx = regexp.MustCompile(`// (?:GC_)?ERRORAUTO (.*)`) - errQuotesRx = regexp.MustCompile(`"([^"]*)"`) - lineRx = regexp.MustCompile(`LINE(([+-])(\d+))?`) + errRx = regexp.MustCompile(`// (?:GC_)?ERROR (.*)`) + errAutoRx = regexp.MustCompile(`// (?:GC_)?ERRORAUTO (.*)`) + linterPrefixRx = regexp.MustCompile("^\\s*([^\\s\"`]+)") ) // wantedErrors parses expected errors from comments in a file. //nolint:nakedret -func wantedErrors(file, short string) (errs []wantedError) { +func wantedErrors(file, short, defaultLinter string) (errs []wantedError) { cache := make(map[string]*regexp.Regexp) src, err := ioutil.ReadFile(file) @@ -184,47 +203,35 @@ func wantedErrors(file, short string) (errs []wantedError) { if m == nil { continue } - all := m[1] - mm := errQuotesRx.FindAllStringSubmatch(all, -1) - if mm == nil { - log.Fatalf("%s:%d: invalid errchk line: %s", file, lineNum, line) + rest := m[1] + linter := defaultLinter + if lm := linterPrefixRx.FindStringSubmatch(rest); lm != nil { + linter = lm[1] + rest = rest[len(lm[0]):] + } + rx, err := strconv.Unquote(strings.TrimSpace(rest)) + if err != nil { + log.Fatalf("%s:%d: invalid errchk line: %s, %v", file, lineNum, line, err) } - for _, m := range mm { - replacedOnce := false - rx := lineRx.ReplaceAllStringFunc(m[1], func(m string) string { - if replacedOnce { - return m - } - replacedOnce = true - n := lineNum - if strings.HasPrefix(m, "LINE+") { - delta, _ := strconv.Atoi(m[5:]) - n += delta - } else if strings.HasPrefix(m, "LINE-") { - delta, _ := strconv.Atoi(m[5:]) - n -= delta - } - return fmt.Sprintf("%s:%d", short, n) - }) - re := cache[rx] - if re == nil { - var err error - re, err = regexp.Compile(rx) - if err != nil { - log.Fatalf("%s:%d: invalid regexp \"%#q\" in ERROR line: %v", file, lineNum, rx, err) - } - cache[rx] = re + re := cache[rx] + if re == nil { + var err error + re, err = regexp.Compile(rx) + if err != nil { + log.Fatalf("%s:%d: invalid regexp \"%#q\" in ERROR line: %v", file, lineNum, rx, err) } - prefix := fmt.Sprintf("%s:%d", short, lineNum) - errs = append(errs, wantedError{ - reStr: rx, - re: re, - prefix: prefix, - auto: auto, - lineNum: lineNum, - file: short, - }) + cache[rx] = re } + prefix := fmt.Sprintf("%s:%d", short, lineNum) + errs = append(errs, wantedError{ + reStr: rx, + re: re, + prefix: prefix, + auto: auto, + lineNum: lineNum, + file: short, + linter: linter, + }) } return diff --git a/test/linters_test.go b/test/linters_test.go index e0508cf328ea..4de5c65d0622 100644 --- a/test/linters_test.go +++ b/test/linters_test.go @@ -15,7 +15,7 @@ import ( "github.com/golangci/golangci-lint/test/testshared" ) -func runGoErrchk(c *exec.Cmd, files []string, t *testing.T) { +func runGoErrchk(c *exec.Cmd, defaultExpectedLinter string, files []string, t *testing.T) { output, err := c.CombinedOutput() // The returned error will be nil if the test file does not have any issues // and thus the linter exits with exit code 0. So perform the additional @@ -33,7 +33,7 @@ func runGoErrchk(c *exec.Cmd, files []string, t *testing.T) { fullshort = append(fullshort, f, filepath.Base(f)) } - err = errorCheck(string(output), false, fullshort...) + err = errorCheck(string(output), false, defaultExpectedLinter, fullshort...) assert.NoError(t, err) } @@ -124,7 +124,6 @@ func testOneSource(t *testing.T, sourcePath string) { "--allow-parallel-runners", "--disable-all", "--print-issued-lines=false", - "--print-linter-name=false", "--out-format=line-number", "--max-same-issues=100", } @@ -156,14 +155,15 @@ func testOneSource(t *testing.T, sourcePath string) { cmd := exec.Command(binName, caseArgs...) t.Log(caseArgs) - runGoErrchk(cmd, []string{sourcePath}, t) + runGoErrchk(cmd, rc.expectedLinter, []string{sourcePath}, t) } } type runContext struct { - args []string - config map[string]interface{} - configPath string + args []string + config map[string]interface{} + configPath string + expectedLinter string } func buildConfigFromShortRepr(t *testing.T, repr string, config map[string]interface{}) { @@ -213,7 +213,7 @@ func extractRunContextFromComments(t *testing.T, sourcePath string) *runContext continue } if !strings.HasPrefix(line, "//") { - return rc + break } line = strings.TrimLeft(strings.TrimPrefix(line, "//"), " ") @@ -242,9 +242,29 @@ func extractRunContextFromComments(t *testing.T, sourcePath string) *runContext continue } + if strings.HasPrefix(line, "expected_linter: ") { + expectedLinter := strings.TrimPrefix(line, "expected_linter: ") + assert.NotEmpty(t, expectedLinter) + rc.expectedLinter = expectedLinter + continue + } + assert.Fail(t, "invalid prefix of comment line %s", line) } + // guess the expected linter if none is specified + if rc.expectedLinter == "" { + for _, arg := range rc.args { + if strings.HasPrefix(arg, "-E") && !strings.Contains(arg, ",") { + if rc.expectedLinter != "" { + assert.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 + break + } + rc.expectedLinter = arg[2:] + } + } + } + return rc } diff --git a/test/testdata/asciicheck.go b/test/testdata/asciicheck.go index cc6ecf8db5d9..3c6cc0c54b46 100644 --- a/test/testdata/asciicheck.go +++ b/test/testdata/asciicheck.go @@ -1,4 +1,4 @@ //args: -Easciicheck package testdata -type TеstStruct struct{} // ERROR `identifier "TеstStruct" contain non-ASCII character: U+0435 'е'` +type TеstStruct struct{} // ERROR `identifier "TеstStruct" contain non-ASCII character: U\+0435 'е'` diff --git a/test/testdata/default_exclude.go b/test/testdata/default_exclude.go index dad1feca6959..beed57ac6757 100644 --- a/test/testdata/default_exclude.go +++ b/test/testdata/default_exclude.go @@ -4,13 +4,13 @@ /*Package testdata ...*/ package testdata -// InvalidFuncComment, both golint and stylecheck will complain about this, // ERROR `ST1020: comment on exported function ExportedFunc1 should be of the form "ExportedFunc1 ..."` +// InvalidFuncComment, both golint and stylecheck will complain about this, // ERROR stylecheck `ST1020: comment on exported function ExportedFunc1 should be of the form "ExportedFunc1 ..."` // if include EXC0011, only the warning from golint will be ignored. // And only the warning from stylecheck will start with "ST1020". func ExportedFunc1() { } -// InvalidFuncComment // ERROR `ST1020: comment on exported function ExportedFunc2 should be of the form "ExportedFunc2 ..."` +// InvalidFuncComment // ERROR stylecheck `ST1020: comment on exported function ExportedFunc2 should be of the form "ExportedFunc2 ..."` // nolint:golint func ExportedFunc2() { } diff --git a/test/testdata/exportloopref.go b/test/testdata/exportloopref.go index 664c1c0e41f9..839113ad3bc7 100644 --- a/test/testdata/exportloopref.go +++ b/test/testdata/exportloopref.go @@ -10,11 +10,11 @@ func dummyFunction() { println("loop expecting 10, 11, 12, 13") for i, p := range []int{10, 11, 12, 13} { printp(&p) - slice = append(slice, &p) // ERROR : "exporting a pointer for the loop variable p" - array[i] = &p // ERROR : "exporting a pointer for the loop variable p" + slice = append(slice, &p) // ERROR "exporting a pointer for the loop variable p" + array[i] = &p // ERROR "exporting a pointer for the loop variable p" if i%2 == 0 { - ref = &p // ERROR : "exporting a pointer for the loop variable p" - str.x = &p // ERROR : "exporting a pointer for the loop variable p" + ref = &p // ERROR "exporting a pointer for the loop variable p" + str.x = &p // ERROR "exporting a pointer for the loop variable p" } var vStr struct{ x *int } var vArray [4]*int diff --git a/test/testdata/forbidigo.go b/test/testdata/forbidigo.go index 441d21b99d1a..5ac04676b795 100644 --- a/test/testdata/forbidigo.go +++ b/test/testdata/forbidigo.go @@ -5,5 +5,5 @@ package testdata import "fmt" func Forbidigo() { - fmt.Printf("too noisy!!!") // ERROR "use of `fmt.Printf` forbidden by pattern `fmt\\.Print.*`" + fmt.Printf("too noisy!!!") // ERROR "use of `fmt\\.Printf` forbidden by pattern `fmt\\\\.Print\\.\\*`" } diff --git a/test/testdata/funlen.go b/test/testdata/funlen.go index 4f8fb8d7c507..e37e35525525 100644 --- a/test/testdata/funlen.go +++ b/test/testdata/funlen.go @@ -3,7 +3,7 @@ //config: linters-settings.funlen.statements=10 package testdata -func TooManyLines() { // ERROR "Function 'TooManyLines' is too long \(22 > 20\)" +func TooManyLines() { // ERROR `Function 'TooManyLines' is too long \(22 > 20\)` t := struct { A string B string @@ -28,7 +28,7 @@ func TooManyLines() { // ERROR "Function 'TooManyLines' is too long \(22 > 20\)" _ = t } -func TooManyStatements() { // ERROR "Function 'TooManyStatements' has too many statements \(11 > 10\)" +func TooManyStatements() { // ERROR `Function 'TooManyStatements' has too many statements \(11 > 10\)` a := 1 b := a c := b diff --git a/test/testdata/go-header_bad.go b/test/testdata/go-header_bad.go index 17c3099eaa2a..c9db39c41b4c 100644 --- a/test/testdata/go-header_bad.go +++ b/test/testdata/go-header_bad.go @@ -1,4 +1,4 @@ -/*MY TITLE!*/ // ERROR "Expected:TITLE., Actual: TITLE!" +/*MY TITLE!*/ // ERROR `Expected:TITLE\., Actual: TITLE!` //args: -Egoheader //config_path: testdata/configs/go-header.yml diff --git a/test/testdata/gocritic.go b/test/testdata/gocritic.go index 1e48bd3820db..5e821a4e6553 100644 --- a/test/testdata/gocritic.go +++ b/test/testdata/gocritic.go @@ -7,7 +7,7 @@ import ( "log" ) -var _ = *flag.Bool("global1", false, "") // ERROR "flagDeref: immediate deref in \*flag.Bool\(.global1., false, ..\) is most likely an error; consider using flag\.BoolVar" +var _ = *flag.Bool("global1", false, "") // ERROR `flagDeref: immediate deref in \*flag.Bool\(.global1., false, ..\) is most likely an error; consider using flag\.BoolVar` type size1 struct { a bool diff --git a/test/testdata/godox.go b/test/testdata/godox.go index 3ee7b98e840e..59a751db5914 100644 --- a/test/testdata/godox.go +++ b/test/testdata/godox.go @@ -3,11 +3,11 @@ package testdata func todoLeftInCode() { - // TODO implement me // ERROR godox.go:6: Line contains FIXME/TODO: "TODO implement me" - //TODO no space // ERROR godox.go:7: Line contains FIXME/TODO: "TODO no space" - // TODO(author): 123 // ERROR godox.go:8: Line contains FIXME/TODO: "TODO\(author\): 123 // ERROR godox.go:8: L..." - //TODO(author): 123 // ERROR godox.go:9: Line contains FIXME/TODO: "TODO\(author\): 123 // ERROR godox.go:9: L..." - //TODO(author) 456 // ERROR godox.go:10: Line contains FIXME/TODO: "TODO\(author\) 456 // ERROR godox.go:10: L..." - // TODO: qwerty // ERROR godox.go:11: Line contains FIXME/TODO: "TODO: qwerty // ERROR godox.go:11: Line ..." - // todo 789 // ERROR godox.go:12: Line contains FIXME/TODO: "todo 789" + // TODO implement me // ERROR `Line contains FIXME/TODO: "TODO implement me` + //TODO no space // ERROR `Line contains FIXME/TODO: "TODO no space` + // TODO(author): 123 // ERROR `Line contains FIXME/TODO: "TODO\(author\): 123` + //TODO(author): 123 // ERROR `Line contains FIXME/TODO: "TODO\(author\): 123` + //TODO(author) 456 // ERROR `Line contains FIXME/TODO: "TODO\(author\) 456` + // TODO: qwerty // ERROR `Line contains FIXME/TODO: "TODO: qwerty` + // todo 789 // ERROR `Line contains FIXME/TODO: "todo 789` } diff --git a/test/testdata/goerr113.go b/test/testdata/goerr113.go index 3f2a4e2933cb..c1b7c04f18d6 100644 --- a/test/testdata/goerr113.go +++ b/test/testdata/goerr113.go @@ -4,17 +4,17 @@ package testdata import "os" func SimpleEqual(e1, e2 error) bool { - return e1 == e2 // ERROR `err113: do not compare errors directly, use errors.Is() instead: "e1 == e2"` + return e1 == e2 // ERROR `err113: do not compare errors directly, use errors.Is\(\) instead: "e1 == e2"` } func SimpleNotEqual(e1, e2 error) bool { - return e1 != e2 // ERROR `err113: do not compare errors directly, use errors.Is() instead: "e1 != e2"` + return e1 != e2 // ERROR `err113: do not compare errors directly, use errors.Is\(\) instead: "e1 != e2"` } func CheckGoerr13Import(e error) bool { f, err := os.Create("f.txt") if err != nil { - return err == e // ERROR `err113: do not compare errors directly, use errors.Is() instead: "err == e"` + return err == e // ERROR `err113: do not compare errors directly, use errors.Is\(\) instead: "err == e"` } f.Close() return false diff --git a/test/testdata/gofmt_no_simplify.go b/test/testdata/gofmt_no_simplify.go index bcdcf262d062..c5cfd58aef26 100644 --- a/test/testdata/gofmt_no_simplify.go +++ b/test/testdata/gofmt_no_simplify.go @@ -9,5 +9,5 @@ func GofmtNotSimplifiedOk() { fmt.Print(x[1:len(x)]) } -func GofmtBadFormat(){ // ERROR "^File is not `gofmt`-ed$" +func GofmtBadFormat(){ // ERROR "^File is not `gofmt`-ed" } diff --git a/test/testdata/gomnd.go b/test/testdata/gomnd.go index 08a33780b048..204018b7a093 100644 --- a/test/testdata/gomnd.go +++ b/test/testdata/gomnd.go @@ -9,14 +9,14 @@ import ( func UseMagicNumber() { c := &http.Client{ - Timeout: 2 * time.Second, // ERROR : "Magic number: 2, in detected" + Timeout: 2 * time.Second, // ERROR "Magic number: 2, in detected" } res, err := c.Get("http://www.google.com") if err != nil { log.Fatal(err) } - if res.StatusCode != 200 { // ERROR : "Magic number: 200, in detected" + if res.StatusCode != 200 { // ERROR "Magic number: 200, in detected" log.Println("Something went wrong") } } diff --git a/test/testdata/gomodguard.go b/test/testdata/gomodguard.go index f5f752324392..cbde5f4919f5 100644 --- a/test/testdata/gomodguard.go +++ b/test/testdata/gomodguard.go @@ -6,7 +6,7 @@ import ( "log" "golang.org/x/mod/modfile" - "gopkg.in/yaml.v2" // ERROR : "import of package `gopkg.in/yaml.v2` is blocked because the module is in the blocked modules list. `github.com/kylelemons/go-gypsy` is a recommended module. This is an example of recommendations." + "gopkg.in/yaml.v2" // ERROR "import of package `gopkg.in/yaml.v2` is blocked because the module is in the blocked modules list. `github.com/kylelemons/go-gypsy` is a recommended module. This is an example of recommendations." ) // Something just some struct diff --git a/test/testdata/govet.go b/test/testdata/govet.go index c928699cdcd0..d4c67bf325fb 100644 --- a/test/testdata/govet.go +++ b/test/testdata/govet.go @@ -14,7 +14,7 @@ func Govet() error { func GovetShadow(f io.Reader, buf []byte) (err error) { if f != nil { - _, err := f.Read(buf) // ERROR "shadow: declaration of .err. shadows declaration at line \d+" + _, err := f.Read(buf) // ERROR `shadow: declaration of .err. shadows declaration at line \d+` if err != nil { return err } diff --git a/test/testdata/nestif.go b/test/testdata/nestif.go index 350e0a7257f1..d63df75c74ea 100644 --- a/test/testdata/nestif.go +++ b/test/testdata/nestif.go @@ -5,19 +5,19 @@ package testdata func _() { var b1, b2, b3, b4 bool - if b1 { // ERROR "`if b1` is deeply nested \(complexity: 1\)" + if b1 { // ERROR "`if b1` is deeply nested \\(complexity: 1\\)" if b2 { // +1 } } - if b1 { // ERROR "`if b1` is deeply nested \(complexity: 3\)" + if b1 { // ERROR "`if b1` is deeply nested \\(complexity: 3\\)" if b2 { // +1 if b3 { // +2 } } } - if b1 { // ERROR "`if b1` is deeply nested \(complexity: 5\)" + if b1 { // ERROR "`if b1` is deeply nested \\(complexity: 5\\)" if b2 { // +1 } else if b3 { // +1 if b4 { // +2 @@ -26,7 +26,7 @@ func _() { } } - if b1 { // ERROR "`if b1` is deeply nested \(complexity: 9\)" + if b1 { // ERROR "`if b1` is deeply nested \\(complexity: 9\\)" if b2 { // +1 if b3 { // +2 } @@ -40,7 +40,7 @@ func _() { } } - if b1 == b2 == b3 { // ERROR "`if b1 == b2 == b3` is deeply nested \(complexity: 1\)" + if b1 == b2 == b3 { // ERROR "`if b1 == b2 == b3` is deeply nested \\(complexity: 1\\)" if b4 { // +1 } } diff --git a/test/testdata/noctx.go b/test/testdata/noctx.go index e78b25010dcb..d29169ff6a73 100644 --- a/test/testdata/noctx.go +++ b/test/testdata/noctx.go @@ -13,25 +13,25 @@ func Noctx() { cli := &http.Client{} ctx := context.Background() - http.Get(url) // ERROR "net/http\.Get must not be called" + http.Get(url) // ERROR `net/http\.Get must not be called` _ = http.Get // OK f := http.Get // OK - f(url) // ERROR "net/http\.Get must not be called" + f(url) // ERROR `net/http\.Get must not be called` - http.Head(url) // ERROR "net/http\.Head must not be called" - http.Post(url, "", nil) // ERROR "net/http\.Post must not be called" - http.PostForm(url, nil) // ERROR "net/http\.PostForm must not be called" + http.Head(url) // ERROR `net/http\.Head must not be called` + http.Post(url, "", nil) // ERROR `net/http\.Post must not be called` + http.PostForm(url, nil) // ERROR `net/http\.PostForm must not be called` - cli.Get(url) // ERROR "\(\*net/http\.Client\)\.Get must not be called" + cli.Get(url) // ERROR `\(\*net/http\.Client\)\.Get must not be called` _ = cli.Get // OK m := cli.Get // OK - m(url) // ERROR "\(\*net/http\.Client\)\.Get must not be called" + m(url) // ERROR `\(\*net/http\.Client\)\.Get must not be called` - cli.Head(url) // ERROR "\(\*net/http\.Client\)\.Head must not be called" - cli.Post(url, "", nil) // ERROR "\(\*net/http\.Client\)\.Post must not be called" - cli.PostForm(url, nil) // ERROR "\(\*net/http\.Client\)\.PostForm must not be called" + cli.Head(url) // ERROR `\(\*net/http\.Client\)\.Head must not be called` + cli.Post(url, "", nil) // ERROR `\(\*net/http\.Client\)\.Post must not be called` + cli.PostForm(url, nil) // ERROR `\(\*net/http\.Client\)\.PostForm must not be called` - req, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR `should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext` cli.Do(req) req2, _ := http.NewRequestWithContext(ctx, http.MethodPost, url, nil) // OK @@ -44,7 +44,7 @@ func Noctx() { f2 := func(req *http.Request, ctx context.Context) *http.Request { return req } - req4, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req4, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR `should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext` req4 = f2(req4, ctx) req41, _ := http.NewRequest(http.MethodPost, url, nil) // OK @@ -52,21 +52,21 @@ func Noctx() { req41 = f2(req41, ctx) newRequest := http.NewRequest - req5, _ := newRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req5, _ := newRequest(http.MethodPost, url, nil) // ERROR `should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext` cli.Do(req5) req51, _ := newRequest(http.MethodPost, url, nil) // OK req51 = req51.WithContext(ctx) cli.Do(req51) - req52, _ := newRequestPkg(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req52, _ := newRequestPkg(http.MethodPost, url, nil) // ERROR `should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext` cli.Do(req52) type MyRequest = http.Request f3 := func(req *MyRequest, ctx context.Context) *MyRequest { return req } - req6, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req6, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR `should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext` req6 = f3(req6, ctx) req61, _ := http.NewRequest(http.MethodPost, url, nil) // OK @@ -77,7 +77,7 @@ func Noctx() { f4 := func(req *MyRequest2, ctx context.Context) *MyRequest2 { return req } - req7, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req7, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR `should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext` req71 := MyRequest2(*req7) f4(&req71, ctx) @@ -87,7 +87,7 @@ func Noctx() { f4(&req73, ctx) req8, _ := func() (*http.Request, error) { - return http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + return http.NewRequest(http.MethodPost, url, nil) // ERROR `should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext` }() cli.Do(req8) @@ -101,30 +101,30 @@ func Noctx() { f5 := func(req, req2 *http.Request, ctx context.Context) (*http.Request, *http.Request) { return req, req2 } - req9, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req9, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR `should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext` req9, _ = f5(req9, req9, ctx) req91, _ := http.NewRequest(http.MethodPost, url, nil) // OK req91 = req91.WithContext(ctx) req9, _ = f5(req91, req91, ctx) - req10, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" - req11, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req10, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR `should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext` + req11, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR `should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext` req10, req11 = f5(req10, req11, ctx) - req101, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req101, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR `should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext` req111, _ := http.NewRequest(http.MethodPost, url, nil) // OK req111 = req111.WithContext(ctx) req101, req111 = f5(req101, req111, ctx) func() (*http.Request, *http.Request) { - req12, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" - req13, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req12, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR `should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext` + req13, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR `should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext` return req12, req13 }() func() (*http.Request, *http.Request) { - req14, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR "should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext" + req14, _ := http.NewRequest(http.MethodPost, url, nil) // ERROR `should rewrite http.NewRequestWithContext or add \(\*Request\).WithContext` req15, _ := http.NewRequest(http.MethodPost, url, nil) // OK req15 = req15.WithContext(ctx) diff --git a/test/testdata/nolintlint_unused.go b/test/testdata/nolintlint_unused.go index f9d7b41f235a..df323bb55ed9 100644 --- a/test/testdata/nolintlint_unused.go +++ b/test/testdata/nolintlint_unused.go @@ -1,5 +1,6 @@ //args: -Enolintlint -Evarcheck //config: linters-settings.nolintlint.allow-unused=false +//expected_linter: nolintlint package testdata import "fmt" diff --git a/test/testdata/staticcheck_in_megacheck.go b/test/testdata/staticcheck_in_megacheck.go index 6c424bd2de27..8c8cde4255b5 100644 --- a/test/testdata/staticcheck_in_megacheck.go +++ b/test/testdata/staticcheck_in_megacheck.go @@ -5,7 +5,7 @@ import "fmt" func StaticcheckInMegacheck() { var x int - x = x // ERROR "self-assignment of x to x" + x = x // ERROR staticcheck "self-assignment of x to x" fmt.Printf("%d", x) } @@ -18,3 +18,9 @@ func StaticcheckNolintMegacheckInMegacheck() { var x int x = x //nolint:megacheck } + +func Staticcheck2() { + var x int + x = x // ERROR staticcheck "self-assignment of x to x" + fmt.Printf("%d", x) +} diff --git a/test/testdata/stylecheck_not_in_megacheck.go b/test/testdata/stylecheck_not_in_megacheck.go index 374469a35357..d23fb5f11400 100644 --- a/test/testdata/stylecheck_not_in_megacheck.go +++ b/test/testdata/stylecheck_not_in_megacheck.go @@ -1,16 +1,8 @@ //args: -Emegacheck package testdata -import "fmt" - func StylecheckNotInMegacheck(x int) { if 0 == x { panic(x) } } - -func Staticcheck2() { - var x int - x = x // ERROR "self-assignment of x to x" - fmt.Printf("%d", x) -} diff --git a/test/testdata/thelper.go b/test/testdata/thelper.go index 677cdb1f8815..077b7addea70 100644 --- a/test/testdata/thelper.go +++ b/test/testdata/thelper.go @@ -8,11 +8,11 @@ func thelperWithHelperAfterAssignment(t *testing.T) { // ERROR "test helper func t.Helper() } -func thelperWithNotFirst(s string, t *testing.T, i int) { // ERROR "parameter \*testing.T should be the first" +func thelperWithNotFirst(s string, t *testing.T, i int) { // ERROR `parameter \*testing.T should be the first` t.Helper() } -func thelperWithIncorrectName(o *testing.T) { // ERROR "parameter \*testing.T should have name t" +func thelperWithIncorrectName(o *testing.T) { // ERROR `parameter \*testing.T should have name t` o.Helper() } @@ -21,11 +21,11 @@ func bhelperWithHelperAfterAssignment(b *testing.B) { // ERROR "test helper func b.Helper() } -func bhelperWithNotFirst(s string, b *testing.B, i int) { // ERROR "parameter \*testing.B should be the first" +func bhelperWithNotFirst(s string, b *testing.B, i int) { // ERROR `parameter \*testing.B should be the first` b.Helper() } -func bhelperWithIncorrectName(o *testing.B) { // ERROR "parameter \*testing.B should have name b" +func bhelperWithIncorrectName(o *testing.B) { // ERROR `parameter \*testing.B should have name b` o.Helper() }