diff --git a/env.go b/env.go index bb4442c..e8944fd 100644 --- a/env.go +++ b/env.go @@ -159,7 +159,7 @@ func makeCacheKey(testname string, params interface{}, opt *FixtureOptions, test externalCallerLevel := 5 var pc = make([]uintptr, externalCallerLevel) var extCallerFrame runtime.Frame - if externalCallerLevel == runtime.Callers(0, pc) { + if externalCallerLevel == runtime.Callers(opt.additionlSkipExternalCalls, pc) { frames := runtime.CallersFrames(pc) frames.Next() // callers frames.Next() // the function diff --git a/env_generic_sugar.go b/env_generic_sugar.go index 82c0110..f5098de 100644 --- a/env_generic_sugar.go +++ b/env_generic_sugar.go @@ -4,6 +4,7 @@ package fixenv func Cache[TRes any](env Env, params any, opt *FixtureOptions, f func() (TRes, error)) TRes { + addSkipLevel(&opt) callbackResult := env.Cache(params, opt, func() (res interface{}, err error) { return f() }) @@ -16,6 +17,7 @@ func Cache[TRes any](env Env, params any, opt *FixtureOptions, f func() (TRes, e } func CacheWithCleanup[TRes any](env Env, params any, opt *FixtureOptions, f func() (TRes, FixtureCleanupFunc, error)) TRes { + addSkipLevel(&opt) callbackResult := env.CacheWithCleanup(params, opt, func() (res interface{}, cleanup FixtureCleanupFunc, err error) { return f() }) @@ -26,3 +28,10 @@ func CacheWithCleanup[TRes any](env Env, params any, opt *FixtureOptions, f func } return res } + +func addSkipLevel(optspp **FixtureOptions) { + if *optspp == nil { + *optspp = &FixtureOptions{} + } + (*optspp).additionlSkipExternalCalls++ +} diff --git a/env_generic_sugar_test.go b/env_generic_sugar_test.go index c572d7f..6e447e5 100644 --- a/env_generic_sugar_test.go +++ b/env_generic_sugar_test.go @@ -10,42 +10,84 @@ import ( ) func TestCacheGeneric(t *testing.T) { - inParams := 123 - inOpt := &FixtureOptions{Scope: ScopeTest} - - env := envMock{onCache: func(params interface{}, opt *FixtureOptions, f FixtureCallbackFunc) interface{} { - require.Equal(t, inParams, params) - require.Equal(t, inOpt, opt) - res, _ := f() - return res - }} - - res := Cache(env, inParams, inOpt, func() (int, error) { - return 2, nil + t.Run("PassParams", func(t *testing.T) { + inParams := 123 + inOpt := &FixtureOptions{Scope: ScopeTest} + + env := envMock{onCache: func(params interface{}, opt *FixtureOptions, f FixtureCallbackFunc) interface{} { + opt.additionlSkipExternalCalls-- + require.Equal(t, inParams, params) + require.Equal(t, inOpt, opt) + res, _ := f() + return res + }} + + res := Cache(env, inParams, inOpt, func() (int, error) { + return 2, nil + }) + require.Equal(t, 2, res) + }) + t.Run("SkipAdditionalCache", func(t *testing.T) { + test := &testMock{name: t.Name()} + env := newTestEnv(test) + + f1 := func() int { + return Cache(env, nil, nil, func() (int, error) { + return 1, nil + }) + } + f2 := func() int { + return Cache(env, nil, nil, func() (int, error) { + return 2, nil + }) + } + + require.Equal(t, 1, f1()) + require.Equal(t, 2, f2()) }) - require.Equal(t, 2, res) } func TestCacheWithCleanupGeneric(t *testing.T) { - inParams := 123 - inOpt := &FixtureOptions{Scope: ScopeTest} + t.Run("PassParams", func(t *testing.T) { + inParams := 123 + inOpt := &FixtureOptions{Scope: ScopeTest} + + cleanupCalledBack := 0 - cleanupCalledBack := 0 + env := envMock{onCacheWithCleanup: func(params interface{}, opt *FixtureOptions, f FixtureCallbackWithCleanupFunc) interface{} { + opt.additionlSkipExternalCalls-- + require.Equal(t, inParams, params) + require.Equal(t, inOpt, opt) + res, _, _ := f() + return res + }} - env := envMock{onCacheWithCleanup: func(params interface{}, opt *FixtureOptions, f FixtureCallbackWithCleanupFunc) interface{} { - require.Equal(t, inParams, params) - require.Equal(t, inOpt, opt) - res, _, _ := f() - return res - }} + res := CacheWithCleanup(env, inParams, inOpt, func() (int, FixtureCleanupFunc, error) { + cleanup := func() { + cleanupCalledBack++ + } + return 2, cleanup, nil + }) + require.Equal(t, 2, res) + }) + t.Run("SkipAdditionalCache", func(t *testing.T) { + test := &testMock{name: t.Name()} + env := newTestEnv(test) - res := CacheWithCleanup(env, inParams, inOpt, func() (int, FixtureCleanupFunc, error) { - cleanup := func() { - cleanupCalledBack++ + f1 := func() int { + return CacheWithCleanup(env, nil, nil, func() (int, FixtureCleanupFunc, error) { + return 1, nil, nil + }) } - return 2, cleanup, nil + f2 := func() int { + return CacheWithCleanup(env, nil, nil, func() (int, FixtureCleanupFunc, error) { + return 2, nil, nil + }) + } + + require.Equal(t, 1, f1()) + require.Equal(t, 2, f2()) }) - require.Equal(t, 2, res) } diff --git a/interface.go b/interface.go index c9c4e25..866cf2c 100644 --- a/interface.go +++ b/interface.go @@ -72,6 +72,8 @@ type FixtureOptions struct { // Scope for cache result Scope CacheScope + additionlSkipExternalCalls int + // cleanupFunc if not nil - called for cleanup fixture results // internal implementation details cleanupFunc FixtureCleanupFunc