wand/apply_test.go

137 lines
4.3 KiB
Go
Raw Normal View History

2025-09-06 21:38:50 +02:00
package wand
import (
"errors"
"io"
"testing"
)
func TestApply(t *testing.T) {
t.Run("input", func(t *testing.T) {
type s0 struct {
Foo string
Bar string
}
type s2 struct {
Foo bool
Bar bool
}
f0 := func(a s0) string { return a.Foo + a.Bar }
f0a := func(a ...s0) int { return len(a) }
f0b := func(a *s0) string { return a.Foo + a.Bar }
f0c := func(a []s0) int { return len(a) }
f0d := func(a *[]**s0) int { return len(*a) }
f0io := func(out io.Writer, a s0, in io.Reader) { io.Copy(out, in); out.Write([]byte(a.Foo + a.Bar)) }
f1 := func(a, b, c int) int { return a + b + c }
f1a := func(a, b int, c ...int) int { return a + b + len(c) }
2026-01-08 21:22:16 +01:00
f1b := func(a, b, c **int) int { return **a + **b + **c }
f1c := func(a, b, c []int) int { return a[0] + b[0] + c[0] }
f1d := func(a, b, c **[]*int) int { return *(**a)[0] + *(**b)[0] + *(**c)[0] }
2025-09-06 21:38:50 +02:00
f2 := func(a s2) bool { return a.Foo != a.Bar }
t.Run("config", testExec(testCase{impl: f0, command: "foo", conf: "foo=bar"}, "", "bar"))
t.Run("env", testExec(testCase{impl: f0, command: "foo", env: "foo_foo=bar"}, "", "bar"))
t.Run("options", testExec(testCase{impl: f0, command: "foo --foo bar"}, "", "bar"))
t.Run(
"env overrides config",
testExec(
testCase{impl: f0, command: "foo", conf: "foo=bar\nbar=baz", env: "foo_foo=qux"},
"",
"quxbaz",
),
)
t.Run(
"options override env and config",
testExec(
testCase{impl: f0, command: "foo --bar quux", conf: "foo=bar\nbar=baz", env: "foo_foo=qux"},
"",
"quxquux",
),
)
t.Run("variadic structure not set", testExec(testCase{impl: f0a, command: "foo"}, "", "0"))
t.Run(
"variadic structure from env",
testExec(testCase{impl: f0a, command: "foo", env: "foo_foo=bar"}, "", "1"),
)
t.Run(
"variadic structure from options",
testExec(testCase{impl: f0a, command: "foo --foo bar"}, "", "1"),
)
t.Run(
"variadic with multiple entries not allowed",
testExec(testCase{impl: f0a, command: "foo --foo bar --foo baz"}, "expected only one value", ""),
)
t.Run(
"pointer",
testExec(testCase{impl: f0b, command: "foo --foo bar"}, "", "bar"),
)
t.Run(
"list",
testExec(testCase{impl: f0c, command: "foo --foo bar"}, "", "1"),
)
t.Run(
"list with multiple entries not allowed",
testExec(testCase{impl: f0c, command: "foo --foo bar --foo baz"}, "expected only one value", ""),
)
t.Run(
"variadic list pointer",
testExec(testCase{impl: f0d, command: "foo --foo bar"}, "", "1"),
)
t.Run(
"reader and writer set",
testExec(
testCase{impl: f0io, stdin: "foobar", command: "foo --foo baz --bar qux"},
"",
"foobarbazqux",
),
)
t.Run("positional", testExec(testCase{impl: f1, command: "foo 1 2 3"}, "", "6"))
t.Run(
"variadic positional",
testExec(testCase{impl: f1a, command: "foo 1 2 3 4 5"}, "", "6"),
)
t.Run("boolean options", testExec(testCase{impl: f2, command: "foo --foo --bar"}, "", "false"))
t.Run(
"short form options",
testExec(
testCase{impl: ShortForm(Command("foo", f0), "f", "foo"), command: "foo -f bar"},
"",
"bar",
),
)
2026-01-08 21:22:16 +01:00
t.Run("positional in pointer", testExec(testCase{impl: f1b, command: "foo 1 2 3"}, "", "6"))
t.Run("positional in pointer", testExec(testCase{impl: f1c, command: "foo 1 2 3"}, "", "6"))
t.Run("positional in pointer", testExec(testCase{impl: f1d, command: "foo 1 2 3"}, "", "6"))
2025-09-06 21:38:50 +02:00
})
t.Run("output", func(t *testing.T) {
f0 := func() {}
f1 := func() int { return 42 }
f2 := func() (int, int, int) { return 21, 42, 84 }
f3 := func() error { return nil }
f4 := func() error { return errors.New("test error") }
f5 := func() (int, int, error) { return 42, 84, nil }
f6 := func() (int, int, error) { return 42, 84, errors.New("test error") }
t.Run("no output", testExec(testCase{impl: f0, command: "foo"}, "", ""))
t.Run("non-error output", testExec(testCase{impl: f1, command: "foo"}, "", "42"))
t.Run("multiple outputs", testExec(testCase{impl: f2, command: "foo"}, "", "21\n42\n84"))
t.Run("error output no error", testExec(testCase{impl: f3, command: "foo"}, "", ""))
t.Run("error output error", testExec(testCase{impl: f4, command: "foo"}, "test error", ""))
t.Run("mixed output no error", testExec(testCase{impl: f5, command: "foo"}, "", "42\n84"))
t.Run("mixed output error", testExec(testCase{impl: f6, command: "foo"}, "test error", ""))
})
}