github.com/nozzle/golangci-lint@v1.49.0-nz3/pkg/golinters/nolintlint/nolintlint_test.go (about) 1 package nolintlint 2 3 import ( 4 "go/parser" 5 "go/token" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 "github.com/stretchr/testify/require" 10 11 "github.com/golangci/golangci-lint/pkg/result" 12 ) 13 14 //nolint:funlen 15 func TestLinter_Run(t *testing.T) { 16 type issueWithReplacement struct { 17 issue string 18 replacement *result.Replacement 19 } 20 testCases := []struct { 21 desc string 22 needs Needs 23 excludes []string 24 contents string 25 expected []issueWithReplacement 26 }{ 27 { 28 desc: "when no explanation is provided", 29 needs: NeedsExplanation, 30 contents: ` 31 package bar 32 33 // example 34 //nolint 35 func foo() { 36 bad() //nolint 37 bad() //nolint // 38 bad() //nolint // 39 good() //nolint // this is ok 40 other() //nolintother 41 }`, 42 expected: []issueWithReplacement{ 43 {issue: "directive `//nolint` should provide explanation such as `//nolint // this is why` at testing.go:5:1"}, 44 {issue: "directive `//nolint` should provide explanation such as `//nolint // this is why` at testing.go:7:9"}, 45 {issue: "directive `//nolint //` should provide explanation such as `//nolint // this is why` at testing.go:8:9"}, 46 {issue: "directive `//nolint // ` should provide explanation such as `//nolint // this is why` at testing.go:9:9"}, 47 }, 48 }, 49 { 50 desc: "when multiple directives on multiple lines", 51 needs: NeedsExplanation, 52 contents: ` 53 package bar 54 55 // example 56 //nolint // this is ok 57 //nolint:dupl 58 func foo() {}`, 59 expected: []issueWithReplacement{ 60 {issue: "directive `//nolint:dupl` should provide explanation such as `//nolint:dupl // this is why` at testing.go:6:1"}, 61 }, 62 }, 63 { 64 desc: "when no explanation is needed for a specific linter", 65 needs: NeedsExplanation, 66 excludes: []string{"lll"}, 67 contents: ` 68 package bar 69 70 func foo() { 71 thisIsAReallyLongLine() //nolint:lll 72 }`, 73 }, 74 { 75 desc: "when no specific linter is mentioned", 76 needs: NeedsSpecific, 77 contents: ` 78 package bar 79 80 func foo() { 81 good() //nolint:my-linter 82 bad() //nolint 83 bad() //nolint // because 84 }`, 85 expected: []issueWithReplacement{ 86 {issue: "directive `//nolint` should mention specific linter such as `//nolint:my-linter` at testing.go:6:9"}, 87 {issue: "directive `//nolint // because` should mention specific linter such as `//nolint:my-linter` at testing.go:7:9"}, 88 }, 89 }, 90 { 91 desc: "when machine-readable style isn't used", 92 contents: ` 93 package bar 94 95 func foo() { 96 bad() // nolint 97 bad() // nolint 98 good() //nolint 99 }`, 100 expected: []issueWithReplacement{ 101 { 102 issue: "directive `// nolint` should be written without leading space as `//nolint` at testing.go:5:9", 103 replacement: &result.Replacement{ 104 Inline: &result.InlineFix{ 105 StartCol: 10, 106 Length: 1, 107 NewString: "", 108 }, 109 }, 110 }, 111 { 112 issue: "directive `// nolint` should be written without leading space as `//nolint` at testing.go:6:9", 113 replacement: &result.Replacement{ 114 Inline: &result.InlineFix{ 115 StartCol: 10, 116 Length: 3, 117 NewString: "", 118 }, 119 }, 120 }, 121 }, 122 }, 123 { 124 desc: "spaces are allowed in comma-separated list of linters", 125 contents: ` 126 package bar 127 128 func foo() { 129 good() //nolint:linter1,linter-two 130 bad() //nolint:linter1 linter2 131 good() //nolint: linter1,linter2 132 good() //nolint: linter1, linter2 133 }`, 134 expected: []issueWithReplacement{ 135 {issue: "directive `//nolint:linter1 linter2` should match `//nolint[:<comma-separated-linters>] [// <explanation>]` at testing.go:6:9"}, //nolint:lll // this is a string 136 }, 137 }, 138 { 139 desc: "multi-line comments don't confuse parser", 140 contents: ` 141 package bar 142 143 func foo() { 144 //nolint:test 145 // something else 146 }`, 147 }, 148 { 149 desc: "needs unused without specific linter generates replacement", 150 needs: NeedsUnused, 151 contents: ` 152 package bar 153 154 func foo() { 155 bad() //nolint 156 }`, 157 expected: []issueWithReplacement{ 158 { 159 issue: "directive `//nolint` is unused at testing.go:5:9", 160 replacement: &result.Replacement{ 161 Inline: &result.InlineFix{ 162 StartCol: 8, 163 Length: 8, 164 NewString: "", 165 }, 166 }, 167 }, 168 }, 169 }, 170 { 171 desc: "needs unused with one specific linter generates replacement", 172 needs: NeedsUnused, 173 contents: ` 174 package bar 175 176 func foo() { 177 bad() //nolint:somelinter 178 }`, 179 expected: []issueWithReplacement{ 180 { 181 issue: "directive `//nolint:somelinter` is unused for linter \"somelinter\" at testing.go:5:9", 182 replacement: &result.Replacement{ 183 Inline: &result.InlineFix{ 184 StartCol: 8, 185 Length: 19, 186 NewString: "", 187 }, 188 }, 189 }, 190 }, 191 }, 192 { 193 desc: "needs unused with multiple specific linters does not generate replacements", 194 needs: NeedsUnused, 195 contents: ` 196 package bar 197 198 func foo() { 199 bad() //nolint:linter1,linter2 200 }`, 201 expected: []issueWithReplacement{ 202 { 203 issue: "directive `//nolint:linter1,linter2` is unused for linter \"linter1\" at testing.go:5:9", 204 }, 205 { 206 issue: "directive `//nolint:linter1,linter2` is unused for linter \"linter2\" at testing.go:5:9", 207 }, 208 }, 209 }, 210 } 211 212 for _, test := range testCases { 213 test := test 214 t.Run(test.desc, func(t *testing.T) { 215 t.Parallel() 216 217 linter, _ := NewLinter(test.needs, test.excludes) 218 219 fset := token.NewFileSet() 220 expr, err := parser.ParseFile(fset, "testing.go", test.contents, parser.ParseComments) 221 require.NoError(t, err) 222 223 actualIssues, err := linter.Run(fset, expr) 224 require.NoError(t, err) 225 226 actualIssuesWithReplacements := make([]issueWithReplacement, 0, len(actualIssues)) 227 for _, i := range actualIssues { 228 actualIssuesWithReplacements = append(actualIssuesWithReplacements, issueWithReplacement{ 229 issue: i.String(), 230 replacement: i.Replacement(), 231 }) 232 } 233 234 assert.ElementsMatch(t, test.expected, actualIssuesWithReplacements, 235 "expected %s \nbut got %s", test.expected, actualIssuesWithReplacements) 236 }) 237 } 238 }