route/vendor/github.com/posener/complete/complete_test.go

327 lines
5.6 KiB
Go

package complete
import (
"bytes"
"os"
"sort"
"strings"
"testing"
)
func TestCompleter_Complete(t *testing.T) {
t.Parallel()
initTests()
c := Command{
Sub: Commands{
"sub1": {
Flags: Flags{
"-flag1": PredictAnything,
"-flag2": PredictNothing,
},
},
"sub2": {
Flags: Flags{
"-flag2": PredictNothing,
"-flag3": PredictSet("opt1", "opt2", "opt12"),
},
Args: PredictFiles("*.md"),
},
},
Flags: Flags{
"-o": PredictFiles("*.txt"),
},
GlobalFlags: Flags{
"-h": PredictNothing,
"-global1": PredictAnything,
},
}
cmp := New("cmd", c)
tests := []struct {
args string
want []string
}{
{
args: "",
want: []string{"sub1", "sub2"},
},
{
args: "-",
want: []string{"-h", "-global1", "-o"},
},
{
args: "-h ",
want: []string{"sub1", "sub2"},
},
{
args: "-global1 ", // global1 is known follow flag
want: []string{},
},
{
args: "sub",
want: []string{"sub1", "sub2"},
},
{
args: "sub1",
want: []string{"sub1"},
},
{
args: "sub2",
want: []string{"sub2"},
},
{
args: "sub1 ",
want: []string{},
},
{
args: "sub1 -",
want: []string{"-flag1", "-flag2", "-h", "-global1"},
},
{
args: "sub2 ",
want: []string{"./", "dir/", "outer/", "readme.md"},
},
{
args: "sub2 ./",
want: []string{"./", "./readme.md", "./dir/", "./outer/"},
},
{
args: "sub2 re",
want: []string{"readme.md"},
},
{
args: "sub2 ./re",
want: []string{"./readme.md"},
},
{
args: "sub2 -flag2 ",
want: []string{"./", "dir/", "outer/", "readme.md"},
},
{
args: "sub1 -fl",
want: []string{"-flag1", "-flag2"},
},
{
args: "sub1 -flag1",
want: []string{"-flag1"},
},
{
args: "sub1 -flag1 ",
want: []string{}, // flag1 is unknown follow flag
},
{
args: "sub1 -flag2 -",
want: []string{"-flag1", "-flag2", "-h", "-global1"},
},
{
args: "-no-such-flag",
want: []string{},
},
{
args: "-no-such-flag ",
want: []string{"sub1", "sub2"},
},
{
args: "-no-such-flag -",
want: []string{"-h", "-global1", "-o"},
},
{
args: "no-such-command",
want: []string{},
},
{
args: "no-such-command ",
want: []string{"sub1", "sub2"},
},
{
args: "-o ",
want: []string{"a.txt", "b.txt", "c.txt", ".dot.txt", "./", "dir/", "outer/"},
},
{
args: "-o ./no-su",
want: []string{},
},
{
args: "-o ./",
want: []string{"./a.txt", "./b.txt", "./c.txt", "./.dot.txt", "./", "./dir/", "./outer/"},
},
{
args: "-o=./",
want: []string{"./a.txt", "./b.txt", "./c.txt", "./.dot.txt", "./", "./dir/", "./outer/"},
},
{
args: "-o .",
want: []string{"./a.txt", "./b.txt", "./c.txt", "./.dot.txt", "./", "./dir/", "./outer/"},
},
{
args: "-o ./b",
want: []string{"./b.txt"},
},
{
args: "-o=./b",
want: []string{"./b.txt"},
},
{
args: "-o ./read",
want: []string{},
},
{
args: "-o=./read",
want: []string{},
},
{
args: "-o ./readme.md",
want: []string{},
},
{
args: "-o ./readme.md ",
want: []string{"sub1", "sub2"},
},
{
args: "-o=./readme.md ",
want: []string{"sub1", "sub2"},
},
{
args: "-o sub2 -flag3 ",
want: []string{"opt1", "opt2", "opt12"},
},
{
args: "-o sub2 -flag3 opt1",
want: []string{"opt1", "opt12"},
},
{
args: "-o sub2 -flag3 opt",
want: []string{"opt1", "opt2", "opt12"},
},
}
for _, tt := range tests {
t.Run(tt.args, func(t *testing.T) {
got := runComplete(cmp, tt.args)
sort.Strings(tt.want)
sort.Strings(got)
if !equalSlices(got, tt.want) {
t.Errorf("failed '%s'\ngot: %s\nwant: %s", t.Name(), got, tt.want)
}
})
}
}
func TestCompleter_Complete_SharedPrefix(t *testing.T) {
t.Parallel()
initTests()
c := Command{
Sub: Commands{
"status": {
Flags: Flags{
"-f3": PredictNothing,
},
},
"job": {
Sub: Commands{
"status": {
Flags: Flags{
"-f4": PredictNothing,
},
},
},
},
},
Flags: Flags{
"-o": PredictFiles("*.txt"),
},
GlobalFlags: Flags{
"-h": PredictNothing,
"-global1": PredictAnything,
},
}
cmp := New("cmd", c)
tests := []struct {
args string
want []string
}{
{
args: "",
want: []string{"status", "job"},
},
{
args: "-",
want: []string{"-h", "-global1", "-o"},
},
{
args: "j",
want: []string{"job"},
},
{
args: "job ",
want: []string{"status"},
},
{
args: "job -",
want: []string{"-h", "-global1"},
},
{
args: "job status ",
want: []string{},
},
{
args: "job status -",
want: []string{"-f4", "-h", "-global1"},
},
}
for _, tt := range tests {
t.Run(tt.args, func(t *testing.T) {
got := runComplete(cmp, tt.args)
sort.Strings(tt.want)
sort.Strings(got)
if !equalSlices(got, tt.want) {
t.Errorf("failed '%s'\ngot = %s\nwant: %s", t.Name(), got, tt.want)
}
})
}
}
// runComplete runs the complete login for test purposes
// it gets the complete struct and command line arguments and returns
// the complete options
func runComplete(c *Complete, args string) (completions []string) {
os.Setenv(envComplete, "cmd "+args)
b := bytes.NewBuffer(nil)
c.Out = b
c.Complete()
completions = parseOutput(b.String())
return
}
func parseOutput(output string) []string {
lines := strings.Split(output, "\n")
options := []string{}
for _, l := range lines {
if l != "" {
options = append(options, l)
}
}
return options
}
func equalSlices(a, b []string) bool {
if len(a) != len(b) {
return false
}
for i := range a {
if a[i] != b[i] {
return false
}
}
return true
}