mirror of
https://github.com/lukaszraczylo/kportal.git
synced 2026-06-23 04:01:08 +00:00
328 lines
7.7 KiB
Go
328 lines
7.7 KiB
Go
package complete
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestGenerateBash(t *testing.T) {
|
|
script, err := Generate(ShellBash)
|
|
if err != nil {
|
|
t.Fatalf("Generate(ShellBash) failed: %v", err)
|
|
}
|
|
|
|
// Verify script contains key elements
|
|
if !strings.Contains(script, "_kportal()") {
|
|
t.Error("Bash script missing _kportal function")
|
|
}
|
|
if !strings.Contains(script, "complete -F _kportal kportal") {
|
|
t.Error("Bash script missing completion registration")
|
|
}
|
|
if !strings.Contains(script, "--version") {
|
|
t.Error("Bash script missing --version flag")
|
|
}
|
|
if !strings.Contains(script, "generate") {
|
|
t.Error("Bash script missing generate subcommand")
|
|
}
|
|
}
|
|
|
|
func TestGenerateZsh(t *testing.T) {
|
|
script, err := Generate(ShellZsh)
|
|
if err != nil {
|
|
t.Fatalf("Generate(ShellZsh) failed: %v", err)
|
|
}
|
|
|
|
// Verify script contains key elements
|
|
if !strings.Contains(script, "#compdef kportal") {
|
|
t.Error("Zsh script missing #compdef directive")
|
|
}
|
|
if !strings.Contains(script, "_kportal()") {
|
|
t.Error("Zsh script missing _kportal function")
|
|
}
|
|
if !strings.Contains(script, "'generate:") {
|
|
t.Error("Zsh script missing generate subcommand")
|
|
}
|
|
if !strings.Contains(script, "'--context[") {
|
|
t.Error("Zsh script missing --context flag")
|
|
}
|
|
}
|
|
|
|
func TestGenerateFish(t *testing.T) {
|
|
script, err := Generate(ShellFish)
|
|
if err != nil {
|
|
t.Fatalf("Generate(ShellFish) failed: %v", err)
|
|
}
|
|
|
|
// Verify script contains key elements
|
|
if !strings.Contains(script, "complete -c kportal") {
|
|
t.Error("Fish script missing complete directive")
|
|
}
|
|
if !strings.Contains(script, "-n '__fish_use_subcommand'") {
|
|
t.Error("Fish script missing subcommand detection")
|
|
}
|
|
if !strings.Contains(script, "-l context") {
|
|
t.Error("Fish script missing --context flag")
|
|
}
|
|
}
|
|
|
|
func TestGenerateUnsupported(t *testing.T) {
|
|
_, err := Generate(Shell("unsupported"))
|
|
if err == nil {
|
|
t.Error("Expected error for unsupported shell")
|
|
}
|
|
}
|
|
|
|
func TestAutoDetectShell(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
shellEnv string
|
|
expected Shell
|
|
}{
|
|
{"bash", "/bin/bash", ShellBash},
|
|
{"zsh", "/usr/bin/zsh", ShellZsh},
|
|
{"fish", "/usr/local/bin/fish", ShellFish},
|
|
{"tcsh", "/bin/tcsh", ShellBash}, // Falls back to bash
|
|
{"empty", "", ShellBash}, // Falls back to bash
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
detected := autoDetectShellFromEnv(tt.shellEnv)
|
|
if detected != tt.expected {
|
|
t.Errorf("AutoDetectShell() = %v, want %v", detected, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// autoDetectShellFromEnv is a test helper that simulates shell detection
|
|
func autoDetectShellFromEnv(shellEnv string) Shell {
|
|
if shellEnv == "" {
|
|
return ShellBash
|
|
}
|
|
if strings.HasSuffix(shellEnv, "/bash") {
|
|
return ShellBash
|
|
}
|
|
if strings.HasSuffix(shellEnv, "/zsh") {
|
|
return ShellZsh
|
|
}
|
|
if strings.HasSuffix(shellEnv, "/fish") {
|
|
return ShellFish
|
|
}
|
|
return ShellBash
|
|
}
|
|
|
|
func TestInstaller(t *testing.T) {
|
|
// Test with bash
|
|
installer := NewInstaller(ShellBash)
|
|
if installer.prefixDir == "" {
|
|
t.Error("Installer should have a prefix directory")
|
|
}
|
|
|
|
// Test filename generation
|
|
t.Run("filename", func(t *testing.T) {
|
|
tests := []struct {
|
|
shell Shell
|
|
expected string
|
|
}{
|
|
{ShellBash, "_kportal"},
|
|
{ShellZsh, "_kportal"},
|
|
{ShellFish, "kportal.fish"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
inst := NewInstaller(tt.shell)
|
|
got := inst.getCompletionFilename()
|
|
if got != tt.expected {
|
|
t.Errorf("getCompletionFilename() for %v = %v, want %v", tt.shell, got, tt.expected)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestInstallCompletion(t *testing.T) {
|
|
// Temp directory (auto-removed by the test framework)
|
|
tempDir := t.TempDir()
|
|
|
|
// Test installation to temp directory
|
|
installer := &Installer{
|
|
shell: ShellBash,
|
|
prefixDir: tempDir,
|
|
}
|
|
|
|
// Should fail because file doesn't exist (doesn't matter, just test the method exists)
|
|
_ = installer.Install()
|
|
}
|
|
|
|
func TestPrint(t *testing.T) {
|
|
// Test that Print doesn't crash and outputs something
|
|
orig := os.Stdout
|
|
r, w, _ := os.Pipe()
|
|
os.Stdout = w
|
|
|
|
err := Print(ShellBash)
|
|
|
|
_ = w.Close()
|
|
os.Stdout = orig
|
|
|
|
if err != nil {
|
|
t.Fatalf("Print(ShellBash) failed: %v", err)
|
|
}
|
|
|
|
// Read output
|
|
buf := make([]byte, 1024)
|
|
n, _ := r.Read(buf)
|
|
output := string(buf[:n])
|
|
|
|
if !strings.Contains(output, "_kportal") {
|
|
t.Error("Print output should contain _kportal")
|
|
}
|
|
}
|
|
|
|
func TestGetCompletionFilename(t *testing.T) {
|
|
tests := []struct {
|
|
shell Shell
|
|
expected string
|
|
}{
|
|
{ShellBash, "_kportal"},
|
|
{ShellZsh, "_kportal"},
|
|
{ShellFish, "kportal.fish"},
|
|
{Shell("unknown"), "_kportal"}, // Falls back
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
inst := &Installer{shell: tt.shell}
|
|
got := inst.getCompletionFilename()
|
|
if got != tt.expected {
|
|
t.Errorf("getCompletionFilename() for %v = %v, want %v", tt.shell, got, tt.expected)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBashCompletionIncludesContextCompletion(t *testing.T) {
|
|
script, err := Generate(ShellBash)
|
|
if err != nil {
|
|
t.Fatalf("Generate(ShellBash) failed: %v", err)
|
|
}
|
|
|
|
// Should include kubectl context completion
|
|
if !strings.Contains(script, "kubectl config get-contexts") {
|
|
t.Error("Bash completion should include kubectl context completion")
|
|
}
|
|
}
|
|
|
|
func TestZshCompletionIncludesContextCompletion(t *testing.T) {
|
|
script, err := Generate(ShellZsh)
|
|
if err != nil {
|
|
t.Fatalf("Generate(ShellZsh) failed: %v", err)
|
|
}
|
|
|
|
// Should include kubectl context completion
|
|
if !strings.Contains(script, "kubectl config get-contexts") {
|
|
t.Error("Zsh completion should include kubectl context completion")
|
|
}
|
|
}
|
|
|
|
func TestFishCompletionIncludesContextCompletion(t *testing.T) {
|
|
script, err := Generate(ShellFish)
|
|
if err != nil {
|
|
t.Fatalf("Generate(ShellFish) failed: %v", err)
|
|
}
|
|
|
|
// Should include kubectl context completion
|
|
if !strings.Contains(script, "kubectl config get-contexts") {
|
|
t.Error("Fish completion should include kubectl context completion")
|
|
}
|
|
}
|
|
|
|
func TestAllFlagsPresent(t *testing.T) {
|
|
script, err := Generate(ShellBash)
|
|
if err != nil {
|
|
t.Fatalf("Generate(ShellBash) failed: %v", err)
|
|
}
|
|
|
|
// Check all main flags are present. The main command exposes single-dash
|
|
// -c/-v (no --config/--verbose long forms); word flags use --.
|
|
flags := []string{
|
|
"-c",
|
|
"-v",
|
|
"--version",
|
|
"--update",
|
|
"--check",
|
|
"--headless",
|
|
"--log-format",
|
|
"--convert",
|
|
"--convert-output",
|
|
}
|
|
|
|
for _, flag := range flags {
|
|
if !strings.Contains(script, flag) {
|
|
t.Errorf("Bash completion missing flag: %s", flag)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSubcommandsPresent(t *testing.T) {
|
|
for _, shell := range []Shell{ShellBash, ShellZsh, ShellFish} {
|
|
script, err := Generate(shell)
|
|
if err != nil {
|
|
t.Fatalf("Generate(%v) failed: %v", shell, err)
|
|
}
|
|
|
|
for _, sub := range []string{"generate", "completion"} {
|
|
if !strings.Contains(script, sub) {
|
|
t.Errorf("%s completion missing %q subcommand", shell, sub)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGenerateFlagsPresent(t *testing.T) {
|
|
script, err := Generate(ShellBash)
|
|
if err != nil {
|
|
t.Fatalf("Generate(ShellBash) failed: %v", err)
|
|
}
|
|
|
|
generateFlags := []string{
|
|
"--context",
|
|
"--config",
|
|
"--dry-run",
|
|
}
|
|
|
|
for _, flag := range generateFlags {
|
|
if !strings.Contains(script, flag) {
|
|
t.Errorf("Bash completion missing generate flag: %s", flag)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestCompletionScriptPermissions(t *testing.T) {
|
|
// Create temp file and verify permissions handling
|
|
tempDir := t.TempDir()
|
|
|
|
installer := &Installer{
|
|
shell: ShellBash,
|
|
prefixDir: tempDir,
|
|
}
|
|
|
|
filename := filepath.Join(tempDir, installer.getCompletionFilename())
|
|
|
|
// Write a test file
|
|
err := os.WriteFile(filename, []byte("test"), 0o600)
|
|
if err != nil {
|
|
t.Fatalf("Failed to write test file: %v", err)
|
|
}
|
|
|
|
// Verify file exists and is readable
|
|
data, err := os.ReadFile(filename)
|
|
if err != nil {
|
|
t.Fatalf("Failed to read test file: %v", err)
|
|
}
|
|
|
|
if string(data) != "test" {
|
|
t.Error("File content mismatch")
|
|
}
|
|
}
|