1
0
mirror of https://github.com/mgechev/revive.git synced 2025-10-30 23:37:49 +02:00

Fix #245 File header rule: index out of range [0] with length 0

This commit is contained in:
dshemin
2019-11-28 01:29:59 +07:00
parent 88015ccf8e
commit 3c93b9c1a4
7 changed files with 78 additions and 32 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.idea
golinter
revive
vendor

View File

@@ -0,0 +1 @@
package fixtures // MATCH /the file doesn't have an appropriate header/

View File

@@ -51,25 +51,34 @@ type lintFileHeader struct {
onFailure func(lint.Failure)
}
var (
multiRegexp = regexp.MustCompile("^/\\*")
singleRegexp = regexp.MustCompile("^//")
)
func (w lintFileHeader) Visit(_ ast.Node) ast.Visitor {
g := w.fileAst.Comments[0]
failure := lint.Failure{
Node: w.fileAst,
Confidence: 1,
Failure: "the file doesn't have an appropriate header",
}
if len(w.fileAst.Comments) == 0 {
w.onFailure(failure)
return nil
}
g := w.fileAst.Comments[0]
if g == nil {
w.onFailure(failure)
return nil
}
multi := regexp.MustCompile("^/\\*")
single := regexp.MustCompile("^//")
comment := ""
for _, c := range g.List {
text := c.Text
if multi.Match([]byte(text)) {
if multiRegexp.Match([]byte(text)) {
text = text[2 : len(text)-2]
} else if single.Match([]byte(text)) {
} else if singleRegexp.Match([]byte(text)) {
text = text[2:]
}
comment += text

View File

@@ -27,4 +27,20 @@ func TestLintFileHeader(t *testing.T) {
testRule(t, "lint-file-header5", &rule.FileHeaderRule{}, &lint.RuleConfig{
Arguments: []interface{}{"^\\sfoo.*bar$"},
})
testRule(t, "lint-file-header6", &rule.FileHeaderRule{}, &lint.RuleConfig{
Arguments: []interface{}{"foobar"},
})
}
func BenchmarkLintFileHeader(b *testing.B) {
benchRule(b, "lint-file-header1", &rule.FileHeaderRule{}, &lint.RuleConfig{
Arguments: []interface{}{"foobar"},
})
//var t *testing.T
//for i := 0; i <= b.N; i++ {
// testRule(t, "lint-file-header1", &rule.FileHeaderRule{}, &lint.RuleConfig{
// Arguments: []interface{}{"foobar"},
// })
//}
}

View File

@@ -17,10 +17,7 @@ func TestImportsBlacklist(t *testing.T) {
func BenchmarkImportsBlacklist(b *testing.B) {
args := []interface{}{"crypto/md5", "crypto/sha1"}
var t *testing.T
for i := 0; i <= b.N; i++ {
testRule(t, "imports-blacklist", &rule.ImportsBlacklistRule{}, &lint.RuleConfig{
Arguments: args,
})
}
benchRule(b, "imports-blacklist", &rule.ImportsBlacklistRule{}, &lint.RuleConfig{
Arguments: args,
})
}

View File

@@ -11,8 +11,5 @@ func TestUnusedParam(t *testing.T) {
}
func BenchmarkUnusedParam(b *testing.B) {
var t *testing.T
for i := 0; i <= b.N; i++ {
testRule(t, "unused-param", &rule.UnusedParamRule{})
}
benchRule(b, "unused-param", &rule.UnusedParamRule{})
}

View File

@@ -6,7 +6,6 @@ import (
"fmt"
"go/ast"
"go/parser"
"go/printer"
"go/token"
"go/types"
"io/ioutil"
@@ -19,14 +18,42 @@ import (
"github.com/pkg/errors"
)
const fixtureBasePath = "../fixtures/"
func benchRule(b *testing.B, filename string, rule lint.Rule, config ...*lint.RuleConfig) {
fixturePath := fixtureBasePath + filename + ".go"
stat, err := os.Stat(fixturePath)
if err != nil {
b.Fatalf("Cannot get file info for %s: %v", rule.Name(), err)
}
c := map[string]lint.RuleConfig{}
if config != nil {
c[rule.Name()] = *config[0]
}
l := lint.New(func(file string) ([]byte, error) {
return ioutil.ReadFile(fixtureBasePath + file)
})
for i := 0; i < b.N; i++ {
ps, err := l.Lint([][]string{{stat.Name()}}, []lint.Rule{rule}, lint.Config{
Rules: c,
})
if err != nil {
b.Fatalf("Unexpected error: %s", err)
}
for range ps {
}
}
}
func testRule(t *testing.T, filename string, rule lint.Rule, config ...*lint.RuleConfig) {
baseDir := "../fixtures/"
filename = filename + ".go"
src, err := ioutil.ReadFile(baseDir + filename)
fixturePath := fixtureBasePath + filename + ".go"
src, err := ioutil.ReadFile(fixturePath)
if err != nil {
t.Fatalf("Bad filename path in test for %s: %v", rule.Name(), err)
}
stat, err := os.Stat(baseDir + filename)
stat, err := os.Stat(fixturePath)
if err != nil {
t.Fatalf("Cannot get file info for %s: %v", rule.Name(), err)
}
@@ -35,10 +62,16 @@ func testRule(t *testing.T, filename string, rule lint.Rule, config ...*lint.Rul
c[rule.Name()] = *config[0]
}
if parseInstructions(t, filename, src) == nil {
assertSuccess(t, baseDir, stat, []lint.Rule{rule}, c)
err := assertSuccess(t, fixtureBasePath, stat, []lint.Rule{rule}, c)
if err != nil {
t.Fatalf("Cannot invoke 'assertSuccess' for %s: %v", rule.Name(), err)
}
return
}
assertFailures(t, baseDir, stat, src, []lint.Rule{rule}, c)
err = assertFailures(t, fixtureBasePath, stat, src, []lint.Rule{rule}, c)
if err != nil {
t.Fatalf("Cannot invoke 'assertFailures' for %s: %v", rule.Name(), err)
}
}
func assertSuccess(t *testing.T, baseDir string, fi os.FileInfo, rules []lint.Rule, config map[string]lint.RuleConfig) error {
@@ -46,7 +79,7 @@ func assertSuccess(t *testing.T, baseDir string, fi os.FileInfo, rules []lint.Ru
return ioutil.ReadFile(baseDir + file)
})
ps, err := l.Lint([][]string{[]string{fi.Name()}}, rules, lint.Config{
ps, err := l.Lint([][]string{{fi.Name()}}, rules, lint.Config{
Rules: config,
})
if err != nil {
@@ -73,7 +106,7 @@ func assertFailures(t *testing.T, baseDir string, fi os.FileInfo, src []byte, ru
return errors.Errorf("Test file %v does not have instructions", fi.Name())
}
ps, err := l.Lint([][]string{[]string{fi.Name()}}, rules, lint.Config{
ps, err := l.Lint([][]string{{fi.Name()}}, rules, lint.Config{
Rules: config,
})
if err != nil {
@@ -200,14 +233,6 @@ func extractReplacement(line string) (string, bool) {
return line[a+len(start) : b], true
}
func render(fset *token.FileSet, x interface{}) string {
var buf bytes.Buffer
if err := printer.Fprint(&buf, fset, x); err != nil {
panic(err)
}
return buf.String()
}
func srcLine(src []byte, p token.Position) string {
// Run to end of line in both directions if not at line start/end.
lo, hi := p.Offset, p.Offset+1