mirror of
https://github.com/chenasraf/wand.git
synced 2026-05-17 17:38:02 +00:00
365 lines
7.7 KiB
Go
365 lines
7.7 KiB
Go
package cmd
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestBuildCobraCommand_Basic(t *testing.T) {
|
|
cfg := &Config{}
|
|
cmd := Command{
|
|
Description: "test command",
|
|
Cmd: "echo test",
|
|
}
|
|
|
|
c := buildCobraCommand(cfg, "mycommand", cmd)
|
|
|
|
if c.Use != "mycommand" {
|
|
t.Errorf("Use = %q, want mycommand", c.Use)
|
|
}
|
|
if c.Short != "test command" {
|
|
t.Errorf("Short = %q, want 'test command'", c.Short)
|
|
}
|
|
if c.RunE == nil {
|
|
t.Error("RunE should be set when Cmd is non-empty")
|
|
}
|
|
}
|
|
|
|
func TestBuildCobraCommand_NoCmd(t *testing.T) {
|
|
cfg := &Config{}
|
|
cmd := Command{
|
|
Description: "parent only",
|
|
Children: map[string]Command{
|
|
"child": {Description: "child cmd", Cmd: "echo child"},
|
|
},
|
|
}
|
|
|
|
c := buildCobraCommand(cfg, "parent", cmd)
|
|
|
|
if c.RunE != nil {
|
|
t.Error("RunE should be nil when Cmd is empty")
|
|
}
|
|
if !c.HasSubCommands() {
|
|
t.Error("expected subcommands")
|
|
}
|
|
}
|
|
|
|
func TestBuildCobraCommand_Children(t *testing.T) {
|
|
cfg := &Config{}
|
|
cmd := Command{
|
|
Description: "parent",
|
|
Cmd: "echo parent",
|
|
Children: map[string]Command{
|
|
"child1": {Description: "first child", Cmd: "echo child1"},
|
|
"child2": {
|
|
Description: "second child",
|
|
Cmd: "echo child2",
|
|
Children: map[string]Command{
|
|
"grandchild": {Description: "grandchild", Cmd: "echo grandchild"},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
c := buildCobraCommand(cfg, "parent", cmd)
|
|
|
|
children := c.Commands()
|
|
if len(children) != 2 {
|
|
t.Fatalf("expected 2 children, got %d", len(children))
|
|
}
|
|
|
|
// Find child2 and check its grandchild
|
|
var child2Found bool
|
|
for _, child := range children {
|
|
if child.Use == "child2" {
|
|
child2Found = true
|
|
grandchildren := child.Commands()
|
|
if len(grandchildren) != 1 {
|
|
t.Fatalf("expected 1 grandchild, got %d", len(grandchildren))
|
|
}
|
|
if grandchildren[0].Use != "grandchild" {
|
|
t.Errorf("grandchild Use = %q", grandchildren[0].Use)
|
|
}
|
|
}
|
|
}
|
|
if !child2Found {
|
|
t.Error("child2 not found in subcommands")
|
|
}
|
|
}
|
|
|
|
func TestExecute_WithConfig(t *testing.T) {
|
|
setupTestConfig(t, `
|
|
main:
|
|
description: test main
|
|
cmd: echo hello
|
|
`)
|
|
|
|
// Execute should succeed - the root command runs "echo hello"
|
|
err := Execute()
|
|
if err != nil {
|
|
t.Fatalf("Execute() failed: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestExecute_Subcommand(t *testing.T) {
|
|
setupTestConfig(t, `
|
|
greet:
|
|
description: say hi
|
|
cmd: echo hi
|
|
`)
|
|
|
|
// Simulate running "wand greet" by setting os.Args
|
|
origArgs := setArgs("wand", "greet")
|
|
defer restoreArgs(origArgs)
|
|
|
|
err := Execute()
|
|
if err != nil {
|
|
t.Fatalf("Execute() failed: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestExecute_NestedSubcommand(t *testing.T) {
|
|
setupTestConfig(t, `
|
|
parent:
|
|
description: parent
|
|
cmd: echo parent
|
|
children:
|
|
child:
|
|
description: child
|
|
cmd: echo child
|
|
`)
|
|
|
|
origArgs := setArgs("wand", "parent", "child")
|
|
defer restoreArgs(origArgs)
|
|
|
|
err := Execute()
|
|
if err != nil {
|
|
t.Fatalf("Execute() failed: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestBuildCobraCommand_WithStringFlags(t *testing.T) {
|
|
cfg := &Config{}
|
|
cmd := Command{
|
|
Description: "flagged",
|
|
Cmd: "echo $WAND_FLAG_OUTPUT",
|
|
Flags: map[string]Flag{
|
|
"output": {Alias: "o", Description: "output path", Default: "default.txt"},
|
|
},
|
|
}
|
|
|
|
c := buildCobraCommand(cfg, "build", cmd)
|
|
|
|
f := c.Flags().Lookup("output")
|
|
if f == nil {
|
|
t.Fatal("flag 'output' not registered")
|
|
}
|
|
if f.Shorthand != "o" {
|
|
t.Errorf("shorthand = %q, want o", f.Shorthand)
|
|
}
|
|
if f.Usage != "output path" {
|
|
t.Errorf("usage = %q", f.Usage)
|
|
}
|
|
if f.DefValue != "default.txt" {
|
|
t.Errorf("default = %q, want default.txt", f.DefValue)
|
|
}
|
|
}
|
|
|
|
func TestBuildCobraCommand_WithBoolFlags(t *testing.T) {
|
|
cfg := &Config{}
|
|
cmd := Command{
|
|
Description: "verbose",
|
|
Cmd: "echo $WAND_FLAG_VERBOSE",
|
|
Flags: map[string]Flag{
|
|
"verbose": {Alias: "v", Description: "verbose output", Type: "bool"},
|
|
},
|
|
}
|
|
|
|
c := buildCobraCommand(cfg, "run", cmd)
|
|
|
|
f := c.Flags().Lookup("verbose")
|
|
if f == nil {
|
|
t.Fatal("flag 'verbose' not registered")
|
|
}
|
|
if f.Shorthand != "v" {
|
|
t.Errorf("shorthand = %q, want v", f.Shorthand)
|
|
}
|
|
if f.DefValue != "false" {
|
|
t.Errorf("default = %q, want false", f.DefValue)
|
|
}
|
|
}
|
|
|
|
func TestBuildCobraCommand_FlagNoAlias(t *testing.T) {
|
|
cfg := &Config{}
|
|
cmd := Command{
|
|
Description: "test",
|
|
Cmd: "echo test",
|
|
Flags: map[string]Flag{
|
|
"count": {Description: "a count"},
|
|
},
|
|
}
|
|
|
|
c := buildCobraCommand(cfg, "test", cmd)
|
|
|
|
f := c.Flags().Lookup("count")
|
|
if f == nil {
|
|
t.Fatal("flag 'count' not registered")
|
|
}
|
|
if f.Shorthand != "" {
|
|
t.Errorf("shorthand = %q, want empty", f.Shorthand)
|
|
}
|
|
}
|
|
|
|
func TestExecute_WithStringFlag(t *testing.T) {
|
|
setupTestConfig(t, `
|
|
greet:
|
|
description: greet
|
|
cmd: echo $WAND_FLAG_NAME
|
|
flags:
|
|
name:
|
|
alias: n
|
|
description: who to greet
|
|
`)
|
|
|
|
origArgs := setArgs("wand", "greet", "--name", "world")
|
|
defer restoreArgs(origArgs)
|
|
|
|
err := Execute()
|
|
if err != nil {
|
|
t.Fatalf("Execute() failed: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestExecute_WithBoolFlag(t *testing.T) {
|
|
setupTestConfig(t, `
|
|
greet:
|
|
description: greet
|
|
cmd: echo "verbose=$WAND_FLAG_VERBOSE"
|
|
flags:
|
|
verbose:
|
|
alias: v
|
|
description: verbose output
|
|
type: bool
|
|
`)
|
|
|
|
origArgs := setArgs("wand", "greet", "--verbose")
|
|
defer restoreArgs(origArgs)
|
|
|
|
err := Execute()
|
|
if err != nil {
|
|
t.Fatalf("Execute() failed: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestBuildCobraCommand_WithAliases(t *testing.T) {
|
|
cfg := &Config{}
|
|
cmd := Command{
|
|
Description: "build",
|
|
Cmd: "echo build",
|
|
Aliases: []string{"b", "compile"},
|
|
}
|
|
|
|
c := buildCobraCommand(cfg, "build", cmd)
|
|
|
|
if len(c.Aliases) != 2 {
|
|
t.Fatalf("expected 2 aliases, got %d", len(c.Aliases))
|
|
}
|
|
if c.Aliases[0] != "b" || c.Aliases[1] != "compile" {
|
|
t.Errorf("aliases = %v, want [b compile]", c.Aliases)
|
|
}
|
|
}
|
|
|
|
func TestExecute_WithAlias(t *testing.T) {
|
|
setupTestConfig(t, `
|
|
build:
|
|
description: build
|
|
cmd: echo built
|
|
aliases: [b]
|
|
`)
|
|
|
|
origArgs := setArgs("wand", "b")
|
|
defer restoreArgs(origArgs)
|
|
|
|
err := Execute()
|
|
if err != nil {
|
|
t.Fatalf("Execute() failed: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestResolveConfigFile_Flag(t *testing.T) {
|
|
origArgs := setArgs("wand", "--wand-file", "/tmp/custom.yml", "build")
|
|
defer restoreArgs(origArgs)
|
|
|
|
got := resolveConfigFile()
|
|
if got != "/tmp/custom.yml" {
|
|
t.Errorf("resolveConfigFile() = %q, want /tmp/custom.yml", got)
|
|
}
|
|
}
|
|
|
|
func TestResolveConfigFile_FlagEquals(t *testing.T) {
|
|
origArgs := setArgs("wand", "--wand-file=/tmp/custom.yml", "build")
|
|
defer restoreArgs(origArgs)
|
|
|
|
got := resolveConfigFile()
|
|
if got != "/tmp/custom.yml" {
|
|
t.Errorf("resolveConfigFile() = %q, want /tmp/custom.yml", got)
|
|
}
|
|
}
|
|
|
|
func TestResolveConfigFile_EnvVar(t *testing.T) {
|
|
origArgs := setArgs("wand", "build")
|
|
defer restoreArgs(origArgs)
|
|
|
|
t.Setenv("WAND_FILE", "/tmp/env.yml")
|
|
|
|
got := resolveConfigFile()
|
|
if got != "/tmp/env.yml" {
|
|
t.Errorf("resolveConfigFile() = %q, want /tmp/env.yml", got)
|
|
}
|
|
}
|
|
|
|
func TestResolveConfigFile_FlagOverridesEnv(t *testing.T) {
|
|
origArgs := setArgs("wand", "--wand-file", "/tmp/flag.yml")
|
|
defer restoreArgs(origArgs)
|
|
|
|
t.Setenv("WAND_FILE", "/tmp/env.yml")
|
|
|
|
got := resolveConfigFile()
|
|
if got != "/tmp/flag.yml" {
|
|
t.Errorf("resolveConfigFile() = %q, want /tmp/flag.yml (flag should override env)", got)
|
|
}
|
|
}
|
|
|
|
func TestExecute_WithWandFileFlag(t *testing.T) {
|
|
dir := t.TempDir()
|
|
configPath := filepath.Join(dir, "custom.yml")
|
|
_ = os.WriteFile(configPath, []byte(`
|
|
main:
|
|
description: custom
|
|
cmd: echo custom
|
|
`), 0644)
|
|
|
|
origArgs := setArgs("wand", "--wand-file", configPath)
|
|
defer restoreArgs(origArgs)
|
|
|
|
err := Execute()
|
|
if err != nil {
|
|
t.Fatalf("Execute() failed: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestExecute_NoMain(t *testing.T) {
|
|
setupTestConfig(t, `
|
|
build:
|
|
description: build
|
|
cmd: echo build
|
|
`)
|
|
|
|
// Running with no args and no "main" should print help (no error)
|
|
err := Execute()
|
|
if err != nil {
|
|
t.Fatalf("Execute() failed: %v", err)
|
|
}
|
|
}
|