Verify linter name in integration tests (#1595)

This commit is contained in:
Andrew Shannon Brown 2021-01-15 12:37:56 -08:00 committed by GitHub
parent 257eb9523a
commit ec46f42e01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 158 additions and 131 deletions

View File

@ -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)
}

View File

@ -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("<autogenerated>", 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 (<linter>)".
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 <autogenerated> 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]):]
}
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
rx, err := strconv.Unquote(strings.TrimSpace(rest))
if err != nil {
log.Fatalf("%s:%d: invalid errchk line: %s, %v", file, lineNum, line, err)
}
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

View File

@ -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
}

View File

@ -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 'е'`

View File

@ -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() {
}

View File

@ -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

View File

@ -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\\.\\*`"
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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`
}

View File

@ -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

View File

@ -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"
}

View File

@ -9,14 +9,14 @@ import (
func UseMagicNumber() {
c := &http.Client{
Timeout: 2 * time.Second, // ERROR : "Magic number: 2, in <assign> detected"
Timeout: 2 * time.Second, // ERROR "Magic number: 2, in <assign> detected"
}
res, err := c.Get("http://www.google.com")
if err != nil {
log.Fatal(err)
}
if res.StatusCode != 200 { // ERROR : "Magic number: 200, in <condition> detected"
if res.StatusCode != 200 { // ERROR "Magic number: 200, in <condition> detected"
log.Println("Something went wrong")
}
}

View File

@ -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

View File

@ -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
}

View File

@ -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
}
}

View File

@ -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)

View File

@ -1,5 +1,6 @@
//args: -Enolintlint -Evarcheck
//config: linters-settings.nolintlint.allow-unused=false
//expected_linter: nolintlint
package testdata
import "fmt"

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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()
}