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  }