94 lines
3.9 KiB
Go
94 lines
3.9 KiB
Go
package commandkit
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestCompletionConsumerInShells(t *testing.T) {
|
|
if os.Getenv("COMMANDKIT_COMPLETION_SHELLS") != "1" {
|
|
t.Skip("set COMMANDKIT_COMPLETION_SHELLS=1 to run shell completion checks")
|
|
}
|
|
dir := t.TempDir()
|
|
app := filepath.Join(dir, "probe")
|
|
build := exec.Command("go", "build", "-o", app, "./testdata/completion")
|
|
if output, err := build.CombinedOutput(); err != nil {
|
|
t.Fatalf("build completion fixture: %v\n%s", err, output)
|
|
}
|
|
if err := os.Mkdir(filepath.Join(dir, "partial dir"), 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(dir, "partial file"), nil, 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
tests := []struct {
|
|
name, line string
|
|
want []string
|
|
directory bool
|
|
}{
|
|
{"canonical command", "probe ru", []string{"run"}, false},
|
|
{"entered alias", "probe shortcut --format=ya", []string{"shortcut", "--format=yaml"}, false},
|
|
{"choice", "probe run --format=te", []string{"run", "--format=text"}, false},
|
|
{"no file fallback", `probe run --format=./partial\ f`, []string{"run", "--format=./partial f"}, false},
|
|
{"separated file", `probe run --config ./partial\ f`, []string{"run", "--config", "./partial file"}, false},
|
|
{"attached file", `probe run --config=./partial\ f`, []string{"run", "--config=./partial file"}, false},
|
|
{"short attached file", `probe run -c./partial\ f`, []string{"run", "-c./partial file"}, false},
|
|
{"short cluster equals file", `probe run -sc=./partial\ f`, []string{"run", "-sc=./partial file"}, false},
|
|
{"separated directory", "probe run --directory ./partial", []string{"run", "--directory", "./partial dir"}, true},
|
|
{"attached directory", "probe run --directory=./partial", []string{"run", "--directory=./partial dir"}, true},
|
|
{"empty operand", "probe run ", []string{"run", "alpha"}, false},
|
|
{"leading dash", "probe run --for", []string{"run", "--format"}, false},
|
|
}
|
|
for _, shell := range []string{"bash", "zsh", "fish"} {
|
|
generator := exec.Command(app, "completion", shell)
|
|
script, err := generator.CombinedOutput()
|
|
if err != nil {
|
|
t.Fatalf("generate %s script: %v\n%s", shell, err, script)
|
|
}
|
|
scriptPath := filepath.Join(dir, shell+".completion")
|
|
if err := os.WriteFile(scriptPath, script, 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(shell+"/"+tc.name, func(t *testing.T) {
|
|
log := filepath.Join(dir, "log")
|
|
if err := os.WriteFile(log, nil, 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
terminal := exec.Command("python3", "internal/cobra/testdata/completion_terminal.py", shell, scriptPath, tc.line)
|
|
terminal.Env = append(os.Environ(), "PATH="+dir+string(os.PathListSeparator)+os.Getenv("PATH"), "HOME="+dir, "TERM=xterm", "PROBE_LOG="+log, "PROBE_DIR="+dir)
|
|
if output, err := terminal.CombinedOutput(); err != nil {
|
|
t.Fatalf("shell completion: %v\n%s", err, output)
|
|
}
|
|
content, err := os.ReadFile(log)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var got []string
|
|
if err := json.Unmarshal(content, &got); err != nil {
|
|
t.Fatalf("fixture output %q: %v", content, err)
|
|
}
|
|
if tc.directory && len(got) > 0 {
|
|
got[len(got)-1] = strings.TrimSuffix(got[len(got)-1], "/")
|
|
}
|
|
if !reflect.DeepEqual(got, tc.want) {
|
|
t.Fatalf("edited arguments=%q, want %q", got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
t.Run(shell+"/descriptions", func(t *testing.T) {
|
|
terminal := exec.Command("python3", "internal/cobra/testdata/completion_terminal.py", shell, scriptPath, "probe run --format=")
|
|
terminal.Env = append(os.Environ(), "PATH="+dir+string(os.PathListSeparator)+os.Getenv("PATH"), "HOME="+dir, "TERM=xterm", "PROBE_LOG="+filepath.Join(dir, "log"), "PROBE_DIR="+dir, "PROBE_LIST=1")
|
|
output, err := terminal.CombinedOutput()
|
|
if err != nil || !strings.Contains(string(output), "Readable text") || !strings.Contains(string(output), "YAML output") {
|
|
t.Fatalf("completion descriptions: %v\n%s", err, output)
|
|
}
|
|
})
|
|
}
|
|
}
|