.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / honnef.co / go / tools@v0.1.1 / unused / unused_test.go
1 package unused
2
3 import (
4         "go/types"
5         "strings"
6         "testing"
7
8         "golang.org/x/tools/go/analysis/analysistest"
9 )
10
11 type expectation bool
12
13 const (
14         shouldBeUsed   = true
15         shouldBeUnused = false
16 )
17
18 func (exp expectation) String() string {
19         switch exp {
20         case shouldBeUsed:
21                 return "used"
22         case shouldBeUnused:
23                 return "unused"
24         default:
25                 panic("unreachable")
26         }
27 }
28
29 func check(t *testing.T, res *analysistest.Result) {
30         type key struct {
31                 file string
32                 line int
33         }
34         want := map[key]expectation{}
35         files := map[string]struct{}{}
36
37         isTest := false
38         for _, f := range res.Pass.Files {
39                 filename := res.Pass.Fset.Position(f.Pos()).Filename
40                 if strings.HasSuffix(filename, "_test.go") {
41                         isTest = true
42                         break
43                 }
44         }
45         for _, f := range res.Pass.Files {
46                 filename := res.Pass.Fset.Position(f.Pos()).Filename
47                 if !strings.HasSuffix(filename, ".go") {
48                         continue
49                 }
50                 files[filename] = struct{}{}
51                 for _, cgroup := range f.Comments {
52                 commentLoop:
53                         for _, c := range cgroup.List {
54                                 text := strings.TrimPrefix(c.Text, "//")
55                                 if text == c.Text {
56                                         continue // not a //-comment
57                                 }
58
59                                 fields := strings.Fields(text)
60                                 posn := res.Pass.Fset.Position(c.Pos())
61                                 for _, field := range fields {
62                                         switch field {
63                                         case "used", "unused", "used_test", "unused_test":
64                                         default:
65                                                 continue commentLoop
66                                         }
67                                 }
68                                 for _, field := range fields {
69                                         switch field {
70                                         case "used":
71                                                 if !isTest {
72                                                         want[key{posn.Filename, posn.Line}] = shouldBeUsed
73                                                 }
74                                         case "unused":
75                                                 if !isTest {
76                                                         want[key{posn.Filename, posn.Line}] = shouldBeUnused
77                                                 }
78                                         case "used_test":
79                                                 if isTest {
80                                                         want[key{posn.Filename, posn.Line}] = shouldBeUsed
81                                                 }
82                                         case "unused_test":
83                                                 if isTest {
84                                                         want[key{posn.Filename, posn.Line}] = shouldBeUnused
85                                                 }
86                                         }
87                                 }
88                         }
89                 }
90         }
91
92         checkObjs := func(objs []types.Object, state expectation) {
93                 for _, obj := range objs {
94                         posn := res.Pass.Fset.Position(obj.Pos())
95                         if _, ok := files[posn.Filename]; !ok {
96                                 continue
97                         }
98
99                         k := key{posn.Filename, posn.Line}
100                         exp, ok := want[k]
101                         if !ok {
102                                 t.Errorf("unexpected %s object at %s", state, posn)
103                                 continue
104                         }
105                         delete(want, k)
106                         if state != exp {
107                                 t.Errorf("object at %s should be %s but is %s", posn, exp, state)
108                         }
109                 }
110         }
111         ures := res.Result.(Result)
112         checkObjs(ures.Used, shouldBeUsed)
113         checkObjs(ures.Unused, shouldBeUnused)
114
115         for key, b := range want {
116                 var exp string
117                 if b {
118                         exp = "used"
119                 } else {
120                         exp = "unused "
121                 }
122                 t.Errorf("did not see expected %s object %s:%d", exp, key.file, key.line)
123         }
124 }
125
126 func TestAll(t *testing.T) {
127         dirs := []string{
128                 "tests",
129                 "alias",
130                 "anonymous",
131                 "blank",
132                 "cgo",
133                 "consts",
134                 "conversion",
135                 "cyclic",
136                 "defer",
137                 "elem",
138                 "embedded_call",
139                 "embedding",
140                 "embedding2",
141                 "exported_fields",
142                 "exported_fields_main",
143                 "exported_method_test",
144                 "fields",
145                 "functions",
146                 "ignored",
147                 "interfaces",
148                 "interfaces2",
149                 "linkname",
150                 "main",
151                 "mapslice",
152                 "methods",
153                 "named",
154                 "nested",
155                 "nocopy",
156                 "nocopy-main",
157                 "pointer-type-embedding",
158                 "quiet",
159                 "selectors",
160                 "switch_interface",
161                 "tests",
162                 "tests-main",
163                 "type-dedup",
164                 "type-dedup2",
165                 "type-dedup3",
166                 "types",
167                 "unused-argument",
168                 "unused_type",
169                 "variables",
170         }
171
172         results := analysistest.Run(t, analysistest.TestData(), Analyzer, dirs...)
173         for _, res := range results {
174                 check(t, res)
175         }
176 }