Source file
src/go/ast/directive_test.go
1
2
3
4
5 package ast
6
7 import (
8 "go/token"
9 "reflect"
10 "strings"
11 "testing"
12 )
13
14 func TestParseDirectiveMatchesIsDirective(t *testing.T) {
15 for _, tt := range isDirectiveTests {
16 want := tt.ok
17 if strings.HasPrefix(tt.in, "extern ") || strings.HasPrefix(tt.in, "export ") {
18
19
20 want = false
21 }
22
23 if _, ok := ParseDirective(0, "//"+tt.in); ok != want {
24 t.Errorf("ParseDirective(0, %q) = %v, want %v", "// "+tt.in, ok, want)
25 }
26 }
27 }
28
29 func TestParseDirective(t *testing.T) {
30 for _, test := range []struct {
31 name string
32 in string
33 pos token.Pos
34 want Directive
35 wantOK bool
36 }{
37 {
38 name: "valid",
39 in: "//go:generate stringer -type Op -trimprefix Op",
40 pos: 10,
41 want: Directive{
42 Tool: "go",
43 Name: "generate",
44 Args: "stringer -type Op -trimprefix Op",
45 Slash: 10,
46 ArgsPos: token.Pos(10 + len("//go:generate ")),
47 },
48 wantOK: true,
49 },
50 {
51 name: "no args",
52 in: "//go:build ignore",
53 pos: 20,
54 want: Directive{
55 Tool: "go",
56 Name: "build",
57 Args: "ignore",
58 Slash: 20,
59 ArgsPos: token.Pos(20 + len("//go:build ")),
60 },
61 wantOK: true,
62 },
63 {
64 name: "not a directive",
65 in: "// not a directive",
66 pos: 30,
67 wantOK: false,
68 },
69 {
70 name: "not a comment",
71 in: "go:generate",
72 pos: 40,
73 wantOK: false,
74 },
75 {
76 name: "empty",
77 in: "",
78 pos: 50,
79 wantOK: false,
80 },
81 {
82 name: "just slashes",
83 in: "//",
84 pos: 60,
85 wantOK: false,
86 },
87 {
88 name: "no name",
89 in: "//go:",
90 pos: 70,
91 wantOK: false,
92 },
93 {
94 name: "no tool",
95 in: "//:generate",
96 pos: 80,
97 wantOK: false,
98 },
99 {
100 name: "multiple spaces",
101 in: "//go:build foo bar",
102 pos: 90,
103 want: Directive{
104 Tool: "go",
105 Name: "build",
106 Args: "foo bar",
107 Slash: 90,
108 ArgsPos: token.Pos(90 + len("//go:build ")),
109 },
110 wantOK: true,
111 },
112 {
113 name: "trailing space",
114 in: "//go:build foo ",
115 pos: 100,
116 want: Directive{
117 Tool: "go",
118 Name: "build",
119 Args: "foo",
120 Slash: 100,
121 ArgsPos: token.Pos(100 + len("//go:build ")),
122 },
123 wantOK: true,
124 },
125 } {
126 t.Run(test.name, func(t *testing.T) {
127 got, gotOK := ParseDirective(test.pos, test.in)
128 if gotOK != test.wantOK {
129 t.Fatalf("ParseDirective(%q) ok = %v, want %v", test.in, gotOK, test.wantOK)
130 }
131 if !reflect.DeepEqual(got, test.want) {
132 t.Errorf("ParseDirective(%q) = %+v, want %+v", test.in, got, test.want)
133 }
134 })
135 }
136 }
137
138 func TestParseArgs(t *testing.T) {
139 for _, test := range []struct {
140 name string
141 in Directive
142 want []DirectiveArg
143 wantErr bool
144 }{
145 {
146 name: "simple",
147 in: Directive{
148 Tool: "go",
149 Name: "generate",
150 Args: "stringer -type Op",
151 ArgsPos: 10,
152 },
153 want: []DirectiveArg{
154 {"stringer", 10},
155 {"-type", token.Pos(10 + len("stringer "))},
156 {"Op", token.Pos(10 + len("stringer -type "))},
157 },
158 },
159 {
160 name: "quoted",
161 in: Directive{
162 Tool: "go",
163 Name: "generate",
164 Args: "\"foo bar\" baz",
165 ArgsPos: 10,
166 },
167 want: []DirectiveArg{
168 {"foo bar", 10},
169 {"baz", token.Pos(10 + len("\"foo bar\" "))},
170 },
171 },
172 {
173 name: "raw quoted",
174 in: Directive{
175 Tool: "go",
176 Name: "generate",
177 Args: "`foo bar` baz",
178 ArgsPos: 10,
179 },
180 want: []DirectiveArg{
181 {"foo bar", 10},
182 {"baz", token.Pos(10 + len("`foo bar` "))},
183 },
184 },
185 {
186 name: "escapes",
187 in: Directive{
188 Tool: "go",
189 Name: "generate",
190 Args: "\"foo\\U0001F60Abar\" `a\\tb`",
191 ArgsPos: 10,
192 },
193 want: []DirectiveArg{
194 {"foo😊bar", 10},
195 {"a\\tb", token.Pos(10 + len("\"foo\\U0001F60Abar\" "))},
196 },
197 },
198 {
199 name: "empty args",
200 in: Directive{
201 Tool: "go",
202 Name: "build",
203 Args: "",
204 ArgsPos: 10,
205 },
206 want: []DirectiveArg{},
207 },
208 {
209 name: "spaces",
210 in: Directive{
211 Tool: "go",
212 Name: "build",
213 Args: " foo bar ",
214 ArgsPos: 10,
215 },
216 want: []DirectiveArg{
217 {"foo", token.Pos(10 + len(" "))},
218 {"bar", token.Pos(10 + len(" foo "))},
219 },
220 },
221 {
222 name: "unterminated quote",
223 in: Directive{
224 Tool: "go",
225 Name: "generate",
226 Args: "`foo",
227 },
228 wantErr: true,
229 },
230 {
231 name: "no space after quote",
232 in: Directive{
233 Tool: "go",
234 Name: "generate",
235 Args: `"foo"bar`,
236 },
237 wantErr: true,
238 },
239 } {
240 t.Run(test.name, func(t *testing.T) {
241 got, err := test.in.ParseArgs()
242 if err != nil && !test.wantErr {
243 t.Errorf("got ParseArgs(%+v) = error %s; want %+v", test.in, err, test.want)
244 } else if err == nil && test.wantErr {
245 t.Errorf("got ParseArgs(%+v) = %+v; want error", test.in, got)
246 } else if err == nil && !reflect.DeepEqual(got, test.want) {
247 t.Errorf("got ParseArgs(%+v) = %+v; want %+v", test.in, got, test.want)
248 }
249 })
250 }
251 }
252
View as plain text