1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package cobra
16
17 import (
18 "fmt"
19 "strings"
20 "testing"
21 )
22
23 func getCommand(args PositionalArgs, withValid bool) *Command {
24 c := &Command{
25 Use: "c",
26 Args: args,
27 Run: emptyRun,
28 }
29 if withValid {
30 c.ValidArgs = []string{"one", "two", "three"}
31 }
32 return c
33 }
34
35 func expectSuccess(output string, err error, t *testing.T) {
36 if output != "" {
37 t.Errorf("Unexpected output: %v", output)
38 }
39 if err != nil {
40 t.Fatalf("Unexpected error: %v", err)
41 }
42 }
43
44 func validOnlyWithInvalidArgs(err error, t *testing.T) {
45 if err == nil {
46 t.Fatal("Expected an error")
47 }
48 got := err.Error()
49 expected := `invalid argument "a" for "c"`
50 if got != expected {
51 t.Errorf("Expected: %q, got: %q", expected, got)
52 }
53 }
54
55 func noArgsWithArgs(err error, t *testing.T, arg string) {
56 if err == nil {
57 t.Fatal("Expected an error")
58 }
59 got := err.Error()
60 expected := `unknown command "` + arg + `" for "c"`
61 if got != expected {
62 t.Errorf("Expected: %q, got: %q", expected, got)
63 }
64 }
65
66 func minimumNArgsWithLessArgs(err error, t *testing.T) {
67 if err == nil {
68 t.Fatal("Expected an error")
69 }
70 got := err.Error()
71 expected := "requires at least 2 arg(s), only received 1"
72 if got != expected {
73 t.Fatalf("Expected %q, got %q", expected, got)
74 }
75 }
76
77 func maximumNArgsWithMoreArgs(err error, t *testing.T) {
78 if err == nil {
79 t.Fatal("Expected an error")
80 }
81 got := err.Error()
82 expected := "accepts at most 2 arg(s), received 3"
83 if got != expected {
84 t.Fatalf("Expected %q, got %q", expected, got)
85 }
86 }
87
88 func exactArgsWithInvalidCount(err error, t *testing.T) {
89 if err == nil {
90 t.Fatal("Expected an error")
91 }
92 got := err.Error()
93 expected := "accepts 2 arg(s), received 3"
94 if got != expected {
95 t.Fatalf("Expected %q, got %q", expected, got)
96 }
97 }
98
99 func rangeArgsWithInvalidCount(err error, t *testing.T) {
100 if err == nil {
101 t.Fatal("Expected an error")
102 }
103 got := err.Error()
104 expected := "accepts between 2 and 4 arg(s), received 1"
105 if got != expected {
106 t.Fatalf("Expected %q, got %q", expected, got)
107 }
108 }
109
110
111
112 func TestNoArgs(t *testing.T) {
113 c := getCommand(NoArgs, false)
114 output, err := executeCommand(c)
115 expectSuccess(output, err, t)
116 }
117
118 func TestNoArgs_WithArgs(t *testing.T) {
119 c := getCommand(NoArgs, false)
120 _, err := executeCommand(c, "one")
121 noArgsWithArgs(err, t, "one")
122 }
123
124 func TestNoArgs_WithValid_WithArgs(t *testing.T) {
125 c := getCommand(NoArgs, true)
126 _, err := executeCommand(c, "one")
127 noArgsWithArgs(err, t, "one")
128 }
129
130 func TestNoArgs_WithValid_WithInvalidArgs(t *testing.T) {
131 c := getCommand(NoArgs, true)
132 _, err := executeCommand(c, "a")
133 noArgsWithArgs(err, t, "a")
134 }
135
136 func TestNoArgs_WithValidOnly_WithInvalidArgs(t *testing.T) {
137 c := getCommand(MatchAll(OnlyValidArgs, NoArgs), true)
138 _, err := executeCommand(c, "a")
139 validOnlyWithInvalidArgs(err, t)
140 }
141
142
143
144 func TestOnlyValidArgs(t *testing.T) {
145 c := getCommand(OnlyValidArgs, true)
146 output, err := executeCommand(c, "one", "two")
147 expectSuccess(output, err, t)
148 }
149
150 func TestOnlyValidArgs_WithInvalidArgs(t *testing.T) {
151 c := getCommand(OnlyValidArgs, true)
152 _, err := executeCommand(c, "a")
153 validOnlyWithInvalidArgs(err, t)
154 }
155
156
157
158 func TestArbitraryArgs(t *testing.T) {
159 c := getCommand(ArbitraryArgs, false)
160 output, err := executeCommand(c, "a", "b")
161 expectSuccess(output, err, t)
162 }
163
164 func TestArbitraryArgs_WithValid(t *testing.T) {
165 c := getCommand(ArbitraryArgs, true)
166 output, err := executeCommand(c, "one", "two")
167 expectSuccess(output, err, t)
168 }
169
170 func TestArbitraryArgs_WithValid_WithInvalidArgs(t *testing.T) {
171 c := getCommand(ArbitraryArgs, true)
172 output, err := executeCommand(c, "a")
173 expectSuccess(output, err, t)
174 }
175
176 func TestArbitraryArgs_WithValidOnly_WithInvalidArgs(t *testing.T) {
177 c := getCommand(MatchAll(OnlyValidArgs, ArbitraryArgs), true)
178 _, err := executeCommand(c, "a")
179 validOnlyWithInvalidArgs(err, t)
180 }
181
182
183
184 func TestMinimumNArgs(t *testing.T) {
185 c := getCommand(MinimumNArgs(2), false)
186 output, err := executeCommand(c, "a", "b", "c")
187 expectSuccess(output, err, t)
188 }
189
190 func TestMinimumNArgs_WithValid(t *testing.T) {
191 c := getCommand(MinimumNArgs(2), true)
192 output, err := executeCommand(c, "one", "three")
193 expectSuccess(output, err, t)
194 }
195
196 func TestMinimumNArgs_WithValid__WithInvalidArgs(t *testing.T) {
197 c := getCommand(MinimumNArgs(2), true)
198 output, err := executeCommand(c, "a", "b")
199 expectSuccess(output, err, t)
200 }
201
202 func TestMinimumNArgs_WithValidOnly_WithInvalidArgs(t *testing.T) {
203 c := getCommand(MatchAll(OnlyValidArgs, MinimumNArgs(2)), true)
204 _, err := executeCommand(c, "a", "b")
205 validOnlyWithInvalidArgs(err, t)
206 }
207
208 func TestMinimumNArgs_WithLessArgs(t *testing.T) {
209 c := getCommand(MinimumNArgs(2), false)
210 _, err := executeCommand(c, "a")
211 minimumNArgsWithLessArgs(err, t)
212 }
213
214 func TestMinimumNArgs_WithLessArgs_WithValid(t *testing.T) {
215 c := getCommand(MinimumNArgs(2), true)
216 _, err := executeCommand(c, "one")
217 minimumNArgsWithLessArgs(err, t)
218 }
219
220 func TestMinimumNArgs_WithLessArgs_WithValid_WithInvalidArgs(t *testing.T) {
221 c := getCommand(MinimumNArgs(2), true)
222 _, err := executeCommand(c, "a")
223 minimumNArgsWithLessArgs(err, t)
224 }
225
226 func TestMinimumNArgs_WithLessArgs_WithValidOnly_WithInvalidArgs(t *testing.T) {
227 c := getCommand(MatchAll(OnlyValidArgs, MinimumNArgs(2)), true)
228 _, err := executeCommand(c, "a")
229 validOnlyWithInvalidArgs(err, t)
230 }
231
232
233
234 func TestMaximumNArgs(t *testing.T) {
235 c := getCommand(MaximumNArgs(3), false)
236 output, err := executeCommand(c, "a", "b")
237 expectSuccess(output, err, t)
238 }
239
240 func TestMaximumNArgs_WithValid(t *testing.T) {
241 c := getCommand(MaximumNArgs(2), true)
242 output, err := executeCommand(c, "one", "three")
243 expectSuccess(output, err, t)
244 }
245
246 func TestMaximumNArgs_WithValid_WithInvalidArgs(t *testing.T) {
247 c := getCommand(MaximumNArgs(2), true)
248 output, err := executeCommand(c, "a", "b")
249 expectSuccess(output, err, t)
250 }
251
252 func TestMaximumNArgs_WithValidOnly_WithInvalidArgs(t *testing.T) {
253 c := getCommand(MatchAll(OnlyValidArgs, MaximumNArgs(2)), true)
254 _, err := executeCommand(c, "a", "b")
255 validOnlyWithInvalidArgs(err, t)
256 }
257
258 func TestMaximumNArgs_WithMoreArgs(t *testing.T) {
259 c := getCommand(MaximumNArgs(2), false)
260 _, err := executeCommand(c, "a", "b", "c")
261 maximumNArgsWithMoreArgs(err, t)
262 }
263
264 func TestMaximumNArgs_WithMoreArgs_WithValid(t *testing.T) {
265 c := getCommand(MaximumNArgs(2), true)
266 _, err := executeCommand(c, "one", "three", "two")
267 maximumNArgsWithMoreArgs(err, t)
268 }
269
270 func TestMaximumNArgs_WithMoreArgs_WithValid_WithInvalidArgs(t *testing.T) {
271 c := getCommand(MaximumNArgs(2), true)
272 _, err := executeCommand(c, "a", "b", "c")
273 maximumNArgsWithMoreArgs(err, t)
274 }
275
276 func TestMaximumNArgs_WithMoreArgs_WithValidOnly_WithInvalidArgs(t *testing.T) {
277 c := getCommand(MatchAll(OnlyValidArgs, MaximumNArgs(2)), true)
278 _, err := executeCommand(c, "a", "b", "c")
279 validOnlyWithInvalidArgs(err, t)
280 }
281
282
283
284 func TestExactArgs(t *testing.T) {
285 c := getCommand(ExactArgs(3), false)
286 output, err := executeCommand(c, "a", "b", "c")
287 expectSuccess(output, err, t)
288 }
289
290 func TestExactArgs_WithValid(t *testing.T) {
291 c := getCommand(ExactArgs(3), true)
292 output, err := executeCommand(c, "three", "one", "two")
293 expectSuccess(output, err, t)
294 }
295
296 func TestExactArgs_WithValid_WithInvalidArgs(t *testing.T) {
297 c := getCommand(ExactArgs(3), true)
298 output, err := executeCommand(c, "three", "a", "two")
299 expectSuccess(output, err, t)
300 }
301
302 func TestExactArgs_WithValidOnly_WithInvalidArgs(t *testing.T) {
303 c := getCommand(MatchAll(OnlyValidArgs, ExactArgs(3)), true)
304 _, err := executeCommand(c, "three", "a", "two")
305 validOnlyWithInvalidArgs(err, t)
306 }
307
308 func TestExactArgs_WithInvalidCount(t *testing.T) {
309 c := getCommand(ExactArgs(2), false)
310 _, err := executeCommand(c, "a", "b", "c")
311 exactArgsWithInvalidCount(err, t)
312 }
313
314 func TestExactArgs_WithInvalidCount_WithValid(t *testing.T) {
315 c := getCommand(ExactArgs(2), true)
316 _, err := executeCommand(c, "three", "one", "two")
317 exactArgsWithInvalidCount(err, t)
318 }
319
320 func TestExactArgs_WithInvalidCount_WithValid_WithInvalidArgs(t *testing.T) {
321 c := getCommand(ExactArgs(2), true)
322 _, err := executeCommand(c, "three", "a", "two")
323 exactArgsWithInvalidCount(err, t)
324 }
325
326 func TestExactArgs_WithInvalidCount_WithValidOnly_WithInvalidArgs(t *testing.T) {
327 c := getCommand(MatchAll(OnlyValidArgs, ExactArgs(2)), true)
328 _, err := executeCommand(c, "three", "a", "two")
329 validOnlyWithInvalidArgs(err, t)
330 }
331
332
333
334 func TestRangeArgs(t *testing.T) {
335 c := getCommand(RangeArgs(2, 4), false)
336 output, err := executeCommand(c, "a", "b", "c")
337 expectSuccess(output, err, t)
338 }
339
340 func TestRangeArgs_WithValid(t *testing.T) {
341 c := getCommand(RangeArgs(2, 4), true)
342 output, err := executeCommand(c, "three", "one", "two")
343 expectSuccess(output, err, t)
344 }
345
346 func TestRangeArgs_WithValid_WithInvalidArgs(t *testing.T) {
347 c := getCommand(RangeArgs(2, 4), true)
348 output, err := executeCommand(c, "three", "a", "two")
349 expectSuccess(output, err, t)
350 }
351
352 func TestRangeArgs_WithValidOnly_WithInvalidArgs(t *testing.T) {
353 c := getCommand(MatchAll(OnlyValidArgs, RangeArgs(2, 4)), true)
354 _, err := executeCommand(c, "three", "a", "two")
355 validOnlyWithInvalidArgs(err, t)
356 }
357
358 func TestRangeArgs_WithInvalidCount(t *testing.T) {
359 c := getCommand(RangeArgs(2, 4), false)
360 _, err := executeCommand(c, "a")
361 rangeArgsWithInvalidCount(err, t)
362 }
363
364 func TestRangeArgs_WithInvalidCount_WithValid(t *testing.T) {
365 c := getCommand(RangeArgs(2, 4), true)
366 _, err := executeCommand(c, "two")
367 rangeArgsWithInvalidCount(err, t)
368 }
369
370 func TestRangeArgs_WithInvalidCount_WithValid_WithInvalidArgs(t *testing.T) {
371 c := getCommand(RangeArgs(2, 4), true)
372 _, err := executeCommand(c, "a")
373 rangeArgsWithInvalidCount(err, t)
374 }
375
376 func TestRangeArgs_WithInvalidCount_WithValidOnly_WithInvalidArgs(t *testing.T) {
377 c := getCommand(MatchAll(OnlyValidArgs, RangeArgs(2, 4)), true)
378 _, err := executeCommand(c, "a")
379 validOnlyWithInvalidArgs(err, t)
380 }
381
382
383
384 func TestRootTakesNoArgs(t *testing.T) {
385 rootCmd := &Command{Use: "root", Run: emptyRun}
386 childCmd := &Command{Use: "child", Run: emptyRun}
387 rootCmd.AddCommand(childCmd)
388
389 _, err := executeCommand(rootCmd, "illegal", "args")
390 if err == nil {
391 t.Fatal("Expected an error")
392 }
393
394 got := err.Error()
395 expected := `unknown command "illegal" for "root"`
396 if !strings.Contains(got, expected) {
397 t.Errorf("expected %q, got %q", expected, got)
398 }
399 }
400
401 func TestRootTakesArgs(t *testing.T) {
402 rootCmd := &Command{Use: "root", Args: ArbitraryArgs, Run: emptyRun}
403 childCmd := &Command{Use: "child", Run: emptyRun}
404 rootCmd.AddCommand(childCmd)
405
406 _, err := executeCommand(rootCmd, "legal", "args")
407 if err != nil {
408 t.Errorf("Unexpected error: %v", err)
409 }
410 }
411
412 func TestChildTakesNoArgs(t *testing.T) {
413 rootCmd := &Command{Use: "root", Run: emptyRun}
414 childCmd := &Command{Use: "child", Args: NoArgs, Run: emptyRun}
415 rootCmd.AddCommand(childCmd)
416
417 _, err := executeCommand(rootCmd, "child", "illegal", "args")
418 if err == nil {
419 t.Fatal("Expected an error")
420 }
421
422 got := err.Error()
423 expected := `unknown command "illegal" for "root child"`
424 if !strings.Contains(got, expected) {
425 t.Errorf("expected %q, got %q", expected, got)
426 }
427 }
428
429 func TestChildTakesArgs(t *testing.T) {
430 rootCmd := &Command{Use: "root", Run: emptyRun}
431 childCmd := &Command{Use: "child", Args: ArbitraryArgs, Run: emptyRun}
432 rootCmd.AddCommand(childCmd)
433
434 _, err := executeCommand(rootCmd, "child", "legal", "args")
435 if err != nil {
436 t.Fatalf("Unexpected error: %v", err)
437 }
438 }
439
440 func TestMatchAll(t *testing.T) {
441
442
443 pargs := MatchAll(
444 ExactArgs(3),
445 func(cmd *Command, args []string) error {
446 for _, arg := range args {
447 if len([]byte(arg)) != 2 {
448 return fmt.Errorf("expected to be exactly 2 bytes long")
449 }
450 }
451 return nil
452 },
453 )
454
455 testCases := map[string]struct {
456 args []string
457 fail bool
458 }{
459 "happy path": {
460 []string{"aa", "bb", "cc"},
461 false,
462 },
463 "incorrect number of args": {
464 []string{"aa", "bb", "cc", "dd"},
465 true,
466 },
467 "incorrect number of bytes in one arg": {
468 []string{"aa", "bb", "abc"},
469 true,
470 },
471 }
472
473 rootCmd := &Command{Use: "root", Args: pargs, Run: emptyRun}
474
475 for name, tc := range testCases {
476 t.Run(name, func(t *testing.T) {
477 _, err := executeCommand(rootCmd, tc.args...)
478 if err != nil && !tc.fail {
479 t.Errorf("unexpected: %v\n", err)
480 }
481 if err == nil && tc.fail {
482 t.Errorf("expected error")
483 }
484 })
485 }
486 }
487
488
489
490 func TestExactValidArgs(t *testing.T) {
491 c := getCommand(ExactValidArgs(3), true)
492 output, err := executeCommand(c, "three", "one", "two")
493 expectSuccess(output, err, t)
494 }
495
496 func TestExactValidArgs_WithInvalidCount(t *testing.T) {
497 c := getCommand(ExactValidArgs(2), false)
498 _, err := executeCommand(c, "three", "one", "two")
499 exactArgsWithInvalidCount(err, t)
500 }
501
502 func TestExactValidArgs_WithInvalidCount_WithInvalidArgs(t *testing.T) {
503 c := getCommand(ExactValidArgs(2), true)
504 _, err := executeCommand(c, "three", "a", "two")
505 exactArgsWithInvalidCount(err, t)
506 }
507
508 func TestExactValidArgs_WithInvalidArgs(t *testing.T) {
509 c := getCommand(ExactValidArgs(2), true)
510 _, err := executeCommand(c, "three", "a")
511 validOnlyWithInvalidArgs(err, t)
512 }
513
514
515
516
517
518 func TestLegacyArgsRootAcceptsArgs(t *testing.T) {
519 rootCmd := &Command{Use: "root", Args: nil, Run: emptyRun}
520
521 _, err := executeCommand(rootCmd, "somearg")
522 if err != nil {
523 t.Fatalf("Unexpected error: %v", err)
524 }
525 }
526
527
528
529
530 func TestLegacyArgsSubcmdAcceptsArgs(t *testing.T) {
531 rootCmd := &Command{Use: "root", Args: nil, Run: emptyRun}
532 childCmd := &Command{Use: "child", Args: nil, Run: emptyRun}
533 grandchildCmd := &Command{Use: "grandchild", Args: nil, Run: emptyRun}
534 rootCmd.AddCommand(childCmd)
535 childCmd.AddCommand(grandchildCmd)
536
537 _, err := executeCommand(rootCmd, "child", "somearg")
538 if err != nil {
539 t.Fatalf("Unexpected error: %v", err)
540 }
541 }
542
View as plain text