// Package testing provides testing helpers for state machines using testify.
package testing import ( stdtest amhelp am ) // MachDebug sets up a machine for debugging in tests, based on the AM_DEBUG // env var, passed am-dbg address, log level and stdout flag. func ( *stdtest.T, am.Api, string, am.LogLevel, bool, ) { if { .SemLogger().SetSimple(.Logf, ) } else if == "" { .SemLogger().SetSimple(.Logf, ) return } // expand the default addr if == "1" { = telemetry.DbgAddr } := amhelp.MachDebug(, , , , amhelp.SemConfigEnv(true)) require.NoError(, ) } // MachDebugEnv sets up a machine for debugging in tests, based on env vars // only: AM_DBG_ADDR, AM_LOG, and AM_DEBUG. func ( *stdtest.T, am.Api) { := os.Getenv(telemetry.EnvAmDbgAddr) := am.EnvLogLevel("") := os.Getenv(amhelp.EnvAmLogPrint) != "" MachDebug(, , , , ) } // Wait is a test version of [amhelp.Wait], which errors instead of returning // false. func ( *stdtest.T, string, context.Context, time.Duration, ) { if !amhelp.Wait(, ) { if .Context().Err() == nil { .Fatal("ctx expired") } } } // WaitForAll is a test version of [amhelp.WaitForAll], which errors instead of // returning an error. func ( *stdtest.T, string, context.Context, time.Duration, ...<-chan struct{}, ) { if := amhelp.WaitForAll(, , ...); != nil { if .Context().Err() == nil { .Fatal("error for " + + ": " + .Error()) } } } // WaitForErrAll is a test version of [amhelp.WaitForErrAll], which errors // instead of returning an error. func ( *stdtest.T, string, context.Context, am.Api, time.Duration, ...<-chan struct{}, ) { if := amhelp.WaitForErrAll(, , , ...); != nil { if .Context().Err() == nil { .Fatal("error for " + + ": " + .Error()) } } } // WaitForAny is a test version of [amhelp.WaitForAny], which errors instead of // returning an error. func ( *stdtest.T, string, context.Context, time.Duration, ...<-chan struct{}, ) { if := amhelp.WaitForAny(, , ...); != nil { if .Context().Err() == nil { .Fatal("error for " + + ": " + .Error()) } } } // GroupWhen1 is a test version of [amhelp.GroupWhen1], which errors instead of // returning an error. func ( *stdtest.T, []am.Api, string, context.Context, ) []<-chan struct{} { , := amhelp.GroupWhen1(, , ) if != nil { if .Context().Err() == nil { .Fatal() } } return } // AssertIs asserts that the machine is in the given states. func ( *stdtest.T, am.Api, am.S) { assert.Subset(, .ActiveStates(nil), , "%s expected", ) } // AssertIs1 asserts that the machine is in the given state. func ( *stdtest.T, am.Api, string) { assert.Subset(, .ActiveStates(nil), am.S{}, "%s expected", ) } // AssertNot asserts that the machine is not in the given states. func ( *stdtest.T, am.Api, am.S) { assert.NotSubset(, .ActiveStates(nil), , "%s not expected", ) } // AssertNot1 asserts that the machine is not in the given state. func ( *stdtest.T, am.Api, string) { assert.NotSubset(, .ActiveStates(nil), am.S{}, "%s not expected", ) } // AssertNoErrNow asserts that the machine is not in the Exception state. func ( *stdtest.T, am.Api) { if .IsErr() && .Context().Err() == nil { := .Err() if != nil { .Fatalf("Unexpected error in %s: %s", .Id(), .Error()) } else { .Fatalf("Unexpected error in %s", .Id()) } } } // AssertNoErrEver asserts that the machine never was in the Exception state. func ( *stdtest.T, am.Api) { if .Tick(am.StateException) > 0 && .Context().Err() == nil { := .Err() if != nil { .Fatalf("Unexpected error in %s", .Id()) } else { .Fatalf("Unexpected PAST error in %s", .Id()) } } } // AssertErr asserts that the machine is in the Exception state. func ( *stdtest.T, am.Api) { if !.IsErr() && .Context().Err() == nil { .Fatal("expected " + am.StateException) } }