130 lines
3.9 KiB
Go
130 lines
3.9 KiB
Go
|
|
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) }
|
||
|
|
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",
|
||
|
|
),
|
||
|
|
)
|
||
|
|
})
|
||
|
|
|
||
|
|
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", ""))
|
||
|
|
})
|
||
|
|
}
|