Skip to content

Commit 1309578

Browse files
committed
Refactor: move ginkgo containers logic to the handler
Cleanup the linter code by moving the ginkgo related logic (check for focus containers, and avoid test polution check), to the ginkgo linter package, in order to get cleaner main linter code.
1 parent 05ca79e commit 1309578

File tree

7 files changed

+382
-279
lines changed

7 files changed

+382
-279
lines changed

internal/ginkgohandler/dothandler.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package ginkgohandler
2+
3+
import (
4+
"go/ast"
5+
6+
"golang.org/x/tools/go/analysis"
7+
8+
"github.com/nunnatsa/ginkgolinter/types"
9+
)
10+
11+
// dotHandler is used when importing ginkgo with dot; i.e.
12+
// import . "github.com/onsi/ginkgo"
13+
type dotHandler struct{}
14+
15+
func (h dotHandler) HandleGinkgoSpecs(expr ast.Expr, config types.Config, pass *analysis.Pass) bool {
16+
return handleGinkgoSpecs(expr, config, pass, h)
17+
}
18+
19+
func (h dotHandler) getFocusContainerName(exp *ast.CallExpr) (bool, *ast.Ident) {
20+
if fun, ok := exp.Fun.(*ast.Ident); ok {
21+
return isFocusContainer(fun.Name), fun
22+
}
23+
return false, nil
24+
}
25+
26+
func (h dotHandler) isWrapContainer(exp *ast.CallExpr) bool {
27+
if fun, ok := exp.Fun.(*ast.Ident); ok {
28+
return isWrapContainer(fun.Name)
29+
}
30+
return false
31+
}
32+
33+
func (h dotHandler) isFocusSpec(exp ast.Expr) bool {
34+
id, ok := exp.(*ast.Ident)
35+
return ok && id.Name == focusSpec
36+
}

internal/ginkgohandler/ginkgoinfo.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package ginkgohandler
2+
3+
const ( // container names
4+
describe = "Describe"
5+
pdescribe = "PDescribe"
6+
xdescribe = "XDescribe"
7+
fdescribe = "FDescribe"
8+
9+
when = "When"
10+
pwhen = "PWhen"
11+
xwhen = "XWhen"
12+
fwhen = "FWhen"
13+
14+
contextContainer = "Context"
15+
pcontext = "PContext"
16+
xcontext = "XContext"
17+
fcontext = "FContext"
18+
19+
it = "It"
20+
pit = "PIt"
21+
xit = "XIt"
22+
fit = "FIt"
23+
24+
describeTable = "DescribeTable"
25+
pdescribeTable = "PDescribeTable"
26+
xdescribeTable = "XDescribeTable"
27+
fdescribeTable = "FDescribeTable"
28+
29+
entry = "Entry"
30+
pentry = "PEntry"
31+
xentry = "XEntry"
32+
fentry = "FEntry"
33+
)
34+
35+
func isFocusContainer(name string) bool {
36+
switch name {
37+
case fdescribe, fcontext, fwhen, fit, fdescribeTable, fentry:
38+
return true
39+
}
40+
return false
41+
}
42+
43+
func isContainer(name string) bool {
44+
switch name {
45+
case it, when, contextContainer, describe, describeTable, entry,
46+
pit, pwhen, pcontext, pdescribe, pdescribeTable, pentry,
47+
xit, xwhen, xcontext, xdescribe, xdescribeTable, xentry:
48+
return true
49+
}
50+
return isFocusContainer(name)
51+
}
52+
53+
func isWrapContainer(name string) bool {
54+
switch name {
55+
case when, contextContainer, describe,
56+
fwhen, fcontext, fdescribe,
57+
pwhen, pcontext, pdescribe,
58+
xwhen, xcontext, xdescribe:
59+
return true
60+
}
61+
62+
return false
63+
}

internal/ginkgohandler/handler.go

Lines changed: 21 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ package ginkgohandler
22

33
import (
44
"go/ast"
5+
6+
"golang.org/x/tools/go/analysis"
7+
8+
"github.com/nunnatsa/ginkgolinter/types"
59
)
610

711
const (
@@ -14,116 +18,31 @@ const (
1418
// Handler provide different handling, depend on the way ginkgo was imported, whether
1519
// in imported with "." name, custom name or without any name.
1620
type Handler interface {
17-
GetFocusContainerName(*ast.CallExpr) (bool, *ast.Ident)
18-
IsWrapContainer(*ast.CallExpr) bool
19-
IsFocusSpec(ident ast.Expr) bool
21+
HandleGinkgoSpecs(ast.Expr, types.Config, *analysis.Pass) bool
22+
getFocusContainerName(*ast.CallExpr) (bool, *ast.Ident)
23+
isWrapContainer(*ast.CallExpr) bool
24+
isFocusSpec(ident ast.Expr) bool
2025
}
2126

2227
// GetGinkgoHandler returns a ginkgor handler according to the way ginkgo was imported in the specific file
2328
func GetGinkgoHandler(file *ast.File) Handler {
2429
for _, imp := range file.Imports {
25-
if imp.Path.Value != importPath && imp.Path.Value != importPathV2 {
26-
continue
27-
}
30+
switch imp.Path.Value {
31+
32+
case importPath, importPathV2:
33+
switch name := imp.Name.String(); {
34+
case name == ".":
35+
return dotHandler{}
36+
case name == "<nil>": // import with no local name
37+
return nameHandler("ginkgo")
38+
default:
39+
return nameHandler(name)
40+
}
2841

29-
switch name := imp.Name.String(); {
30-
case name == ".":
31-
return dotHandler{}
32-
case name == "<nil>": // import with no local name
33-
return nameHandler("ginkgo")
3442
default:
35-
return nameHandler(name)
36-
}
37-
}
38-
39-
return nil // no ginkgo import; this file does not use ginkgo
40-
}
41-
42-
// dotHandler is used when importing ginkgo with dot; i.e.
43-
// import . "github.com/onsi/ginkgo"
44-
type dotHandler struct{}
45-
46-
func (h dotHandler) GetFocusContainerName(exp *ast.CallExpr) (bool, *ast.Ident) {
47-
if fun, ok := exp.Fun.(*ast.Ident); ok {
48-
return isFocusContainer(fun.Name), fun
49-
}
50-
return false, nil
51-
}
52-
53-
func (h dotHandler) IsWrapContainer(exp *ast.CallExpr) bool {
54-
if fun, ok := exp.Fun.(*ast.Ident); ok {
55-
return IsWrapContainer(fun.Name)
56-
}
57-
return false
58-
}
59-
60-
func (h dotHandler) IsFocusSpec(exp ast.Expr) bool {
61-
id, ok := exp.(*ast.Ident)
62-
return ok && id.Name == focusSpec
63-
}
64-
65-
// nameHandler is used when importing ginkgo without name; i.e.
66-
// import "github.com/onsi/ginkgo"
67-
//
68-
// or with a custom name; e.g.
69-
// import customname "github.com/onsi/ginkgo"
70-
type nameHandler string
71-
72-
func (h nameHandler) GetFocusContainerName(exp *ast.CallExpr) (bool, *ast.Ident) {
73-
if sel, ok := exp.Fun.(*ast.SelectorExpr); ok {
74-
if id, ok := sel.X.(*ast.Ident); ok && id.Name == string(h) {
75-
return isFocusContainer(sel.Sel.Name), sel.Sel
76-
}
77-
}
78-
return false, nil
79-
}
80-
81-
func (h nameHandler) IsWrapContainer(exp *ast.CallExpr) bool {
82-
if sel, ok := exp.Fun.(*ast.SelectorExpr); ok {
83-
if id, ok := sel.X.(*ast.Ident); ok && id.Name == string(h) {
84-
return IsWrapContainer(sel.Sel.Name)
85-
}
86-
}
87-
return false
88-
89-
}
90-
91-
func (h nameHandler) IsFocusSpec(exp ast.Expr) bool {
92-
if selExp, ok := exp.(*ast.SelectorExpr); ok {
93-
if x, ok := selExp.X.(*ast.Ident); ok && x.Name == string(h) {
94-
return selExp.Sel.Name == focusSpec
43+
continue
9544
}
9645
}
9746

98-
return false
99-
}
100-
101-
func isFocusContainer(name string) bool {
102-
switch name {
103-
case "FDescribe", "FContext", "FWhen", "FIt", "FDescribeTable", "FEntry":
104-
return true
105-
}
106-
return false
107-
}
108-
109-
func IsContainer(name string) bool {
110-
switch name {
111-
case "It", "When", "Context", "Describe", "DescribeTable", "Entry",
112-
"PIt", "PWhen", "PContext", "PDescribe", "PDescribeTable", "PEntry",
113-
"XIt", "XWhen", "XContext", "XDescribe", "XDescribeTable", "XEntry":
114-
return true
115-
}
116-
return isFocusContainer(name)
117-
}
118-
119-
func IsWrapContainer(name string) bool {
120-
switch name {
121-
case "When", "Context", "Describe",
122-
"FWhen", "FContext", "FDescribe",
123-
"PWhen", "PContext", "PDescribe",
124-
"XWhen", "XContext", "XDescribe":
125-
return true
126-
}
127-
128-
return false
47+
return nil
12948
}

internal/ginkgohandler/handler_test.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -113,38 +113,38 @@ func TestGetGinkgoHandler_no_ginkgo(t *testing.T) {
113113

114114
func TestDotHandler_GetFocusContainerName_happy(t *testing.T) {
115115
exp := &ast.CallExpr{
116-
Fun: ast.NewIdent("FIt"),
116+
Fun: ast.NewIdent(fit),
117117
}
118118

119119
h := dotHandler{}
120120

121-
isFocus, name := h.GetFocusContainerName(exp)
121+
isFocus, name := h.getFocusContainerName(exp)
122122

123123
if !isFocus {
124124
t.Error("h.GetFocusContainerName(exp) should return true")
125125
}
126126

127127
if name == nil {
128128
t.Error("should return valid ast.Ident object")
129-
} else if name.Name != "FIt" {
129+
} else if name.Name != fit {
130130
t.Error("function name should be 'FIt'")
131131
}
132132
}
133133

134134
func TestDotHandler_GetFocusContainerName_no_focus(t *testing.T) {
135135
exp := &ast.CallExpr{
136-
Fun: ast.NewIdent("It"),
136+
Fun: ast.NewIdent(it),
137137
}
138138

139139
h := dotHandler{}
140-
isFocus, name := h.GetFocusContainerName(exp)
140+
isFocus, name := h.getFocusContainerName(exp)
141141
if isFocus {
142142
t.Error("h.GetFocusContainerName(exp) should return false")
143143
}
144144

145145
if name == nil {
146146
t.Error("should return valid ast.Ident object")
147-
} else if name.Name != "It" {
147+
} else if name.Name != it {
148148
t.Error("function name should be 'It'")
149149
}
150150
}
@@ -154,13 +154,13 @@ func TestDotHandler_GetFocusContainerName_selector(t *testing.T) {
154154
Fun: &ast.SelectorExpr{
155155
Sel: ast.NewIdent("ginkgo"),
156156
X: &ast.CallExpr{
157-
Fun: ast.NewIdent("FIt"),
157+
Fun: ast.NewIdent(fit),
158158
},
159159
},
160160
}
161161

162162
h := dotHandler{}
163-
isFocus, name := h.GetFocusContainerName(exp)
163+
isFocus, name := h.getFocusContainerName(exp)
164164
if isFocus {
165165
t.Error("h.GetFocusContainerName(exp) should return false")
166166
}
@@ -173,52 +173,52 @@ func TestDotHandler_GetFocusContainerName_selector(t *testing.T) {
173173
func TestNameHandler_GetFocusContainerName_happy(t *testing.T) {
174174
exp := &ast.CallExpr{
175175
Fun: &ast.SelectorExpr{
176-
Sel: ast.NewIdent("FIt"),
176+
Sel: ast.NewIdent(fit),
177177
X: ast.NewIdent("ginkgo"),
178178
},
179179
}
180180

181181
h := nameHandler("ginkgo")
182-
isFocus, name := h.GetFocusContainerName(exp)
182+
isFocus, name := h.getFocusContainerName(exp)
183183
if !isFocus {
184184
t.Error("h.GetFocusContainerName(exp) should return true")
185185
}
186186

187187
if name == nil {
188188
t.Error("should return a valid ast.Ident object")
189-
} else if name.Name != "FIt" {
189+
} else if name.Name != fit {
190190
t.Error("function name should be 'FIt'")
191191
}
192192
}
193193

194194
func TestNameHandler_GetFocusContainerName_no_focus(t *testing.T) {
195195
exp := &ast.CallExpr{
196196
Fun: &ast.SelectorExpr{
197-
Sel: ast.NewIdent("It"),
197+
Sel: ast.NewIdent(it),
198198
X: ast.NewIdent("ginkgo"),
199199
},
200200
}
201201

202202
h := nameHandler("ginkgo")
203-
isFocus, name := h.GetFocusContainerName(exp)
203+
isFocus, name := h.getFocusContainerName(exp)
204204
if isFocus {
205205
t.Error("h.GetFocusContainerName(exp) should return false")
206206
}
207207

208208
if name == nil {
209209
t.Error("should return a valid ast.Ident object")
210-
} else if name.Name != "It" {
210+
} else if name.Name != it {
211211
t.Error("function name should be 'FIt'")
212212
}
213213
}
214214

215215
func TestNameHandler_GetFocusContainerName_ident(t *testing.T) {
216216
exp := &ast.CallExpr{
217-
Fun: ast.NewIdent("FIt"),
217+
Fun: ast.NewIdent(fit),
218218
}
219219

220220
h := nameHandler("ginkgo")
221-
isFocus, name := h.GetFocusContainerName(exp)
221+
isFocus, name := h.getFocusContainerName(exp)
222222
if isFocus {
223223
t.Error("h.GetFocusContainerName(exp) should return false")
224224
}

0 commit comments

Comments
 (0)