envflag

Configure flags from the environment
Log | Files | Refs | README | LICENSE

flag_test.go (4106B)


      1 package envflag
      2 
      3 import (
      4 	"bytes"
      5 	"flag"
      6 	"os"
      7 	"testing"
      8 )
      9 
     10 func TestParseFlagSet(t *testing.T) {
     11 	tests := map[string]struct {
     12 		// Flag name
     13 		name string
     14 		// Default value
     15 		def string
     16 		// Flag command values
     17 		values []string
     18 		opts   []Option
     19 		// The environment
     20 		env map[string]string
     21 
     22 		expected string
     23 		usage    string
     24 	}{
     25 		"no flags no env default": {
     26 			name:     "testing-123",
     27 			def:      "defaultvalue",
     28 			expected: "defaultvalue",
     29 		},
     30 		"flags no env no default": {
     31 			name:     "testing-123",
     32 			values:   []string{"-testing-123", "passed"},
     33 			expected: "passed",
     34 		},
     35 		"no flags env": {
     36 			name:     "testing-123",
     37 			env:      map[string]string{"TESTING_123": "fromenv"},
     38 			expected: "fromenv",
     39 		},
     40 		"flags with no env": {
     41 			name:     "testing-123",
     42 			values:   []string{"-testing-123", "passed"},
     43 			expected: "passed",
     44 		},
     45 		"flags with env": {
     46 			// Flags take precedence
     47 			name:     "testing-123",
     48 			values:   []string{"-testing-123", "passed"},
     49 			env:      map[string]string{"TESTING_123": "fromenv"},
     50 			expected: "passed",
     51 		},
     52 		"no flags with env": {
     53 			name:     "testing-123",
     54 			env:      map[string]string{"TESTING_123": "fromenv"},
     55 			expected: "fromenv",
     56 		},
     57 		"flags with env and suffix": {
     58 			name:     "testing-123",
     59 			// Flags take precedence
     60 			values:   []string{"-testing-123", "passed"},
     61 			opts:     []Option{UsageSuffixer()},
     62 			env:      map[string]string{"TESTING_123": "fromenv"},
     63 			expected: "passed",
     64 		},
     65 		"no flags with env and suffix": {
     66 			name:     "testing-123",
     67 			values:   []string{"-h"},
     68 			opts:     []Option{UsageSuffixer()},
     69 			env:      map[string]string{"TESTING_123": "fromenv"},
     70 			expected: "fromenv",
     71 			usage: `Usage of test:
     72   -testing-123 string
     73     	usage [TESTING_123]
     74 `,
     75 		},
     76 		"usage prefix": {
     77 			name:     "testing-123",
     78 			values:   []string{"-h"},
     79 			opts:     []Option{UsagePrefixer()},
     80 			env:      map[string]string{"TESTING_123": "fromenv"},
     81 			expected: "fromenv",
     82 			usage: `Usage of test:
     83   -testing-123 string
     84     	[TESTING_123] usage
     85 `,
     86 		},
     87 		"usage updater": {
     88 			name:     "testing-123",
     89 			values:   []string{"-h"},
     90 			opts:     []Option{UsageUpdater(func(key,usage string)string{
     91 				return "thine usage"
     92 			})},
     93 			env:      map[string]string{"TESTING_123": "fromenv"},
     94 			expected: "fromenv",
     95 			usage: `Usage of test:
     96   -testing-123 string
     97     	thine usage
     98 `,
     99 		},
    100 		"a variety of characters": {
    101 			// Flags take precedence
    102 			name:     "tes_t.ing----123",
    103 			env:      map[string]string{"TES_T_ING_123": "fromenv"},
    104 			expected: "fromenv",
    105 		},
    106 		"prefixed no flag": {
    107 			// Flags take precedence
    108 			name:     "testing-123",
    109 			values:   []string{},
    110 			opts:     []Option{Prefix("APP_")},
    111 			env:      map[string]string{"APP_TESTING_123": "fromenv"},
    112 			expected: "fromenv",
    113 		},
    114 		"prefixed with flag": {
    115 			// Flags take precedence
    116 			name:     "testing-123",
    117 			values:   []string{"-testing-123", "passed"},
    118 			opts:     []Option{Prefix("APP_")},
    119 			env:      map[string]string{"APP_TESTING_123": "fromenv"},
    120 			expected: "passed",
    121 		},
    122 		"no flags custom env": {
    123 			name: "testing-123",
    124 			opts: []Option{Getenv(func(s string) string {
    125 				return "fake env"
    126 			})},
    127 			env:      map[string]string{"TESTING_123": "fromenv"},
    128 			expected: "fake env",
    129 		},
    130 		"no flags with converter": {
    131 			name:     "testing-123",
    132 			opts: []Option{FlagConverter(func(f string) string {
    133 				return "conVERTed"
    134 			})},
    135 			env:      map[string]string{"conVERTed": "fromenv"},
    136 			expected: "fromenv",
    137 		},
    138 	}
    139 
    140 	for name, tt := range tests {
    141 		t.Run(name, func(t *testing.T) {
    142 			fs := flag.NewFlagSet("test", flag.ContinueOnError)
    143 			buf := new(bytes.Buffer)
    144 			fs.SetOutput(buf)
    145 			for k, v := range tt.env {
    146 				os.Setenv(k, v)
    147 			}
    148 			defer func() {
    149 				for k := range tt.env {
    150 					os.Unsetenv(k)
    151 				}
    152 			}()
    153 			actual := fs.String(tt.name, tt.def, "usage")
    154 			ParseFlagSet(fs, tt.values, tt.opts...)
    155 			if *actual != tt.expected {
    156 				t.Errorf("got %q, want %q", *actual, tt.expected)
    157 			}
    158 			if tt.usage != buf.String() {
    159 				t.Errorf("got %q, want %q", buf.String(), tt.usage)
    160 			}
    161 		})
    162 	}
    163 
    164 }