// Copyright (c) 2016 Kelsey Hightower and others. All rights reserved. // Use of this source code is governed by the MIT License that can be found in // the LICENSE file. package envconfig import ( "bytes" "io" "io/ioutil" "log" "os" "strings" "testing" "text/tabwriter" ) var testUsageTableResult, testUsageListResult, testUsageCustomResult, testUsageBadFormatResult string func TestMain(m *testing.M) { // Load the expected test results from a text file data, err := ioutil.ReadFile("testdata/default_table.txt") if err != nil { log.Fatal(err) } testUsageTableResult = string(data) data, err = ioutil.ReadFile("testdata/default_list.txt") if err != nil { log.Fatal(err) } testUsageListResult = string(data) data, err = ioutil.ReadFile("testdata/custom.txt") if err != nil { log.Fatal(err) } testUsageCustomResult = string(data) data, err = ioutil.ReadFile("testdata/fault.txt") if err != nil { log.Fatal(err) } testUsageBadFormatResult = string(data) retCode := m.Run() os.Exit(retCode) } func compareUsage(want, got string, t *testing.T) { got = strings.Replace(got, " ", ".", -1) if want != got { shortest := len(want) if len(got) < shortest { shortest = len(got) } if len(want) != len(got) { t.Errorf("expected result length of %d, found %d", len(want), len(got)) } for i := 0; i < shortest; i++ { if want[i] != got[i] { t.Errorf("difference at index %d, expected '%c' (%v), found '%c' (%v)\n", i, want[i], want[i], got[i], got[i]) break } } t.Errorf("Complete Expected:\n'%s'\nComplete Found:\n'%s'\n", want, got) } } func TestUsageDefault(t *testing.T) { var s Specification os.Clearenv() save := os.Stdout r, w, _ := os.Pipe() os.Stdout = w err := Usage("env_config", &s) outC := make(chan string) // copy the output in a separate goroutine so printing can't block indefinitely go func() { var buf bytes.Buffer io.Copy(&buf, r) outC <- buf.String() }() w.Close() os.Stdout = save // restoring the real stdout out := <-outC if err != nil { t.Error(err.Error()) } compareUsage(testUsageTableResult, out, t) } func TestUsageTable(t *testing.T) { var s Specification os.Clearenv() buf := new(bytes.Buffer) tabs := tabwriter.NewWriter(buf, 1, 0, 4, ' ', 0) err := Usagef("env_config", &s, tabs, DefaultTableFormat) tabs.Flush() if err != nil { t.Error(err.Error()) } compareUsage(testUsageTableResult, buf.String(), t) } func TestUsageList(t *testing.T) { var s Specification os.Clearenv() buf := new(bytes.Buffer) err := Usagef("env_config", &s, buf, DefaultListFormat) if err != nil { t.Error(err.Error()) } compareUsage(testUsageListResult, buf.String(), t) } func TestUsageCustomFormat(t *testing.T) { var s Specification os.Clearenv() buf := new(bytes.Buffer) err := Usagef("env_config", &s, buf, "{{range .}}{{usage_key .}}={{usage_description .}}\n{{end}}") if err != nil { t.Error(err.Error()) } compareUsage(testUsageCustomResult, buf.String(), t) } func TestUsageUnknownKeyFormat(t *testing.T) { var s Specification unknownError := "template: envconfig:1:2: executing \"envconfig\" at <.UnknownKey>" os.Clearenv() buf := new(bytes.Buffer) err := Usagef("env_config", &s, buf, "{{.UnknownKey}}") if err == nil { t.Errorf("expected 'unknown key' error, but got no error") } if strings.Index(err.Error(), unknownError) == -1 { t.Errorf("expected '%s', but got '%s'", unknownError, err.Error()) } } func TestUsageBadFormat(t *testing.T) { var s Specification os.Clearenv() // If you don't use two {{}} then you get a lieteral buf := new(bytes.Buffer) err := Usagef("env_config", &s, buf, "{{range .}}{.Key}\n{{end}}") if err != nil { t.Error(err.Error()) } compareUsage(testUsageBadFormatResult, buf.String(), t) }