-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathAT012.go
118 lines (90 loc) · 3.01 KB
/
AT012.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package AT012
import (
"flag"
"go/ast"
"go/token"
"path/filepath"
"strings"
"github.com/bflad/tfproviderlint/passes/commentignore"
"github.com/bflad/tfproviderlint/passes/testaccfuncdecl"
"golang.org/x/tools/go/analysis"
)
const Doc = `check for test files containing multiple acceptance test function name prefixes
The AT012 analyzer reports likely incorrect uses of multiple TestAcc function
name prefixes up to the conventional underscore (_) prefix separator within
the same file. Typically, Terraform acceptance tests should use the same naming
prefix within one test file so testers can easily run all acceptance tests for
the file and not miss associated tests.
Optional parameters:
- ignored-filenames Comma-separated list of file names to ignore, defaults to none.`
const (
acceptanceTestNameSeparator = "_"
analyzerName = "AT012"
)
var (
ignoredFilenames string
)
var Analyzer = &analysis.Analyzer{
Name: analyzerName,
Doc: Doc,
Flags: parseFlags(),
Requires: []*analysis.Analyzer{
commentignore.Analyzer,
testaccfuncdecl.Analyzer,
},
Run: run,
}
func isFilenameIgnored(fileName string, fileNameList string) bool {
prefixes := strings.Split(fileNameList, ",")
for _, prefix := range prefixes {
if strings.HasPrefix(fileName, prefix) {
return true
}
}
return false
}
func parseFlags() flag.FlagSet {
var flags = flag.NewFlagSet(analyzerName, flag.ExitOnError)
flags.StringVar(&ignoredFilenames, "ignored-filenames", "", "Comma-separated list of file names to ignore")
return *flags
}
func run(pass *analysis.Pass) (interface{}, error) {
ignorer := pass.ResultOf[commentignore.Analyzer].(*commentignore.Ignorer)
funcDecls := pass.ResultOf[testaccfuncdecl.Analyzer].([]*ast.FuncDecl)
fileFuncDecls := make(map[*token.File][]*ast.FuncDecl)
for _, funcDecl := range funcDecls {
file := pass.Fset.File(funcDecl.Pos())
fileName := filepath.Base(file.Name())
if ignoredFilenames != "" && isFilenameIgnored(fileName, ignoredFilenames) {
continue
}
if ignorer.ShouldIgnore(analyzerName, funcDecl) {
continue
}
fileFuncDecls[file] = append(fileFuncDecls[file], funcDecl)
}
for file, funcDecls := range fileFuncDecls {
// Map to simplify checking
funcNamePrefixes := make(map[string]struct{})
for _, funcDecl := range funcDecls {
funcName := funcDecl.Name.Name
funcNamePrefixParts := strings.SplitN(funcName, acceptanceTestNameSeparator, 2)
// Ensure function name includes separator
if len(funcNamePrefixParts) != 2 || funcNamePrefixParts[0] == "" || funcNamePrefixParts[1] == "" {
continue
}
funcNamePrefix := funcNamePrefixParts[0]
funcNamePrefixes[funcNamePrefix] = struct{}{}
}
if len(funcNamePrefixes) <= 1 {
continue
}
// Easier to print map keys as slice
namePrefixes := make([]string, 0, len(funcNamePrefixes))
for k := range funcNamePrefixes {
namePrefixes = append(namePrefixes, k)
}
pass.Reportf(file.Pos(0), "%s: file contains multiple acceptance test name prefixes: %v", analyzerName, namePrefixes)
}
return nil, nil
}