diff --git a/completion_test.go b/completion_test.go new file mode 100644 index 0000000..453216d --- /dev/null +++ b/completion_test.go @@ -0,0 +1,94 @@ +package prompt + +import ( + "testing" + "reflect" +) + +func TestFormatShortSuggestion(t *testing.T) { + var scenarioTable = []struct{ + in []Suggest + expected []Suggest + max int + exWidth int + } { + { + in: []Suggest{ + {Text:"foo"}, + {Text:"bar"}, + {Text:"fuga"}, + }, + expected: []Suggest{ + {Text:" foo "}, + {Text:" bar "}, + {Text:" fuga "}, + }, + max: 100, + exWidth: 6, + }, + { + in: []Suggest{ + {Text:"apple", Description: "This is apple."}, + {Text:"banana", Description: "This is banana."}, + {Text:"coconut", Description: "This is coconut."}, + }, + expected: []Suggest{ + {Text:" apple ", Description: " This is apple. "}, + {Text:" banana ", Description: " This is banana. "}, + {Text:" coconut ", Description: " This is coconut. "}, + }, + max: 100, + exWidth: len(" apple " + " This is apple. "), + }, + { + in: []Suggest{ + {Text:"--all-namespaces", Description:"If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace."}, + {Text:"--allow-missing-template-keys", Description:"If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats."}, + {Text:"--export", Description:"If true, use 'export' for the resources. Exported resources are stripped of cluster-specific information."}, + {Text:"-f", Description:"Filename, directory, or URL to files identifying the resource to get from a server."}, + {Text:"--filename", Description:"Filename, directory, or URL to files identifying the resource to get from a server."}, + {Text:"--include-extended-apis", Description:"If true, include definitions of new APIs via calls to the API server. [default true]"}, + }, + expected: []Suggest{ + {Text:" --all-namespaces ", Description:" If present, li... "}, + {Text:" --allow-missing-template-keys ", Description:" If true, ignor... "}, + {Text:" --export ", Description:" If true, use '... "}, + {Text:" -f ", Description:" Filename, dire... "}, + {Text:" --filename ", Description:" Filename, dire... "}, + {Text:" --include-extended-apis ", Description:" If true, inclu... "}, + }, + max: 50, + exWidth: len(" --include-extended-apis " + " If true, includ..."), + }, + { + in: []Suggest{ + {Text:"--all-namespaces", Description:"If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace."}, + {Text:"--allow-missing-template-keys", Description:"If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats."}, + {Text:"--export", Description:"If true, use 'export' for the resources. Exported resources are stripped of cluster-specific information."}, + {Text:"-f", Description:"Filename, directory, or URL to files identifying the resource to get from a server."}, + {Text:"--filename", Description:"Filename, directory, or URL to files identifying the resource to get from a server."}, + {Text:"--include-extended-apis", Description:"If true, include definitions of new APIs via calls to the API server. [default true]"}, + }, + expected: []Suggest{ + {Text:" --all-namespaces ", Description:" If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace. "}, + {Text:" --allow-missing-template-keys ", Description:" If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. "}, + {Text:" --export ", Description:" If true, use 'export' for the resources. Exported resources are stripped of cluster-specific information. "}, + {Text:" -f ", Description:" Filename, directory, or URL to files identifying the resource to get from a server. "}, + {Text:" --filename ", Description:" Filename, directory, or URL to files identifying the resource to get from a server. "}, + {Text:" --include-extended-apis ", Description:" If true, include definitions of new APIs via calls to the API server. [default true] "}, + }, + max: 500, + exWidth: len(" --include-extended-apis " + " If true, include definitions of new APIs via calls to the API server. [default true] "), + }, + } + + for i, s := range scenarioTable { + actual, width := formatCompletions(s.in, s.max) + if width != s.exWidth { + t.Errorf("[scenario %d] Want %d but got %d\n", i, s.exWidth, width) + } + if !reflect.DeepEqual(actual, s.expected) { + t.Errorf("[scenario %d] Want %#v, but got %#v\n", i, s.expected, actual) + } + } +} diff --git a/prompt.go b/prompt.go index 5639084..831909f 100644 --- a/prompt.go +++ b/prompt.go @@ -31,6 +31,17 @@ type Exec struct { } func (p *Prompt) Run() { + // Logging + if os.Getenv(envEnableLog) != "true" { + log.SetOutput(ioutil.Discard) + } else if f, err := os.OpenFile(logfile, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666); err != nil { + log.SetOutput(ioutil.Discard) + } else { + defer f.Close() + log.SetOutput(f) + log.Println("[INFO] Logging is enabled.") + } + p.setUp() defer p.tearDown() @@ -177,6 +188,17 @@ func (p *Prompt) feed(b []byte) (shouldExit bool, exec *Exec) { } func (p *Prompt) Input() string { + // Logging + if os.Getenv(envEnableLog) != "true" { + log.SetOutput(ioutil.Discard) + } else if f, err := os.OpenFile(logfile, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666); err != nil { + log.SetOutput(ioutil.Discard) + } else { + defer f.Close() + log.SetOutput(f) + log.Println("[INFO] Logging is enabled.") + } + p.setUp() defer p.tearDown() @@ -206,17 +228,6 @@ func (p *Prompt) Input() string { } func (p *Prompt) setUp() { - // Logging - if os.Getenv(envEnableLog) != "true" { - log.SetOutput(ioutil.Discard) - } else if f, err := os.OpenFile(logfile, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666); err != nil { - log.SetOutput(ioutil.Discard) - } else { - defer f.Close() - log.SetOutput(f) - log.Println("[INFO] Logging is enabled.") - } - p.in.Setup() p.renderer.Setup() p.renderer.UpdateWinSize(p.in.GetWinSize())