Add linter for nolint

Linter can check that nolint statements are properly formatted and also that all
nolint statements are used.
This commit is contained in:
Andrew Shannon Brown 2020-04-26 19:30:14 -07:00
parent 4a3e9fd2bb
commit 909f628d75
51 changed files with 766 additions and 63 deletions

View file

@ -9,6 +9,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/golinters"
"github.com/golangci/golangci-lint/pkg/lint/lintersdb"
"github.com/golangci/golangci-lint/pkg/logutils"
"github.com/golangci/golangci-lint/pkg/result"
@ -31,7 +33,7 @@ func newNolint2FileIssue(line int) result.Issue {
}
func newTestNolintProcessor(log logutils.Log) *Nolint {
return NewNolint(log, lintersdb.NewManager(nil, nil))
return NewNolint(log, lintersdb.NewManager(nil, nil), nil)
}
func getMockLog() *logutils.MockLog {
@ -40,7 +42,6 @@ func getMockLog() *logutils.MockLog {
return log
}
//nolint:funlen
func TestNolint(t *testing.T) {
p := newTestNolintProcessor(getMockLog())
defer p.Finish()
@ -229,7 +230,7 @@ func TestNolintWholeFile(t *testing.T) {
Filename: fileName,
Line: 4,
},
FromLinter: "unparam",
FromLinter: "varcheck",
})
processAssertSame(t, p, result.Issue{
Pos: token.Position{
@ -239,3 +240,68 @@ func TestNolintWholeFile(t *testing.T) {
FromLinter: "deadcode",
})
}
func TestNolintUnused(t *testing.T) {
fileName := filepath.Join("testdata", "nolint_unused.go")
log := getMockLog()
log.On("Warnf", "Found unknown linters in //nolint directives: %s", "blah")
createProcessor := func(t *testing.T, log *logutils.MockLog, enabledLinters []string) *Nolint {
enabledSetLog := logutils.NewMockLog()
enabledSetLog.On("Infof", "Active %d linters: %s", len(enabledLinters), enabledLinters)
cfg := &config.Config{Linters: config.Linters{DisableAll: true, Enable: enabledLinters}}
dbManager := lintersdb.NewManager(cfg, nil)
enabledLintersSet := lintersdb.NewEnabledSet(dbManager, lintersdb.NewValidator(dbManager), enabledSetLog, cfg)
lcs, err := enabledLintersSet.Get(false)
assert.NoError(t, err)
return NewNolint(log, dbManager, lcs)
}
// the issues below the nolintlint issues that would be generated for the test file
nolintlintIssueVarcheck := result.Issue{
Pos: token.Position{
Filename: fileName,
Line: 3,
},
FromLinter: golinters.NolintlintName,
ExpectNoLint: true,
ExpectedNoLintLinter: "varcheck",
}
t.Run("when an issue does not occur, it is not removed from the nolintlint issues", func(t *testing.T) {
p := createProcessor(t, log, []string{"nolintlint", "varcheck"})
defer p.Finish()
processAssertSame(t, p, nolintlintIssueVarcheck)
})
t.Run("when an issue occurs, it is removed from the nolintlint issues", func(t *testing.T) {
p := createProcessor(t, log, []string{"nolintlint", "varcheck"})
defer p.Finish()
processAssertEmpty(t, p, []result.Issue{{
Pos: token.Position{
Filename: fileName,
Line: 3,
},
FromLinter: "varcheck",
}, nolintlintIssueVarcheck}...)
})
t.Run("when a linter is not enabled, it is removed from the nolintlint unused issues", func(t *testing.T) {
enabledSetLog := logutils.NewMockLog()
enabledSetLog.On("Infof", "Active %d linters: %s", 1, []string{"nolintlint"})
cfg := &config.Config{Linters: config.Linters{DisableAll: true, Enable: []string{"nolintlint"}}}
dbManager := lintersdb.NewManager(cfg, nil)
enabledLintersSet := lintersdb.NewEnabledSet(dbManager, lintersdb.NewValidator(dbManager), enabledSetLog, cfg)
lcs, err := enabledLintersSet.Get(false)
assert.NoError(t, err)
p := NewNolint(log, dbManager, lcs)
defer p.Finish()
processAssertEmpty(t, p, nolintlintIssueVarcheck)
})
}