aboutsummaryrefslogtreecommitdiffhomepage
path: root/container/stub/stub_test.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-03-17 16:09:14 +0900
committerOphestra <cat@gensokyo.uk>2026-03-17 16:09:14 +0900
commitbac583f89edd1360150143ff51f7264c01aa69ec (patch)
tree47914efe1ae9fae256ef93725097bdb9255c03d5 /container/stub/stub_test.go
parent722989c68256469963aee963bed9c6ab4bf55b67 (diff)
internal/stub: move from container
This package solves a very specific stubbing use case, in a less than elegant manner. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'container/stub/stub_test.go')
-rw-r--r--container/stub/stub_test.go335
1 files changed, 0 insertions, 335 deletions
diff --git a/container/stub/stub_test.go b/container/stub/stub_test.go
deleted file mode 100644
index 9c9b0eb8..00000000
--- a/container/stub/stub_test.go
+++ /dev/null
@@ -1,335 +0,0 @@
-package stub
-
-import (
- "reflect"
- "sync/atomic"
- "testing"
-)
-
-// stubHolder embeds [Stub].
-type stubHolder struct{ *Stub[stubHolder] }
-
-// overrideT allows some methods of [testing.T] to be overridden.
-type overrideT struct {
- *testing.T
-
- error atomic.Pointer[func(args ...any)]
- errorf atomic.Pointer[func(format string, args ...any)]
-}
-
-func (t *overrideT) Error(args ...any) {
- fp := t.error.Load()
- if fp == nil || *fp == nil {
- t.T.Error(args...)
- return
- }
- (*fp)(args...)
-}
-
-func (t *overrideT) Errorf(format string, args ...any) {
- fp := t.errorf.Load()
- if fp == nil || *fp == nil {
- t.T.Errorf(format, args...)
- return
- }
- (*fp)(format, args...)
-}
-
-func TestStub(t *testing.T) {
- t.Parallel()
-
- t.Run("goexit", func(t *testing.T) {
- t.Parallel()
-
- t.Run("FailNow", func(t *testing.T) {
- t.Parallel()
-
- defer func() {
- if r := recover(); r != panicFailNow {
- t.Errorf("recover: %v", r)
- }
- }()
- stubHolder{&Stub[stubHolder]{TB: t}}.FailNow()
- })
-
- t.Run("SkipNow", func(t *testing.T) {
- t.Parallel()
-
- defer func() {
- want := "invalid call to SkipNow"
- if r := recover(); r != want {
- t.Errorf("recover: %v, want %v", r, want)
- }
- }()
- stubHolder{&Stub[stubHolder]{TB: t}}.SkipNow()
- })
-
- t.Run("Skip", func(t *testing.T) {
- t.Parallel()
-
- defer func() {
- want := "invalid call to Skip"
- if r := recover(); r != want {
- t.Errorf("recover: %v, want %v", r, want)
- }
- }()
- stubHolder{&Stub[stubHolder]{TB: t}}.Skip()
- })
-
- t.Run("Skipf", func(t *testing.T) {
- t.Parallel()
-
- defer func() {
- want := "invalid call to Skipf"
- if r := recover(); r != want {
- t.Errorf("recover: %v, want %v", r, want)
- }
- }()
- stubHolder{&Stub[stubHolder]{TB: t}}.Skipf("")
- })
- })
-
- t.Run("new", func(t *testing.T) {
- t.Parallel()
-
- t.Run("success", func(t *testing.T) {
- t.Parallel()
-
- s := New(t, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{
- {"New", ExpectArgs{}, nil, nil},
- }, Tracks: []Expect{{Calls: []Call{
- {"done", ExpectArgs{0xbabe}, nil, nil},
- }}}})
-
- s.New(func(k stubHolder) {
- expect := k.Expects("done")
- if expect.Name != "done" {
- t.Errorf("New: Name = %s, want done", expect.Name)
- }
- if expect.Args != (ExpectArgs{0xbabe}) {
- t.Errorf("New: Args = %#v", expect.Args)
- }
- if expect.Ret != nil {
- t.Errorf("New: Ret = %#v", expect.Ret)
- }
- if expect.Err != nil {
- t.Errorf("New: Err = %#v", expect.Err)
- }
- })
-
- if pos := s.Pos(); pos != 1 {
- t.Errorf("Pos: %d, want 1", pos)
- }
- if l := s.Len(); l != 1 {
- t.Errorf("Len: %d, want 1", l)
- }
-
- s.VisitIncomplete(func(s *Stub[stubHolder]) { panic("unreachable") })
- })
-
- t.Run("overrun", func(t *testing.T) {
- t.Parallel()
-
- ot := &overrideT{T: t}
- ot.error.Store(checkError(t, "New: track overrun"))
- s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{
- {"New", ExpectArgs{}, nil, nil},
- {"panic", ExpectArgs{"unreachable"}, nil, nil},
- }})
- func() { defer HandleExit(t); s.New(func(k stubHolder) { panic("unreachable") }) }()
-
- var visit int
- s.VisitIncomplete(func(s *Stub[stubHolder]) {
- visit++
- if visit > 1 {
- panic("unexpected visit count")
- }
-
- want := Call{"panic", ExpectArgs{"unreachable"}, nil, nil}
- if got := s.want.Calls[s.pos]; !reflect.DeepEqual(got, want) {
- t.Errorf("VisitIncomplete: %#v, want %#v", got, want)
- }
- })
- })
-
- t.Run("expects", func(t *testing.T) {
- t.Parallel()
-
- t.Run("overrun", func(t *testing.T) {
- t.Parallel()
-
- ot := &overrideT{T: t}
- ot.error.Store(checkError(t, "Expects: advancing beyond expected calls"))
- s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{})
- func() { defer HandleExit(t); s.Expects("unreachable") }()
- })
-
- t.Run("separator", func(t *testing.T) {
- t.Parallel()
-
- t.Run("overrun", func(t *testing.T) {
- t.Parallel()
-
- ot := &overrideT{T: t}
- ot.errorf.Store(checkErrorf(t, "Expects: func = %s, separator overrun", "meow"))
- s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{
- {CallSeparator, ExpectArgs{}, nil, nil},
- }})
- func() { defer HandleExit(t); s.Expects("meow") }()
- })
-
- t.Run("mismatch", func(t *testing.T) {
- t.Parallel()
-
- ot := &overrideT{T: t}
- ot.errorf.Store(checkErrorf(t, "Expects: separator, want %s", "panic"))
- s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{
- {"panic", ExpectArgs{}, nil, nil},
- }})
- func() { defer HandleExit(t); s.Expects(CallSeparator) }()
- })
- })
-
- t.Run("mismatch", func(t *testing.T) {
- t.Parallel()
-
- ot := &overrideT{T: t}
- ot.errorf.Store(checkErrorf(t, "Expects: func = %s, want %s", "meow", "nya"))
- s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{
- {"nya", ExpectArgs{}, nil, nil},
- }})
- func() { defer HandleExit(t); s.Expects("meow") }()
- })
- })
- })
-}
-
-func TestCheckArg(t *testing.T) {
- t.Run("oob negative", func(t *testing.T) {
- t.Parallel()
-
- defer func() {
- want := "invalid call to CheckArg"
- if r := recover(); r != want {
- t.Errorf("recover: %v, want %v", r, want)
- }
- }()
- s := New(t, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{})
- CheckArg(s, "unreachable", struct{}{}, 0)
- })
-
- ot := &overrideT{T: t}
- s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{
- {"panic", ExpectArgs{PanicExit}, nil, nil},
- {"meow", ExpectArgs{-1}, nil, nil},
- }})
-
- t.Run("match", func(t *testing.T) {
- s.Expects("panic")
- if !CheckArg(s, "v", PanicExit, 0) {
- t.Errorf("CheckArg: unexpected false")
- }
- })
-
- t.Run("mismatch", func(t *testing.T) {
- defer HandleExit(t)
- s.Expects("meow")
- ot.errorf.Store(checkErrorf(t, "%s: %s = %#v, want %#v (%d)", "meow", "time", 0, -1, 1))
- if CheckArg(s, "time", 0, 0) {
- t.Errorf("CheckArg: unexpected true")
- }
- })
-
- t.Run("oob", func(t *testing.T) {
- s.pos++
- defer func() {
- want := "invalid call to CheckArg"
- if r := recover(); r != want {
- t.Errorf("recover: %v, want %v", r, want)
- }
- }()
- CheckArg(s, "unreachable", struct{}{}, 0)
- })
-}
-
-func TestCheckArgReflect(t *testing.T) {
- t.Parallel()
-
- t.Run("oob lower", func(t *testing.T) {
- t.Parallel()
-
- defer func() {
- want := "invalid call to CheckArgReflect"
- if r := recover(); r != want {
- t.Errorf("recover: %v, want %v", r, want)
- }
- }()
- s := New(t, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{})
- CheckArgReflect(s, "unreachable", struct{}{}, 0)
- })
-
- ot := &overrideT{T: t}
- s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{
- {"panic", ExpectArgs{PanicExit}, nil, nil},
- {"meow", ExpectArgs{-1}, nil, nil},
- }})
- t.Run("match", func(t *testing.T) {
- s.Expects("panic")
- if !CheckArgReflect(s, "v", PanicExit, 0) {
- t.Errorf("CheckArgReflect: unexpected false")
- }
- })
- t.Run("mismatch", func(t *testing.T) {
- defer HandleExit(t)
- s.Expects("meow")
- ot.errorf.Store(checkErrorf(t, "%s: %s = %#v, want %#v (%d)", "meow", "time", 0, -1, 1))
- if CheckArgReflect(s, "time", 0, 0) {
- t.Errorf("CheckArgReflect: unexpected true")
- }
- })
- t.Run("oob", func(t *testing.T) {
- s.pos++
- defer func() {
- want := "invalid call to CheckArgReflect"
- if r := recover(); r != want {
- t.Errorf("recover: %v, want %v", r, want)
- }
- }()
- CheckArgReflect(s, "unreachable", struct{}{}, 0)
- })
-}
-
-func checkError(t *testing.T, wantArgs ...any) *func(args ...any) {
- var called bool
- f := func(args ...any) {
- if called {
- panic("invalid call to error")
- }
- called = true
-
- if !reflect.DeepEqual(args, wantArgs) {
- t.Errorf("Error: %#v, want %#v", args, wantArgs)
- }
- panic(PanicExit)
- }
- return &f
-}
-
-func checkErrorf(t *testing.T, wantFormat string, wantArgs ...any) *func(format string, args ...any) {
- var called bool
- f := func(format string, args ...any) {
- if called {
- panic("invalid call to errorf")
- }
- called = true
-
- if format != wantFormat {
- t.Errorf("Errorf: format = %q, want %q", format, wantFormat)
- }
- if !reflect.DeepEqual(args, wantArgs) {
- t.Errorf("Errorf: args = %#v, want %#v", args, wantArgs)
- }
- panic(PanicExit)
- }
- return &f
-}