github.com/clysto/awgo@v0.15.0/config_test.go (about) 1 // 2 // Copyright (c) 2018 Dean Jackson <deanishe@deanishe.net> 3 // 4 // MIT Licence. See http://opensource.org/licenses/MIT 5 // 6 // Created on 2018-06-30 7 // 8 9 package aw 10 11 import ( 12 "fmt" 13 "os" 14 "testing" 15 "time" 16 ) 17 18 // TestConfigEnv verifies that Config holds the expected values. 19 func TestConfigEnv(t *testing.T) { 20 21 data := []struct { 22 name, x, key string 23 }{ 24 {"Version", tVersion, EnvVarVersion}, 25 {"Name", tName, EnvVarName}, 26 {"BundleID", tBundleID, EnvVarBundleID}, 27 {"UID", tUID, EnvVarUID}, 28 {"ConfigVersion", tAlfredVersion, EnvVarAlfredVersion}, 29 {"ConfigBuild", tAlfredBuild, EnvVarAlfredBuild}, 30 {"Theme", tTheme, EnvVarTheme}, 31 {"ThemeBackground", tThemeBackground, EnvVarThemeBG}, 32 {"ThemeSelectionBackground", tThemeSelectionBackground, EnvVarThemeSelectionBG}, 33 {"Preferences", tPreferences, EnvVarPreferences}, 34 {"Localhash", tLocalhash, EnvVarLocalhash}, 35 {"CacheDir", tCacheDir, EnvVarCacheDir}, 36 {"CacheDir", tDataDir, EnvVarDataDir}, 37 } 38 39 cfg := NewConfig(testEnv) 40 41 v := cfg.GetBool(EnvVarDebug) 42 if v != tDebug { 43 t.Errorf("bad Debug. Expected=%v, Got=%v", tDebug, v) 44 } 45 46 for _, td := range data { 47 s := cfg.Get(td.key) 48 if s != td.x { 49 t.Errorf("Bad %s. Expected=%v, Got=%v", td.name, td.x, s) 50 } 51 } 52 } 53 54 func TestGet(t *testing.T) { 55 env := MapEnv{ 56 "key": "value", 57 "key2": "value2", 58 "empty": "", 59 } 60 61 data := []struct { 62 key string 63 fb []string 64 out string 65 }{ 66 // valid 67 {"key", []string{}, "value"}, 68 {"key", []string{"value2"}, "value"}, 69 {"key2", []string{}, "value2"}, 70 {"key2", []string{"value"}, "value2"}, 71 // empty 72 {"empty", []string{}, ""}, 73 {"empty", []string{"dave"}, ""}, 74 // unset 75 {"key3", []string{}, ""}, 76 {"key3", []string{"bob"}, "bob"}, 77 } 78 79 cfg := NewConfig(env) 80 81 // Verify env is the same 82 for k, x := range env { 83 v := cfg.Get(k) 84 if v != x { 85 t.Errorf("Bad '%s'. Expected=%v, Got=%v", k, x, v) 86 } 87 } 88 89 // Test Get 90 for _, td := range data { 91 v := cfg.Get(td.key, td.fb...) 92 if v != td.out { 93 t.Errorf("Bad '%s'. Expected=%v, Got=%v", td.key, td.out, v) 94 } 95 96 } 97 } 98 99 func TestGetInt(t *testing.T) { 100 env := MapEnv{ 101 "one": "1", 102 "two": "2", 103 "zero": "0", 104 "float": "3.5", 105 "word": "henry", 106 "empty": "", 107 } 108 109 data := []struct { 110 key string 111 fb []int 112 out int 113 }{ 114 // numbers 115 {"one", []int{}, 1}, 116 {"two", []int{1}, 2}, 117 {"zero", []int{}, 0}, 118 {"zero", []int{2}, 0}, 119 // empty values 120 {"empty", []int{}, 0}, 121 {"empty", []int{5}, 5}, 122 // non-existent values 123 {"five", []int{}, 0}, 124 {"five", []int{5}, 5}, 125 // invalid values 126 {"word", []int{}, 0}, 127 {"word", []int{5}, 5}, 128 // floats 129 {"float", []int{}, 3}, 130 {"float", []int{5}, 3}, 131 } 132 133 cfg := NewConfig(env) 134 // Test GetInt 135 for _, td := range data { 136 v := cfg.GetInt(td.key, td.fb...) 137 if v != td.out { 138 t.Errorf("Bad '%s'. Expected=%v, Got=%v", td.key, td.out, v) 139 } 140 141 } 142 } 143 144 func TestGetFloat(t *testing.T) { 145 env := MapEnv{ 146 "one.three": "1.3", 147 "two": "2.0", 148 "zero": "0", 149 "empty": "", 150 "word": "henry", 151 } 152 153 data := []struct { 154 key string 155 fb []float64 156 out float64 157 }{ 158 // numbers 159 {"one.three", []float64{}, 1.3}, 160 {"two", []float64{1}, 2.0}, 161 {"zero", []float64{}, 0.0}, 162 {"zero", []float64{3.0}, 0.0}, 163 // empty 164 {"empty", []float64{}, 0.0}, 165 {"empty", []float64{5.2}, 5.2}, 166 // non-existent 167 {"five", []float64{}, 0.0}, 168 {"five", []float64{5.0}, 5.0}, 169 // invalid 170 {"word", []float64{}, 0.0}, 171 {"word", []float64{5.0}, 5.0}, 172 } 173 174 cfg := NewConfig(env) 175 // Test GetFloat 176 for _, td := range data { 177 v := cfg.GetFloat(td.key, td.fb...) 178 if v != td.out { 179 t.Errorf("Bad '%s'. Expected=%v, Got=%v", td.key, td.out, v) 180 } 181 182 } 183 } 184 185 func TestGetDuration(t *testing.T) { 186 env := MapEnv{ 187 "5mins": "5m", 188 "1hour": "1h", 189 "zero": "0", 190 "empty": "", 191 "word": "henry", 192 } 193 194 data := []struct { 195 key string 196 fb []time.Duration 197 out time.Duration 198 }{ 199 // valid 200 {"5mins", []time.Duration{}, time.Minute * 5}, 201 {"1hour", []time.Duration{time.Second * 1}, time.Hour * 1}, 202 // zero 203 {"zero", []time.Duration{}, 0}, 204 {"zero", []time.Duration{time.Second * 2}, 0}, 205 // empty 206 {"empty", []time.Duration{}, 0}, 207 {"empty", []time.Duration{time.Second * 2}, time.Second * 2}, 208 // unset 209 {"missing", []time.Duration{}, 0}, 210 {"missing", []time.Duration{time.Second * 2}, time.Second * 2}, 211 // invalid 212 {"word", []time.Duration{}, 0}, 213 {"word", []time.Duration{time.Second * 5}, time.Second * 5}, 214 } 215 216 cfg := NewConfig(env) 217 218 // Test GetDuration 219 for _, td := range data { 220 v := cfg.GetDuration(td.key, td.fb...) 221 if v != td.out { 222 t.Errorf("Bad '%s'. Expected=%v, Got=%v", td.key, td.out, v) 223 } 224 225 } 226 } 227 228 func TestGetBool(t *testing.T) { 229 env := MapEnv{ 230 "empty": "", 231 "t": "t", 232 "f": "f", 233 "1": "1", 234 "0": "0", 235 "true": "true", 236 "false": "false", 237 "word": "nonsense", 238 } 239 240 data := []struct { 241 key string 242 fb []bool 243 out bool 244 }{ 245 // valid 246 {"t", []bool{}, true}, 247 {"f", []bool{true}, false}, 248 {"1", []bool{}, true}, 249 {"0", []bool{true}, false}, 250 {"true", []bool{}, true}, 251 {"false", []bool{true}, false}, 252 // empty 253 {"empty", []bool{}, false}, 254 {"empty", []bool{true}, true}, 255 // missing 256 {"missing", []bool{}, false}, 257 {"missing", []bool{true}, true}, 258 // invalid 259 {"word", []bool{}, false}, 260 {"word", []bool{true}, true}, 261 } 262 263 cfg := NewConfig(env) 264 265 // Test GetBool 266 for _, td := range data { 267 v := cfg.GetBool(td.key, td.fb...) 268 if v != td.out { 269 t.Errorf("Bad '%s'. Expected=%v, Got=%v", td.key, td.out, v) 270 } 271 272 } 273 } 274 275 func TestStringify(t *testing.T) { 276 data := []struct { 277 in interface{} 278 out string 279 }{ 280 {"", ""}, 281 {"plaintext", "plaintext"}, 282 {"A whole sentence", "A whole sentence"}, 283 {true, "true"}, 284 {false, "false"}, 285 {0, "0"}, 286 {1, "1"}, 287 {4.1, "4.1"}, 288 {time.Second * 60, "1m0s"}, 289 } 290 291 for _, td := range data { 292 s := stringify(td.in) 293 if s != td.out { 294 t.Errorf("Bad String for %#v. Expected=%v, Got=%v", td.in, td.out, s) 295 } 296 297 } 298 } 299 300 // Basic usage of Config.Get. Returns an empty string if variable is unset. 301 func ExampleConfig_Get() { 302 // Set some test variables 303 os.Setenv("TEST_NAME", "Bob Smith") 304 os.Setenv("TEST_ADDRESS", "7, Dreary Lane") 305 306 // New Config from environment 307 cfg := NewConfig() 308 309 fmt.Println(cfg.Get("TEST_NAME")) 310 fmt.Println(cfg.Get("TEST_ADDRESS")) 311 fmt.Println(cfg.Get("TEST_NONEXISTENT")) // unset variable 312 313 // GetString is a synonym 314 fmt.Println(cfg.GetString("TEST_NAME")) 315 316 // Output: 317 // Bob Smith 318 // 7, Dreary Lane 319 // 320 // Bob Smith 321 322 unsetEnv("TEST_NAME", "TEST_ADDRESS") 323 } 324 325 // The fallback value is returned if the variable is unset. 326 func ExampleConfig_Get_fallback() { 327 // Set some test variables 328 os.Setenv("TEST_NAME", "Bob Smith") 329 os.Setenv("TEST_ADDRESS", "7, Dreary Lane") 330 os.Setenv("TEST_EMAIL", "") 331 332 // New Config from environment 333 cfg := NewConfig() 334 335 fmt.Println(cfg.Get("TEST_NAME", "default name")) // fallback ignored 336 fmt.Println(cfg.Get("TEST_ADDRESS", "default address")) // fallback ignored 337 fmt.Println(cfg.Get("TEST_EMAIL", "test@example.com")) // fallback ignored (var is empty, not unset) 338 fmt.Println(cfg.Get("TEST_NONEXISTENT", "hi there!")) // unset variable 339 340 // Output: 341 // Bob Smith 342 // 7, Dreary Lane 343 // 344 // hi there! 345 346 unsetEnv("TEST_NAME", "TEST_ADDRESS", "TEST_EMAIL") 347 } 348 349 // Getting int values with and without fallbacks. 350 func ExampleConfig_GetInt() { 351 // Set some test variables 352 os.Setenv("PORT", "3000") 353 os.Setenv("PING_INTERVAL", "") 354 355 // New Config from environment 356 cfg := NewConfig() 357 358 fmt.Println(cfg.GetInt("PORT")) 359 fmt.Println(cfg.GetInt("PORT", 5000)) // fallback is ignored 360 fmt.Println(cfg.GetInt("PING_INTERVAL")) // returns zero value 361 fmt.Println(cfg.GetInt("PING_INTERVAL", 60)) // returns fallback 362 // Output: 363 // 3000 364 // 3000 365 // 0 366 // 60 367 368 unsetEnv("PORT", "PING_INTERVAL") 369 } 370 371 // Strings are parsed to floats using strconv.ParseFloat(). 372 func ExampleConfig_GetFloat() { 373 // Set some test variables 374 os.Setenv("TOTAL_SCORE", "172.3") 375 os.Setenv("AVERAGE_SCORE", "7.54") 376 377 // New Config from environment 378 cfg := NewConfig() 379 380 fmt.Printf("%0.2f\n", cfg.GetFloat("TOTAL_SCORE")) 381 fmt.Printf("%0.1f\n", cfg.GetFloat("AVERAGE_SCORE")) 382 fmt.Println(cfg.GetFloat("NON_EXISTENT_SCORE", 120.5)) 383 // Output: 384 // 172.30 385 // 7.5 386 // 120.5 387 388 unsetEnv("TOTAL_SCORE", "AVERAGE_SCORE") 389 } 390 391 // Durations are parsed using time.ParseDuration. 392 func ExampleConfig_GetDuration() { 393 // Set some test variables 394 os.Setenv("DURATION_NAP", "20m") 395 os.Setenv("DURATION_EGG", "5m") 396 os.Setenv("DURATION_BIG_EGG", "") 397 os.Setenv("DURATION_MATCH", "1.5h") 398 399 // New Config from environment 400 cfg := NewConfig() 401 402 // returns time.Duration 403 fmt.Println(cfg.GetDuration("DURATION_NAP")) 404 fmt.Println(cfg.GetDuration("DURATION_EGG") * 2) 405 // fallback with unset variable 406 fmt.Println(cfg.GetDuration("DURATION_POWERNAP", time.Minute*45)) 407 // or an empty one 408 fmt.Println(cfg.GetDuration("DURATION_BIG_EGG", time.Minute*10)) 409 fmt.Println(cfg.GetDuration("DURATION_MATCH").Minutes()) 410 411 // Output: 412 // 20m0s 413 // 10m0s 414 // 45m0s 415 // 10m0s 416 // 90 417 418 unsetEnv( 419 "DURATION_NAP", 420 "DURATION_EGG", 421 "DURATION_BIG_EGG", 422 "DURATION_MATCH", 423 ) 424 } 425 426 // Strings are parsed using strconv.ParseBool(). 427 func ExampleConfig_GetBool() { 428 429 // Set some test variables 430 os.Setenv("LIKE_PEAS", "t") 431 os.Setenv("LIKE_CARROTS", "true") 432 os.Setenv("LIKE_BEANS", "1") 433 os.Setenv("LIKE_LIVER", "f") 434 os.Setenv("LIKE_TOMATOES", "0") 435 os.Setenv("LIKE_BVB", "false") 436 os.Setenv("LIKE_BAYERN", "FALSE") 437 438 // New Config from environment 439 cfg := NewConfig() 440 441 // strconv.ParseBool() supports many formats 442 fmt.Println(cfg.GetBool("LIKE_PEAS")) 443 fmt.Println(cfg.GetBool("LIKE_CARROTS")) 444 fmt.Println(cfg.GetBool("LIKE_BEANS")) 445 fmt.Println(cfg.GetBool("LIKE_LIVER")) 446 fmt.Println(cfg.GetBool("LIKE_TOMATOES")) 447 fmt.Println(cfg.GetBool("LIKE_BVB")) 448 fmt.Println(cfg.GetBool("LIKE_BAYERN")) 449 450 // Fallback 451 fmt.Println(cfg.GetBool("LIKE_BEER", true)) 452 453 // Output: 454 // true 455 // true 456 // true 457 // false 458 // false 459 // false 460 // false 461 // true 462 463 unsetEnv( 464 "LIKE_PEAS", 465 "LIKE_CARROTS", 466 "LIKE_BEANS", 467 "LIKE_LIVER", 468 "LIKE_TOMATOES", 469 "LIKE_BVB", 470 "LIKE_BAYERN", 471 ) 472 } 473 474 func unsetEnv(keys ...string) { 475 for _, key := range keys { 476 os.Unsetenv(key) 477 } 478 }