Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 164 additions & 0 deletions test/e2e/utility_ginkgo_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
//go:build e2e

package e2e

import (
"encoding/json"
"strings"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

var _ = Describe("completion command", func() {
It("generates shell completions for supported shells", func() {
g := NewWithT(GinkgoT())

Comment on lines +13 to +16
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These Ginkgo E2E specs largely duplicate existing non-Ginkgo E2E tests (e.g., test/e2e/completion_version_test.go, test/e2e/extension_test.go, test/e2e/context_test.go). Since all of these run under go test -tags e2e ./test/e2e, this will execute the same assertions twice, increasing suite time and maintenance burden. Consider migrating/removing the older testing.T variants (or gating one set behind a separate build tag) so coverage isn't duplicated.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acknowledged. This duplication is intentional for this phase: per the current test migration boundary, we are keeping the existing tests for now and adding Ginkgo E2E coverage first. We will decide separately whether to remove or gate the older variants after the Ginkgo coverage is in place.

stdout, stderr, err := runA6("completion", "bash")
g.Expect(err).NotTo(HaveOccurred(), "stderr=%s", stderr)
g.Expect(stdout).To(ContainSubstring("bash completion"))
g.Expect(stdout).To(ContainSubstring("__start_a6"))

stdout, stderr, err = runA6("completion", "zsh")
g.Expect(err).NotTo(HaveOccurred(), "stderr=%s", stderr)
g.Expect(stdout).To(ContainSubstring("compdef"))

stdout, stderr, err = runA6("completion", "fish")
g.Expect(err).NotTo(HaveOccurred(), "stderr=%s", stderr)
g.Expect(stdout).To(ContainSubstring("complete -c a6"))

stdout, stderr, err = runA6("completion", "powershell")
g.Expect(err).NotTo(HaveOccurred(), "stderr=%s", stderr)
g.Expect(stdout).To(ContainSubstring("Register-ArgumentCompleter"))
})
})

var _ = Describe("version command", func() {
It("renders text and JSON version output", func() {
g := NewWithT(GinkgoT())

stdout, stderr, err := runA6("version")
g.Expect(err).NotTo(HaveOccurred(), "stderr=%s", stderr)
g.Expect(stdout).To(ContainSubstring("a6 version"))
g.Expect(stdout).To(ContainSubstring("commit:"))
g.Expect(stdout).To(ContainSubstring("go:"))
g.Expect(stdout).To(ContainSubstring("platform:"))

stdout, stderr, err = runA6("version", "--output", "json")
g.Expect(err).NotTo(HaveOccurred(), "stderr=%s", stderr)
g.Expect(json.Valid([]byte(stdout))).To(BeTrue(), stdout)

var info map[string]any
g.Expect(json.Unmarshal([]byte(stdout), &info)).To(Succeed())
g.Expect(info["version"]).NotTo(BeEmpty())
g.Expect(info["goVersion"]).NotTo(BeEmpty())
g.Expect(info["platform"]).NotTo(BeEmpty())
})
})

var _ = Describe("extension command", func() {
It("handles empty state, aliases, help, and validation without external services", func() {
g := NewWithT(GinkgoT())
env := []string{"A6_CONFIG_DIR=" + GinkgoT().TempDir()}

stdout, stderr, err := runA6WithEnv(env, "extension", "list")
g.Expect(err).NotTo(HaveOccurred(), "stderr=%s", stderr)
g.Expect(stdout).To(ContainSubstring("No extensions installed."))

stdout, stderr, err = runA6WithEnv(env, "extension", "upgrade", "--all")
combined := stdout + stderr
g.Expect(err).NotTo(HaveOccurred(), "stdout=%s stderr=%s", stdout, stderr)
g.Expect(combined).To(SatisfyAny(
ContainSubstring("All extensions are already up to date"),
ContainSubstring("No extensions"),
ContainSubstring("no extensions"),
))

_, stderr, err = runA6WithEnv(env, "extension", "install", "bad-format")
g.Expect(err).To(HaveOccurred())
g.Expect(stderr).To(ContainSubstring("owner/repo"))

_, stderr, err = runA6WithEnv(env, "extension", "remove", "nonexistent", "--force")
g.Expect(err).To(HaveOccurred())
g.Expect(stderr).To(ContainSubstring("not found"))

stdout, stderr, err = runA6WithEnv(env, "extension", "--help")
g.Expect(err).NotTo(HaveOccurred(), "stderr=%s", stderr)
g.Expect(stdout).To(ContainSubstring("install"))
g.Expect(stdout).To(ContainSubstring("list"))
g.Expect(stdout).To(ContainSubstring("upgrade"))
g.Expect(stdout).To(ContainSubstring("remove"))

aliasStdout, aliasStderr, aliasErr := runA6WithEnv(env, "ext", "--help")
g.Expect(aliasErr).NotTo(HaveOccurred(), "stderr=%s", aliasStderr)
g.Expect(aliasStdout).To(Equal(stdout))
})
})

var _ = Describe("context command", func() {
It("creates, lists, switches, and deletes local contexts", func() {
g := NewWithT(GinkgoT())
env := []string{"A6_CONFIG_DIR=" + GinkgoT().TempDir()}

stdout, stderr, err := runA6WithEnv(env, "context", "create", "local", "--server", "http://localhost:9180", "--api-key", "test123")
g.Expect(err).NotTo(HaveOccurred(), "stderr=%s", stderr)
g.Expect(stdout).To(ContainSubstring("created"))

stdout, stderr, err = runA6WithEnv(env, "context", "current")
g.Expect(err).NotTo(HaveOccurred(), "stderr=%s", stderr)
g.Expect(strings.TrimSpace(stdout)).To(Equal("local"))

stdout, stderr, err = runA6WithEnv(env, "context", "create", "staging", "--server", "http://staging:9180")
g.Expect(err).NotTo(HaveOccurred(), "stdout=%s stderr=%s", stdout, stderr)

stdout, stderr, err = runA6WithEnv(env, "context", "list")
g.Expect(err).NotTo(HaveOccurred(), "stdout=%s stderr=%s", stdout, stderr)
g.Expect(stdout).To(ContainSubstring("local"))
g.Expect(stdout).To(ContainSubstring("staging"))
g.Expect(stdout).To(ContainSubstring("http://localhost:9180"))
g.Expect(stdout).To(ContainSubstring("http://staging:9180"))

stdout, stderr, err = runA6WithEnv(env, "context", "list", "--output", "json")
g.Expect(err).NotTo(HaveOccurred(), "stdout=%s stderr=%s", stdout, stderr)
g.Expect(json.Valid([]byte(stdout))).To(BeTrue(), stdout)

stdout, stderr, err = runA6WithEnv(env, "context", "use", "staging")
g.Expect(err).NotTo(HaveOccurred(), "stdout=%s stderr=%s", stdout, stderr)

stdout, stderr, err = runA6WithEnv(env, "context", "current")
g.Expect(err).NotTo(HaveOccurred(), "stderr=%s", stderr)
g.Expect(strings.TrimSpace(stdout)).To(Equal("staging"))

stdout, stderr, err = runA6WithEnv(env, "context", "delete", "staging", "--force")
g.Expect(err).NotTo(HaveOccurred(), "stdout=%s stderr=%s", stdout, stderr)

stdout, stderr, err = runA6WithEnv(env, "context", "list")
g.Expect(err).NotTo(HaveOccurred(), "stdout=%s stderr=%s", stdout, stderr)
g.Expect(stdout).To(ContainSubstring("local"))
g.Expect(stdout).NotTo(ContainSubstring("staging"))
})

It("surfaces duplicate and not-found errors", func() {
g := NewWithT(GinkgoT())
env := []string{"A6_CONFIG_DIR=" + GinkgoT().TempDir()}

stdout, stderr, err := runA6WithEnv(env, "context", "create", "local", "--server", "http://localhost:9180")
g.Expect(err).NotTo(HaveOccurred(), "stdout=%s stderr=%s", stdout, stderr)

_, stderr, err = runA6WithEnv(env, "context", "create", "local", "--server", "http://localhost:9180")
g.Expect(err).To(HaveOccurred())
g.Expect(stderr).To(ContainSubstring("already exists"))

_, stderr, err = runA6WithEnv(env, "context", "use", "nonexistent")
g.Expect(err).To(HaveOccurred())
g.Expect(stderr).To(ContainSubstring("not found"))

stdout, stderr, err = runA6WithEnv(env, "context", "delete", "local", "--force")
g.Expect(err).NotTo(HaveOccurred(), "stdout=%s stderr=%s", stdout, stderr)

stdout, stderr, err = runA6WithEnv(env, "context", "list")
g.Expect(err).NotTo(HaveOccurred(), "stdout=%s stderr=%s", stdout, stderr)
trimmed := strings.TrimSpace(stdout)
g.Expect(trimmed == "" || strings.Contains(trimmed, "No contexts")).To(BeTrue(), "stdout=%s", stdout)
})
})
Loading