1 package altsrc
2
3 import (
4 "flag"
5 "fmt"
6 "os"
7 "path/filepath"
8 "runtime"
9 "strings"
10 "testing"
11 "time"
12
13 "github.com/urfave/cli/v2"
14 )
15
16 type testApplyInputSource struct {
17 Flag FlagInputSourceExtension
18 FlagName string
19 FlagSetName string
20 Expected string
21 ContextValueString string
22 ContextValue flag.Value
23 EnvVarValue string
24 EnvVarName string
25 SourcePath string
26 MapValue interface{}
27 }
28
29 type racyInputSource struct {
30 *MapInputSource
31 }
32
33 func (ris *racyInputSource) isSet(name string) bool {
34 if _, ok := ris.MapInputSource.valueMap[name]; ok {
35 ris.MapInputSource.valueMap[name] = bogus{0}
36 }
37 return true
38 }
39
40 func TestGenericApplyInputSourceValue_Alias(t *testing.T) {
41 v := &Parser{"abc", "def"}
42 tis := testApplyInputSource{
43 Flag: NewGenericFlag(&cli.GenericFlag{Name: "test", Aliases: []string{"test_alias"}, Value: &Parser{}}),
44 FlagName: "test_alias",
45 MapValue: v,
46 }
47 c := runTest(t, tis)
48 expect(t, v, c.Generic("test_alias"))
49
50 c = runRacyTest(t, tis)
51 refute(t, v, c.Generic("test_alias"))
52 }
53
54 func TestGenericApplyInputSourceValue(t *testing.T) {
55 v := &Parser{"abc", "def"}
56 tis := testApplyInputSource{
57 Flag: NewGenericFlag(&cli.GenericFlag{Name: "test", Value: &Parser{}}),
58 FlagName: "test",
59 MapValue: v,
60 }
61 c := runTest(t, tis)
62 expect(t, v, c.Generic("test"))
63
64 c = runRacyTest(t, tis)
65 refute(t, v, c.Generic("test"))
66 }
67
68 func TestGenericApplyInputSourceValueError(t *testing.T) {
69 set := flag.NewFlagSet("", flag.ContinueOnError)
70 c := cli.NewContext(nil, set, nil)
71
72 testFlag := &GenericFlag{
73 GenericFlag: &cli.GenericFlag{
74 Name: "test",
75 Value: &cli.StringSlice{},
76 },
77 set: set,
78 }
79
80 err := testFlag.ApplyInputSourceValue(c, NewMapInputSource("", map[interface{}]interface{}{
81 "test": testFlag.Value,
82 }))
83 expect(t, err, fmt.Errorf("no such flag -test"))
84 }
85
86 func TestGenericApplyInputSourceMethodContextSet(t *testing.T) {
87 p := &Parser{"abc", "def"}
88 tis := testApplyInputSource{
89 Flag: NewGenericFlag(&cli.GenericFlag{Name: "test", Value: &Parser{}}),
90 FlagName: "test",
91 MapValue: &Parser{"efg", "hig"},
92 ContextValueString: p.String(),
93 }
94 c := runTest(t, tis)
95 expect(t, p, c.Generic("test"))
96
97 c = runRacyTest(t, tis)
98 refute(t, p, c.Generic("test"))
99 }
100
101 func TestGenericApplyInputSourceMethodEnvVarSet(t *testing.T) {
102 tis := testApplyInputSource{
103 Flag: NewGenericFlag(&cli.GenericFlag{
104 Name: "test",
105 Value: &Parser{},
106 EnvVars: []string{"TEST"},
107 }),
108 FlagName: "test",
109 MapValue: &Parser{"efg", "hij"},
110 EnvVarName: "TEST",
111 EnvVarValue: "abc,def",
112 }
113 c := runTest(t, tis)
114 expect(t, &Parser{"abc", "def"}, c.Generic("test"))
115
116 c = runRacyTest(t, tis)
117 refute(t, &Parser{"abc", "def"}, c.Generic("test"))
118 }
119
120 func TestStringSliceApplyInputSourceValue_Alias(t *testing.T) {
121 dest := cli.NewStringSlice()
122 tis := testApplyInputSource{
123 Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", Aliases: []string{"test_alias"}, Destination: dest}),
124 FlagName: "test_alias",
125 MapValue: []interface{}{"hello", "world"},
126 }
127 c := runTest(t, tis)
128 expect(t, c.StringSlice("test_alias"), []string{"hello", "world"})
129 expect(t, dest.Value(), []string{"hello", "world"})
130
131
132 dest = cli.NewStringSlice()
133 tis = testApplyInputSource{
134 Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", Aliases: []string{"test_alias"}, Destination: dest}),
135 FlagName: "test_alias",
136 MapValue: []interface{}{"hello", "world"},
137 }
138 c = runRacyTest(t, tis)
139 refute(t, c.StringSlice("test_alias"), []string{"hello", "world"})
140 refute(t, dest.Value(), []string{"hello", "world"})
141 }
142
143 func TestStringSliceApplyInputSourceValue(t *testing.T) {
144 dest := cli.NewStringSlice()
145 tis := testApplyInputSource{
146 Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", Destination: dest}),
147 FlagName: "test",
148 MapValue: []interface{}{"hello", "world"},
149 }
150 c := runTest(t, tis)
151 expect(t, c.StringSlice("test"), []string{"hello", "world"})
152 expect(t, dest.Value(), []string{"hello", "world"})
153
154
155 dest = cli.NewStringSlice()
156 tis = testApplyInputSource{
157 Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", Destination: dest}),
158 FlagName: "test",
159 MapValue: []interface{}{"hello", "world"},
160 }
161 c = runRacyTest(t, tis)
162 refute(t, c.StringSlice("test"), []string{"hello", "world"})
163 refute(t, dest.Value(), []string{"hello", "world"})
164 }
165
166 func TestStringSliceApplyInputSourceMethodContextSet(t *testing.T) {
167 dest := cli.NewStringSlice()
168 c := runTest(t, testApplyInputSource{
169 Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", Destination: dest}),
170 FlagName: "test",
171 MapValue: []interface{}{"hello", "world"},
172 ContextValueString: "ohno",
173 })
174 expect(t, c.StringSlice("test"), []string{"ohno"})
175 expect(t, dest.Value(), []string{"ohno"})
176 }
177
178 func TestStringSliceApplyInputSourceMethodEnvVarSet(t *testing.T) {
179 tis := testApplyInputSource{
180 Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", EnvVars: []string{"TEST"}}),
181 FlagName: "test",
182 MapValue: []interface{}{"hello", "world"},
183 EnvVarName: "TEST",
184 EnvVarValue: "oh,no",
185 }
186 c := runTest(t, tis)
187 expect(t, c.StringSlice("test"), []string{"oh", "no"})
188
189 c = runRacyTest(t, tis)
190 refute(t, c.StringSlice("test"), []string{"oh", "no"})
191 }
192
193 func TestIntSliceApplyInputSourceValue_Alias(t *testing.T) {
194 dest := cli.NewIntSlice()
195 tis := testApplyInputSource{
196 Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Aliases: []string{"test_alias"}, Destination: dest}),
197 FlagName: "test_alias",
198 MapValue: []interface{}{1, 2},
199 }
200 c := runTest(t, tis)
201 expect(t, c.IntSlice("test_alias"), []int{1, 2})
202 expect(t, dest.Value(), []int{1, 2})
203
204 dest = cli.NewIntSlice()
205 tis = testApplyInputSource{
206 Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Aliases: []string{"test_alias"}, Destination: dest}),
207 FlagName: "test_alias",
208 MapValue: []interface{}{1, 2},
209 }
210 c = runRacyTest(t, tis)
211 refute(t, c.IntSlice("test_alias"), []int{1, 2})
212 refute(t, dest.Value(), []int{1, 2})
213 }
214
215 func TestIntSliceApplyInputSourceValue(t *testing.T) {
216 dest := cli.NewIntSlice()
217 tis := testApplyInputSource{
218 Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Destination: dest}),
219 FlagName: "test",
220 MapValue: []interface{}{1, 2},
221 }
222 c := runTest(t, tis)
223 expect(t, c.IntSlice("test"), []int{1, 2})
224 expect(t, dest.Value(), []int{1, 2})
225
226
227 dest = cli.NewIntSlice()
228 tis = testApplyInputSource{
229 Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Destination: dest}),
230 FlagName: "test",
231 MapValue: []interface{}{1, 2},
232 }
233 c = runRacyTest(t, tis)
234 refute(t, c.IntSlice("test"), []int{1, 2})
235 refute(t, dest.Value(), []int{1, 2})
236 }
237
238 func TestIntSliceApplyInputSourceMethodContextSet(t *testing.T) {
239 dest := cli.NewIntSlice()
240 tis := testApplyInputSource{
241 Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Destination: dest}),
242 FlagName: "test",
243 MapValue: []interface{}{1, 2},
244 ContextValueString: "3",
245 }
246 c := runTest(t, tis)
247 expect(t, c.IntSlice("test"), []int{3})
248 expect(t, dest.Value(), []int{3})
249
250
251 dest = cli.NewIntSlice()
252 tis = testApplyInputSource{
253 Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Destination: dest}),
254 FlagName: "test",
255 MapValue: []interface{}{1, 2},
256 ContextValueString: "3",
257 }
258 c = runRacyTest(t, tis)
259 refute(t, c.IntSlice("test"), []int{3})
260 refute(t, dest.Value(), []int{3})
261 }
262
263 func TestIntSliceApplyInputSourceMethodEnvVarSet(t *testing.T) {
264 tis := testApplyInputSource{
265 Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", EnvVars: []string{"TEST"}}),
266 FlagName: "test",
267 MapValue: []interface{}{1, 2},
268 EnvVarName: "TEST",
269 EnvVarValue: "3,4",
270 }
271 c := runTest(t, tis)
272 expect(t, c.IntSlice("test"), []int{3, 4})
273
274 c = runRacyTest(t, tis)
275 refute(t, c.IntSlice("test"), []int{3, 4})
276 }
277
278 func TestInt64SliceFlagApplyInputSourceValue(t *testing.T) {
279 dest := cli.NewInt64Slice()
280 tis := testApplyInputSource{
281 Flag: NewInt64SliceFlag(&cli.Int64SliceFlag{Name: "test", Destination: dest}),
282 FlagName: "test",
283 MapValue: []interface{}{int64(1), int64(2)},
284 }
285 c := runTest(t, tis)
286 expect(t, c.Int64Slice("test"), []int64{1, 2})
287 expect(t, dest.Value(), []int64{1, 2})
288
289
290 dest = cli.NewInt64Slice()
291 tis = testApplyInputSource{
292 Flag: NewInt64SliceFlag(&cli.Int64SliceFlag{Name: "test", Destination: dest}),
293 FlagName: "test",
294 MapValue: []interface{}{int64(1), int64(2)},
295 }
296 c = runRacyTest(t, tis)
297 refute(t, c.IntSlice("test"), []int64{1, 2})
298 refute(t, dest.Value(), []int64{1, 2})
299 }
300
301 func TestInt64SliceFlagApplyInputSourceValueNotSet(t *testing.T) {
302 dest := cli.NewInt64Slice()
303 tis := testApplyInputSource{
304 Flag: NewInt64SliceFlag(&cli.Int64SliceFlag{Name: "test", Destination: dest}),
305 FlagName: "test1",
306 MapValue: []interface{}{int64(1), int64(2)},
307 }
308 c := runTest(t, tis)
309 expect(t, c.Int64Slice("test"), []int64{})
310 expect(t, dest.Value(), []int64{})
311 }
312
313 func TestFloat64SliceFlagApplyInputSourceValue(t *testing.T) {
314 dest := cli.NewFloat64Slice()
315 tis := testApplyInputSource{
316 Flag: NewFloat64SliceFlag(&cli.Float64SliceFlag{Name: "test", Destination: dest}),
317 FlagName: "test",
318 MapValue: []interface{}{float64(1.0), float64(2.1)},
319 }
320 c := runTest(t, tis)
321 expect(t, c.Float64Slice("test"), []float64{1.0, 2.1})
322 expect(t, dest.Value(), []float64{1.0, 2.1})
323
324
325 dest = cli.NewFloat64Slice()
326 tis = testApplyInputSource{
327 Flag: NewFloat64SliceFlag(&cli.Float64SliceFlag{Name: "test", Destination: dest}),
328 FlagName: "test",
329 MapValue: []interface{}{float64(1.0), float64(2.1)},
330 }
331 c = runRacyTest(t, tis)
332 refute(t, c.IntSlice("test"), []int64{1, 2})
333 refute(t, dest.Value(), []int64{1, 2})
334 }
335
336 func TestFloat64SliceFlagApplyInputSourceValueNotSet(t *testing.T) {
337 dest := cli.NewFloat64Slice()
338 tis := testApplyInputSource{
339 Flag: NewFloat64SliceFlag(&cli.Float64SliceFlag{Name: "test", Destination: dest}),
340 FlagName: "test1",
341 MapValue: []interface{}{float64(1.0), float64(2.1)},
342 }
343 c := runTest(t, tis)
344 expect(t, c.Float64Slice("test"), []float64{})
345 expect(t, dest.Value(), []float64{})
346 }
347
348 func TestFloat64SliceFlagApplyInputSourceValueInvalidType(t *testing.T) {
349 dest := cli.NewFloat64Slice()
350 tis := testApplyInputSource{
351 Flag: NewFloat64SliceFlag(&cli.Float64SliceFlag{Name: "test", Destination: dest}),
352 FlagName: "test",
353 MapValue: []interface{}{1, 2},
354 }
355 c := runTest(t, tis)
356 expect(t, c.Float64Slice("test"), []float64{})
357 expect(t, dest.Value(), []float64{})
358 }
359
360 func TestBoolApplyInputSourceMethodSet(t *testing.T) {
361 tis := testApplyInputSource{
362 Flag: NewBoolFlag(&cli.BoolFlag{Name: "test"}),
363 FlagName: "test",
364 MapValue: true,
365 }
366 c := runTest(t, tis)
367 expect(t, true, c.Bool("test"))
368
369 c = runRacyTest(t, tis)
370 refute(t, true, c.Bool("test"))
371 }
372
373 func TestBoolApplyInputSourceMethodSet_Alias(t *testing.T) {
374 tis := testApplyInputSource{
375 Flag: NewBoolFlag(&cli.BoolFlag{Name: "test", Aliases: []string{"test_alias"}}),
376 FlagName: "test_alias",
377 MapValue: true,
378 }
379 c := runTest(t, tis)
380 expect(t, true, c.Bool("test_alias"))
381
382 c = runRacyTest(t, tis)
383 refute(t, true, c.Bool("test_alias"))
384 }
385
386 func TestBoolApplyInputSourceMethodContextSet(t *testing.T) {
387 tis := testApplyInputSource{
388 Flag: NewBoolFlag(&cli.BoolFlag{Name: "test"}),
389 FlagName: "test",
390 MapValue: false,
391 ContextValueString: "true",
392 }
393 c := runTest(t, tis)
394 expect(t, true, c.Bool("test"))
395
396 c = runRacyTest(t, tis)
397 refute(t, true, c.Bool("test"))
398 }
399
400 func TestBoolApplyInputSourceMethodEnvVarSet(t *testing.T) {
401 tis := testApplyInputSource{
402 Flag: NewBoolFlag(&cli.BoolFlag{Name: "test", EnvVars: []string{"TEST"}}),
403 FlagName: "test",
404 MapValue: false,
405 EnvVarName: "TEST",
406 EnvVarValue: "true",
407 }
408 c := runTest(t, tis)
409 expect(t, true, c.Bool("test"))
410
411 c = runRacyTest(t, tis)
412 refute(t, true, c.Bool("test"))
413 }
414
415 func TestStringApplyInputSourceMethodSet_Alias(t *testing.T) {
416 tis := testApplyInputSource{
417 Flag: NewStringFlag(&cli.StringFlag{Name: "test", Aliases: []string{"test_alias"}}),
418 FlagName: "test_alias",
419 MapValue: "hello",
420 }
421 c := runTest(t, tis)
422 expect(t, "hello", c.String("test_alias"))
423
424 c = runRacyTest(t, tis)
425 refute(t, "hello", c.String("test_alias"))
426 }
427
428 func TestStringApplyInputSourceMethodSet(t *testing.T) {
429 tis := testApplyInputSource{
430 Flag: NewStringFlag(&cli.StringFlag{Name: "test"}),
431 FlagName: "test",
432 MapValue: "hello",
433 }
434 c := runTest(t, tis)
435 expect(t, "hello", c.String("test"))
436
437 c = runRacyTest(t, tis)
438 refute(t, "hello", c.String("test"))
439 }
440
441 func TestStringApplyInputSourceMethodContextSet(t *testing.T) {
442 tis := testApplyInputSource{
443 Flag: NewStringFlag(&cli.StringFlag{Name: "test"}),
444 FlagName: "test",
445 MapValue: "hello",
446 ContextValueString: "goodbye",
447 }
448 c := runTest(t, tis)
449 expect(t, "goodbye", c.String("test"))
450
451 c = runRacyTest(t, tis)
452 refute(t, "goodbye", c.String("test"))
453 }
454
455 func TestStringApplyInputSourceMethodEnvVarSet(t *testing.T) {
456 tis := testApplyInputSource{
457 Flag: NewStringFlag(&cli.StringFlag{Name: "test", EnvVars: []string{"TEST"}}),
458 FlagName: "test",
459 MapValue: "hello",
460 EnvVarName: "TEST",
461 EnvVarValue: "goodbye",
462 }
463 c := runTest(t, tis)
464 expect(t, "goodbye", c.String("test"))
465
466 c = runRacyTest(t, tis)
467 refute(t, "goodbye", c.String("test"))
468 }
469
470 func TestPathApplyInputSourceMethodSet_Alias(t *testing.T) {
471 tis := testApplyInputSource{
472 Flag: NewPathFlag(&cli.PathFlag{Name: "test", Aliases: []string{"test_alias"}}),
473 FlagName: "test_alias",
474 MapValue: "hello",
475 SourcePath: "/path/to/source/file",
476 }
477 c := runTest(t, tis)
478
479 expected := "/path/to/source/hello"
480 if runtime.GOOS == "windows" {
481 var err error
482
483
484 expected, err = filepath.Abs(expected)
485 if err != nil {
486 t.Fatal(err)
487 }
488 }
489 expect(t, expected, c.String("test_alias"))
490
491 c = runRacyTest(t, tis)
492 refute(t, expected, c.String("test_alias"))
493 }
494
495 func TestPathApplyInputSourceMethodSet(t *testing.T) {
496 tis := testApplyInputSource{
497 Flag: NewPathFlag(&cli.PathFlag{Name: "test"}),
498 FlagName: "test",
499 MapValue: "hello",
500 SourcePath: "/path/to/source/file",
501 }
502 c := runTest(t, tis)
503
504 expected := "/path/to/source/hello"
505 if runtime.GOOS == "windows" {
506 var err error
507
508
509 expected, err = filepath.Abs(expected)
510 if err != nil {
511 t.Fatal(err)
512 }
513 }
514 expect(t, expected, c.String("test"))
515
516 c = runRacyTest(t, tis)
517 refute(t, expected, c.String("test"))
518 }
519
520 func TestPathApplyInputSourceMethodContextSet(t *testing.T) {
521 tis := testApplyInputSource{
522 Flag: NewPathFlag(&cli.PathFlag{Name: "test"}),
523 FlagName: "test",
524 MapValue: "hello",
525 ContextValueString: "goodbye",
526 SourcePath: "/path/to/source/file",
527 }
528 c := runTest(t, tis)
529 expect(t, "goodbye", c.String("test"))
530
531 c = runRacyTest(t, tis)
532 refute(t, "goodbye", c.String("test"))
533 }
534
535 func TestPathApplyInputSourceMethodEnvVarSet(t *testing.T) {
536 tis := testApplyInputSource{
537 Flag: NewPathFlag(&cli.PathFlag{Name: "test", EnvVars: []string{"TEST"}}),
538 FlagName: "test",
539 MapValue: "hello",
540 EnvVarName: "TEST",
541 EnvVarValue: "goodbye",
542 SourcePath: "/path/to/source/file",
543 }
544 c := runTest(t, tis)
545 expect(t, "goodbye", c.String("test"))
546
547 c = runRacyTest(t, tis)
548 refute(t, "goodbye", c.String("test"))
549 }
550
551 func TestIntApplyInputSourceMethodSet_Alias(t *testing.T) {
552 tis := testApplyInputSource{
553 Flag: NewIntFlag(&cli.IntFlag{Name: "test", Aliases: []string{"test_alias"}}),
554 FlagName: "test_alias",
555 MapValue: 15,
556 }
557 c := runTest(t, tis)
558 expect(t, 15, c.Int("test_alias"))
559
560 c = runRacyTest(t, tis)
561 refute(t, 15, c.Int("test_alias"))
562 }
563
564 func TestIntApplyInputSourceMethodSet(t *testing.T) {
565 tis := testApplyInputSource{
566 Flag: NewIntFlag(&cli.IntFlag{Name: "test"}),
567 FlagName: "test",
568 MapValue: 15,
569 }
570 c := runTest(t, tis)
571 expect(t, 15, c.Int("test"))
572
573 c = runRacyTest(t, tis)
574 refute(t, 15, c.Int("test"))
575 }
576
577 func TestIntApplyInputSourceMethodSetNegativeValue(t *testing.T) {
578 tis := testApplyInputSource{
579 Flag: NewIntFlag(&cli.IntFlag{Name: "test"}),
580 FlagName: "test",
581 MapValue: -1,
582 }
583 c := runTest(t, tis)
584 expect(t, -1, c.Int("test"))
585
586 c = runRacyTest(t, tis)
587 refute(t, -1, c.Int("test"))
588 }
589
590 func TestIntApplyInputSourceMethodContextSet(t *testing.T) {
591 tis := testApplyInputSource{
592 Flag: NewIntFlag(&cli.IntFlag{Name: "test"}),
593 FlagName: "test",
594 MapValue: 15,
595 ContextValueString: "7",
596 }
597 c := runTest(t, tis)
598 expect(t, 7, c.Int("test"))
599
600 c = runRacyTest(t, tis)
601 refute(t, 7, c.Int("test"))
602 }
603
604 func TestIntApplyInputSourceMethodContextNotSet(t *testing.T) {
605 tis := testApplyInputSource{
606 Flag: NewIntFlag(&cli.IntFlag{Name: "test"}),
607 FlagName: "test1",
608 MapValue: 15,
609 ContextValueString: "7",
610 }
611 c := runTest(t, tis)
612 expect(t, 0, c.Int("test"))
613 }
614
615 func TestIntApplyInputSourceMethodContextSetInvalidType(t *testing.T) {
616 tis := testApplyInputSource{
617 Flag: NewIntFlag(&cli.IntFlag{Name: "test"}),
618 FlagName: "test",
619 ContextValueString: "d",
620 }
621 c := runTest(t, tis)
622 expect(t, 0, c.Int("test"))
623 }
624
625 func TestIntApplyInputSourceMethodEnvVarSet(t *testing.T) {
626 tis := testApplyInputSource{
627 Flag: NewIntFlag(&cli.IntFlag{Name: "test", EnvVars: []string{"TEST"}}),
628 FlagName: "test",
629 MapValue: 15,
630 EnvVarName: "TEST",
631 EnvVarValue: "12",
632 }
633 c := runTest(t, tis)
634 expect(t, 12, c.Int("test"))
635
636 c = runRacyTest(t, tis)
637 refute(t, 12, c.Int("test"))
638 }
639
640 func TestInt64ApplyInputSourceMethodSet_Alias(t *testing.T) {
641 tis := testApplyInputSource{
642 Flag: NewInt64Flag(&cli.Int64Flag{Name: "test", Aliases: []string{"test_alias"}}),
643 FlagName: "test_alias",
644 MapValue: int64(15),
645 }
646 c := runTest(t, tis)
647 expect(t, int64(15), c.Int64("test_alias"))
648
649 c = runRacyTest(t, tis)
650 refute(t, int64(15), c.Int64("test_alias"))
651 }
652
653 func TestInt64ApplyInputSourceMethodSet(t *testing.T) {
654 tis := testApplyInputSource{
655 Flag: NewInt64Flag(&cli.Int64Flag{Name: "test"}),
656 FlagName: "test",
657 MapValue: int64(15),
658 }
659 c := runTest(t, tis)
660 expect(t, int64(15), c.Int64("test"))
661
662 c = runRacyTest(t, tis)
663 refute(t, int64(15), c.Int("test"))
664 }
665
666 func TestInt64ApplyInputSourceMethodSetNegativeValue(t *testing.T) {
667 tis := testApplyInputSource{
668 Flag: NewInt64Flag(&cli.Int64Flag{Name: "test"}),
669 FlagName: "test",
670 MapValue: int64(-1),
671 }
672 c := runTest(t, tis)
673 expect(t, int64(-1), c.Int64("test"))
674
675 c = runRacyTest(t, tis)
676 refute(t, int64(-1), c.Int("test"))
677 }
678
679 func TestInt64ApplyInputSourceMethodContextSet(t *testing.T) {
680 tis := testApplyInputSource{
681 Flag: NewInt64Flag(&cli.Int64Flag{Name: "test"}),
682 FlagName: "test",
683 MapValue: 15,
684 ContextValueString: "7",
685 }
686 c := runTest(t, tis)
687 expect(t, int64(7), c.Int64("test"))
688
689 c = runRacyTest(t, tis)
690 refute(t, int64(7), c.Int64("test"))
691 }
692
693 func TestInt64ApplyInputSourceMethodContextNotSet(t *testing.T) {
694 tis := testApplyInputSource{
695 Flag: NewInt64Flag(&cli.Int64Flag{Name: "test"}),
696 FlagName: "test1",
697 MapValue: 15,
698 ContextValueString: "7",
699 }
700 c := runTest(t, tis)
701 expect(t, int64(0), c.Int64("test"))
702 }
703
704 func TestInt64ApplyInputSourceMethodContextSetInvalidType(t *testing.T) {
705 tis := testApplyInputSource{
706 Flag: NewInt64Flag(&cli.Int64Flag{Name: "test"}),
707 FlagName: "test",
708 ContextValueString: "d",
709 }
710 c := runTest(t, tis)
711 expect(t, int64(0), c.Int64("test"))
712 }
713
714 func TestInt64ApplyInputSourceMethodEnvVarSet(t *testing.T) {
715 tis := testApplyInputSource{
716 Flag: NewInt64Flag(&cli.Int64Flag{Name: "test", EnvVars: []string{"TEST"}}),
717 FlagName: "test",
718 MapValue: 15,
719 EnvVarName: "TEST",
720 EnvVarValue: "12",
721 }
722 c := runTest(t, tis)
723 expect(t, int64(12), c.Int64("test"))
724
725 c = runRacyTest(t, tis)
726 refute(t, int64(12), c.Int64("test"))
727 }
728
729 func TestUintApplyInputSourceMethodSet_Alias(t *testing.T) {
730 tis := testApplyInputSource{
731 Flag: NewUintFlag(&cli.UintFlag{Name: "test", Aliases: []string{"test_alias"}}),
732 FlagName: "test_alias",
733 MapValue: uint(15),
734 }
735 c := runTest(t, tis)
736 expect(t, uint(15), c.Uint("test_alias"))
737
738 c = runRacyTest(t, tis)
739 refute(t, uint(15), c.Uint("test_alias"))
740 }
741
742 func TestUintApplyInputSourceMethodSet(t *testing.T) {
743 tis := testApplyInputSource{
744 Flag: NewUintFlag(&cli.UintFlag{Name: "test"}),
745 FlagName: "test",
746 MapValue: uint(15),
747 }
748 c := runTest(t, tis)
749 expect(t, uint(15), c.Uint("test"))
750
751 c = runRacyTest(t, tis)
752 refute(t, uint(15), c.Uint("test"))
753 }
754
755 func TestUintApplyInputSourceMethodContextSet(t *testing.T) {
756 tis := testApplyInputSource{
757 Flag: NewUintFlag(&cli.UintFlag{Name: "test"}),
758 FlagName: "test",
759 MapValue: uint(15),
760 ContextValueString: "7",
761 }
762 c := runTest(t, tis)
763 expect(t, uint(7), c.Uint("test"))
764
765 c = runRacyTest(t, tis)
766 refute(t, uint(7), c.Uint("test"))
767 }
768
769 func TestUint64ApplyInputSourceMethodSet_Alias(t *testing.T) {
770 tis := testApplyInputSource{
771 Flag: NewUint64Flag(&cli.Uint64Flag{Name: "test", Aliases: []string{"test_alias"}}),
772 FlagName: "test_alias",
773 MapValue: uint64(15),
774 }
775 c := runTest(t, tis)
776 expect(t, uint64(15), c.Uint64("test_alias"))
777
778 c = runRacyTest(t, tis)
779 refute(t, uint64(15), c.Uint64("test_alias"))
780 }
781
782 func TestUint64ApplyInputSourceMethodSet(t *testing.T) {
783 tis := testApplyInputSource{
784 Flag: NewUint64Flag(&cli.Uint64Flag{Name: "test"}),
785 FlagName: "test",
786 MapValue: uint64(15),
787 }
788 c := runTest(t, tis)
789 expect(t, uint64(15), c.Uint64("test"))
790
791 c = runRacyTest(t, tis)
792 refute(t, uint64(15), c.Uint64("test"))
793 }
794
795 func TestUint64ApplyInputSourceMethodContextSet(t *testing.T) {
796 tis := testApplyInputSource{
797 Flag: NewUint64Flag(&cli.Uint64Flag{Name: "test"}),
798 FlagName: "test",
799 MapValue: uint64(15),
800 ContextValueString: "7",
801 }
802 c := runTest(t, tis)
803 expect(t, uint64(7), c.Uint64("test"))
804
805 c = runRacyTest(t, tis)
806 refute(t, uint64(7), c.Uint64("test"))
807 }
808
809 func TestUint64ApplyInputSourceMethodEnvVarSet(t *testing.T) {
810 tis := testApplyInputSource{
811 Flag: NewUint64Flag(&cli.Uint64Flag{Name: "test", EnvVars: []string{"TEST"}}),
812 FlagName: "test",
813 MapValue: uint64(15),
814 EnvVarName: "TEST",
815 EnvVarValue: "12",
816 }
817 c := runTest(t, tis)
818 expect(t, uint64(12), c.Uint64("test"))
819
820 c = runRacyTest(t, tis)
821 refute(t, uint64(12), c.Uint64("test"))
822 }
823
824 func TestDurationApplyInputSourceMethodSet_Alias(t *testing.T) {
825 tis := testApplyInputSource{
826 Flag: NewDurationFlag(&cli.DurationFlag{Name: "test", Aliases: []string{"test_alias"}}),
827 FlagName: "test_alias",
828 MapValue: 30 * time.Second,
829 }
830 c := runTest(t, tis)
831 expect(t, 30*time.Second, c.Duration("test_alias"))
832
833 c = runRacyTest(t, tis)
834 refute(t, 30*time.Second, c.Duration("test_alias"))
835 }
836
837 func TestDurationApplyInputSourceMethodSet(t *testing.T) {
838 tis := testApplyInputSource{
839 Flag: NewDurationFlag(&cli.DurationFlag{Name: "test"}),
840 FlagName: "test",
841 MapValue: 30 * time.Second,
842 }
843 c := runTest(t, tis)
844 expect(t, 30*time.Second, c.Duration("test"))
845
846 c = runRacyTest(t, tis)
847 refute(t, 30*time.Second, c.Duration("test"))
848 }
849
850 func TestDurationApplyInputSourceMethodSetNegativeValue(t *testing.T) {
851 tis := testApplyInputSource{
852 Flag: NewDurationFlag(&cli.DurationFlag{Name: "test"}),
853 FlagName: "test",
854 MapValue: -30 * time.Second,
855 }
856 c := runTest(t, tis)
857 expect(t, -30*time.Second, c.Duration("test"))
858
859 c = runRacyTest(t, tis)
860 refute(t, -30*time.Second, c.Duration("test"))
861 }
862
863 func TestDurationApplyInputSourceMethodContextSet(t *testing.T) {
864 tis := testApplyInputSource{
865 Flag: NewDurationFlag(&cli.DurationFlag{Name: "test"}),
866 FlagName: "test",
867 MapValue: 30 * time.Second,
868 ContextValueString: (15 * time.Second).String(),
869 }
870 c := runTest(t, tis)
871 expect(t, 15*time.Second, c.Duration("test"))
872
873 c = runRacyTest(t, tis)
874 refute(t, 15*time.Second, c.Duration("test"))
875 }
876
877 func TestDurationApplyInputSourceMethodEnvVarSet(t *testing.T) {
878 tis := testApplyInputSource{
879 Flag: NewDurationFlag(&cli.DurationFlag{Name: "test", EnvVars: []string{"TEST"}}),
880 FlagName: "test",
881 MapValue: 30 * time.Second,
882 EnvVarName: "TEST",
883 EnvVarValue: (15 * time.Second).String(),
884 }
885 c := runTest(t, tis)
886 expect(t, 15*time.Second, c.Duration("test"))
887
888 c = runRacyTest(t, tis)
889 refute(t, 15*time.Second, c.Duration("test"))
890 }
891
892 func TestFloat64ApplyInputSourceMethodSet(t *testing.T) {
893 tis := testApplyInputSource{
894 Flag: NewFloat64Flag(&cli.Float64Flag{Name: "test"}),
895 FlagName: "test",
896 MapValue: 1.3,
897 }
898 c := runTest(t, tis)
899 expect(t, 1.3, c.Float64("test"))
900
901 c = runRacyTest(t, tis)
902 refute(t, 1.3, c.Float64("test"))
903 }
904
905 func TestFloat64ApplyInputSourceMethodSetNegativeValue_Alias(t *testing.T) {
906 tis := testApplyInputSource{
907 Flag: NewFloat64Flag(&cli.Float64Flag{Name: "test", Aliases: []string{"test_alias"}}),
908 FlagName: "test_alias",
909 MapValue: -1.3,
910 }
911 c := runTest(t, tis)
912 expect(t, -1.3, c.Float64("test_alias"))
913
914 c = runRacyTest(t, tis)
915 refute(t, -1.3, c.Float64("test_alias"))
916 }
917
918 func TestFloat64ApplyInputSourceMethodSetNegativeValue(t *testing.T) {
919 tis := testApplyInputSource{
920 Flag: NewFloat64Flag(&cli.Float64Flag{Name: "test"}),
921 FlagName: "test",
922 MapValue: -1.3,
923 }
924 c := runTest(t, tis)
925 expect(t, -1.3, c.Float64("test"))
926
927 c = runRacyTest(t, tis)
928 refute(t, -1.3, c.Float64("test"))
929 }
930
931 func TestFloat64ApplyInputSourceMethodSetNegativeValueNotSet(t *testing.T) {
932 c := runTest(t, testApplyInputSource{
933 Flag: NewFloat64Flag(&cli.Float64Flag{Name: "test1"}),
934 FlagName: "test1",
935
936 })
937 expect(t, 0.0, c.Float64("test1"))
938 }
939
940 func TestFloat64ApplyInputSourceMethodContextSet(t *testing.T) {
941 tis := testApplyInputSource{
942 Flag: NewFloat64Flag(&cli.Float64Flag{Name: "test"}),
943 FlagName: "test",
944 MapValue: 1.3,
945 ContextValueString: fmt.Sprintf("%v", 1.4),
946 }
947 c := runTest(t, tis)
948 expect(t, 1.4, c.Float64("test"))
949
950 c = runRacyTest(t, tis)
951 refute(t, 1.4, c.Float64("test"))
952 }
953
954 func TestFloat64ApplyInputSourceMethodEnvVarSet(t *testing.T) {
955 tis := testApplyInputSource{
956 Flag: NewFloat64Flag(&cli.Float64Flag{Name: "test", EnvVars: []string{"TEST"}}),
957 FlagName: "test",
958 MapValue: 1.3,
959 EnvVarName: "TEST",
960 EnvVarValue: fmt.Sprintf("%v", 1.4),
961 }
962 c := runTest(t, tis)
963 expect(t, 1.4, c.Float64("test"))
964
965 c = runRacyTest(t, tis)
966 refute(t, 1.4, c.Float64("test"))
967 }
968
969 func runTest(t *testing.T, test testApplyInputSource) *cli.Context {
970 inputSource := &MapInputSource{
971 file: test.SourcePath,
972 valueMap: map[interface{}]interface{}{test.FlagName: test.MapValue},
973 }
974 set := flag.NewFlagSet(test.FlagSetName, flag.ContinueOnError)
975 c := cli.NewContext(nil, set, nil)
976 if test.EnvVarName != "" && test.EnvVarValue != "" {
977 _ = os.Setenv(test.EnvVarName, test.EnvVarValue)
978 defer os.Setenv(test.EnvVarName, "")
979 }
980
981 _ = test.Flag.Apply(set)
982 if test.ContextValue != nil {
983 f := set.Lookup(test.FlagName)
984 f.Value = test.ContextValue
985 }
986 if test.ContextValueString != "" {
987 _ = set.Set(test.FlagName, test.ContextValueString)
988 }
989 _ = test.Flag.ApplyInputSourceValue(c, inputSource)
990
991 return c
992 }
993
994 func runRacyTest(t *testing.T, test testApplyInputSource) *cli.Context {
995 set := flag.NewFlagSet(test.FlagSetName, flag.ContinueOnError)
996 c := cli.NewContext(nil, set, nil)
997 _ = test.Flag.ApplyInputSourceValue(c, &racyInputSource{
998 MapInputSource: &MapInputSource{
999 file: test.SourcePath,
1000 valueMap: map[interface{}]interface{}{test.FlagName: test.MapValue},
1001 },
1002 })
1003
1004 return c
1005 }
1006
1007 type Parser [2]string
1008
1009 func (p *Parser) Set(value string) error {
1010 parts := strings.Split(value, ",")
1011 if len(parts) != 2 {
1012 return fmt.Errorf("invalid format")
1013 }
1014
1015 (*p)[0] = parts[0]
1016 (*p)[1] = parts[1]
1017
1018 return nil
1019 }
1020
1021 func (p *Parser) String() string {
1022 return fmt.Sprintf("%s,%s", p[0], p[1])
1023 }
1024
1025 type bogus [1]uint
1026
View as plain text