[🤖] Add Unit-Tests
Build Docker and Deploy / Run goext test-suite (push) Successful in 1m34s

This commit is contained in:
2026-04-27 10:46:08 +02:00
parent dad0e3240d
commit 02d6894ec6
116 changed files with 18795 additions and 1 deletions
+324
View File
@@ -0,0 +1,324 @@
package cmdext
import (
"reflect"
"testing"
"time"
)
func TestRunnerInit(t *testing.T) {
r := Runner("myprog")
if r == nil {
t.Fatalf("Runner returned nil")
}
if r.program != "myprog" {
t.Errorf("program == %v, want myprog", r.program)
}
if r.args == nil {
t.Errorf("args is nil, want empty slice")
}
if len(r.args) != 0 {
t.Errorf("len(args) == %v, want 0", len(r.args))
}
if r.env == nil {
t.Errorf("env is nil, want empty slice")
}
if len(r.env) != 0 {
t.Errorf("len(env) == %v, want 0", len(r.env))
}
if r.listener == nil {
t.Errorf("listener is nil, want empty slice")
}
if len(r.listener) != 0 {
t.Errorf("len(listener) == %v, want 0", len(r.listener))
}
if r.timeout != nil {
t.Errorf("timeout == %v, want nil", r.timeout)
}
if r.enforceExitCodes != nil {
t.Errorf("enforceExitCodes == %v, want nil", r.enforceExitCodes)
}
if r.enforceNoTimeout {
t.Errorf("enforceNoTimeout == true, want false")
}
if r.enforceNoStderr {
t.Errorf("enforceNoStderr == true, want false")
}
}
func TestArgSingle(t *testing.T) {
r := Runner("p").Arg("a")
if !reflect.DeepEqual(r.args, []string{"a"}) {
t.Errorf("args == %v, want [a]", r.args)
}
}
func TestArgMultiple(t *testing.T) {
r := Runner("p").Arg("a").Arg("b").Arg("c")
if !reflect.DeepEqual(r.args, []string{"a", "b", "c"}) {
t.Errorf("args == %v, want [a b c]", r.args)
}
}
func TestArgsAppendsAll(t *testing.T) {
r := Runner("p").Args([]string{"x", "y"}).Args([]string{"z"})
if !reflect.DeepEqual(r.args, []string{"x", "y", "z"}) {
t.Errorf("args == %v, want [x y z]", r.args)
}
}
func TestArgAndArgsMixed(t *testing.T) {
r := Runner("p").Arg("a").Args([]string{"b", "c"}).Arg("d")
if !reflect.DeepEqual(r.args, []string{"a", "b", "c", "d"}) {
t.Errorf("args == %v, want [a b c d]", r.args)
}
}
func TestArgsEmptySlice(t *testing.T) {
r := Runner("p").Args([]string{})
if len(r.args) != 0 {
t.Errorf("len(args) == %v, want 0", len(r.args))
}
}
func TestTimeoutSet(t *testing.T) {
d := 500 * time.Millisecond
r := Runner("p").Timeout(d)
if r.timeout == nil {
t.Fatalf("timeout is nil")
}
if *r.timeout != d {
t.Errorf("timeout == %v, want %v", *r.timeout, d)
}
}
func TestTimeoutOverride(t *testing.T) {
r := Runner("p").Timeout(1 * time.Second).Timeout(2 * time.Second)
if *r.timeout != 2*time.Second {
t.Errorf("timeout == %v, want 2s", *r.timeout)
}
}
func TestEnv(t *testing.T) {
r := Runner("p").Env("KEY", "VALUE")
if !reflect.DeepEqual(r.env, []string{"KEY=VALUE"}) {
t.Errorf("env == %v, want [KEY=VALUE]", r.env)
}
}
func TestEnvMultiple(t *testing.T) {
r := Runner("p").Env("A", "1").Env("B", "2")
if !reflect.DeepEqual(r.env, []string{"A=1", "B=2"}) {
t.Errorf("env == %v, want [A=1 B=2]", r.env)
}
}
func TestEnvWithEmptyValue(t *testing.T) {
r := Runner("p").Env("KEY", "")
if !reflect.DeepEqual(r.env, []string{"KEY="}) {
t.Errorf("env == %v, want [KEY=]", r.env)
}
}
func TestRawEnv(t *testing.T) {
r := Runner("p").RawEnv("FOO=BAR=BAZ")
if !reflect.DeepEqual(r.env, []string{"FOO=BAR=BAZ"}) {
t.Errorf("env == %v, want [FOO=BAR=BAZ]", r.env)
}
}
func TestEnvs(t *testing.T) {
r := Runner("p").Envs([]string{"A=1", "B=2"})
if !reflect.DeepEqual(r.env, []string{"A=1", "B=2"}) {
t.Errorf("env == %v, want [A=1 B=2]", r.env)
}
}
func TestEnvMixed(t *testing.T) {
r := Runner("p").Env("A", "1").RawEnv("B=2").Envs([]string{"C=3", "D=4"})
if !reflect.DeepEqual(r.env, []string{"A=1", "B=2", "C=3", "D=4"}) {
t.Errorf("env == %v, want [A=1 B=2 C=3 D=4]", r.env)
}
}
func TestEnsureExitcodeSingle(t *testing.T) {
r := Runner("p").EnsureExitcode(2)
if r.enforceExitCodes == nil {
t.Fatalf("enforceExitCodes is nil")
}
if !reflect.DeepEqual(*r.enforceExitCodes, []int{2}) {
t.Errorf("enforceExitCodes == %v, want [2]", *r.enforceExitCodes)
}
}
func TestEnsureExitcodeMultiple(t *testing.T) {
r := Runner("p").EnsureExitcode(0, 1, 2)
if r.enforceExitCodes == nil {
t.Fatalf("enforceExitCodes is nil")
}
if !reflect.DeepEqual(*r.enforceExitCodes, []int{0, 1, 2}) {
t.Errorf("enforceExitCodes == %v, want [0 1 2]", *r.enforceExitCodes)
}
}
func TestFailOnExitCode(t *testing.T) {
r := Runner("p").FailOnExitCode()
if r.enforceExitCodes == nil {
t.Fatalf("enforceExitCodes is nil")
}
if !reflect.DeepEqual(*r.enforceExitCodes, []int{0}) {
t.Errorf("enforceExitCodes == %v, want [0]", *r.enforceExitCodes)
}
}
func TestFailOnTimeoutFlag(t *testing.T) {
r := Runner("p")
if r.enforceNoTimeout {
t.Errorf("enforceNoTimeout was true before set")
}
r = r.FailOnTimeout()
if !r.enforceNoTimeout {
t.Errorf("enforceNoTimeout == false after FailOnTimeout()")
}
}
func TestFailOnStderrFlag(t *testing.T) {
r := Runner("p")
if r.enforceNoStderr {
t.Errorf("enforceNoStderr was true before set")
}
r = r.FailOnStderr()
if !r.enforceNoStderr {
t.Errorf("enforceNoStderr == false after FailOnStderr()")
}
}
func TestListen(t *testing.T) {
r := Runner("p").Listen(genericCommandListener{})
if len(r.listener) != 1 {
t.Errorf("len(listener) == %v, want 1", len(r.listener))
}
}
func TestListenMultiple(t *testing.T) {
r := Runner("p").
Listen(genericCommandListener{}).
Listen(genericCommandListener{}).
Listen(genericCommandListener{})
if len(r.listener) != 3 {
t.Errorf("len(listener) == %v, want 3", len(r.listener))
}
}
func TestListenStdoutAddsListener(t *testing.T) {
r := Runner("p").ListenStdout(func(string) {})
if len(r.listener) != 1 {
t.Errorf("len(listener) == %v, want 1", len(r.listener))
}
}
func TestListenStdoutForwardsCalls(t *testing.T) {
got := ""
r := Runner("p").ListenStdout(func(s string) { got = s })
if len(r.listener) != 1 {
t.Fatalf("len(listener) == %v, want 1", len(r.listener))
}
r.listener[0].ReadStdoutLine("hello")
if got != "hello" {
t.Errorf("listener got %q, want hello", got)
}
// non-stdout methods should not panic and should not affect state
r.listener[0].ReadStderrLine("nope")
r.listener[0].ReadRawStdout([]byte("raw"))
r.listener[0].ReadRawStderr([]byte("raw"))
r.listener[0].Finished(0)
r.listener[0].Timeout()
if got != "hello" {
t.Errorf("listener got mutated to %q, want hello", got)
}
}
func TestListenStderrAddsListener(t *testing.T) {
r := Runner("p").ListenStderr(func(string) {})
if len(r.listener) != 1 {
t.Errorf("len(listener) == %v, want 1", len(r.listener))
}
}
func TestListenStderrForwardsCalls(t *testing.T) {
got := ""
r := Runner("p").ListenStderr(func(s string) { got = s })
if len(r.listener) != 1 {
t.Fatalf("len(listener) == %v, want 1", len(r.listener))
}
r.listener[0].ReadStderrLine("oops")
if got != "oops" {
t.Errorf("listener got %q, want oops", got)
}
r.listener[0].ReadStdoutLine("nope")
if got != "oops" {
t.Errorf("listener got mutated to %q, want oops", got)
}
}
func TestChainReturnsSameInstance(t *testing.T) {
r := Runner("p")
if r.Arg("a") != r {
t.Errorf("Arg returned different instance")
}
if r.Args([]string{"b"}) != r {
t.Errorf("Args returned different instance")
}
if r.Timeout(time.Second) != r {
t.Errorf("Timeout returned different instance")
}
if r.Env("K", "V") != r {
t.Errorf("Env returned different instance")
}
if r.RawEnv("K=V") != r {
t.Errorf("RawEnv returned different instance")
}
if r.Envs([]string{"K=V"}) != r {
t.Errorf("Envs returned different instance")
}
if r.EnsureExitcode(0) != r {
t.Errorf("EnsureExitcode returned different instance")
}
if r.FailOnExitCode() != r {
t.Errorf("FailOnExitCode returned different instance")
}
if r.FailOnTimeout() != r {
t.Errorf("FailOnTimeout returned different instance")
}
if r.FailOnStderr() != r {
t.Errorf("FailOnStderr returned different instance")
}
if r.Listen(genericCommandListener{}) != r {
t.Errorf("Listen returned different instance")
}
if r.ListenStdout(func(string) {}) != r {
t.Errorf("ListenStdout returned different instance")
}
if r.ListenStderr(func(string) {}) != r {
t.Errorf("ListenStderr returned different instance")
}
}
func TestSeparateInstancesIndependent(t *testing.T) {
r1 := Runner("p1").Arg("a")
r2 := Runner("p2").Arg("b")
if r1.program != "p1" {
t.Errorf("r1.program == %v, want p1", r1.program)
}
if r2.program != "p2" {
t.Errorf("r2.program == %v, want p2", r2.program)
}
if !reflect.DeepEqual(r1.args, []string{"a"}) {
t.Errorf("r1.args == %v, want [a]", r1.args)
}
if !reflect.DeepEqual(r2.args, []string{"b"}) {
t.Errorf("r2.args == %v, want [b]", r2.args)
}
}