From c3aae49387bc32375e84bd42fa89fbfe17719b22 Mon Sep 17 00:00:00 2001 From: rekby Date: Sat, 28 Aug 2021 21:47:09 +0300 Subject: [PATCH 1/3] fix module name --- examples/custom_env/custom_env_test.go | 3 ++- .../custom_env_with_shared_content_test.go | 3 ++- examples/simple/http_server_test.go | 3 ++- examples/simple/package_scope_test.go | 3 ++- examples/simple/simple_test.go | 3 ++- go.mod | 2 +- 6 files changed, 11 insertions(+), 6 deletions(-) diff --git a/examples/custom_env/custom_env_test.go b/examples/custom_env/custom_env_test.go index b4a2d47..789cd94 100644 --- a/examples/custom_env/custom_env_test.go +++ b/examples/custom_env/custom_env_test.go @@ -2,12 +2,13 @@ package custom_env import ( "context" - "fixenv" "io" "net/http" "net/http/httptest" "testing" + "github.com/rekby/fixenv" + "github.com/stretchr/testify/assert" ) diff --git a/examples/custom_env_with_shared_content/custom_env_with_shared_content_test.go b/examples/custom_env_with_shared_content/custom_env_with_shared_content_test.go index 94be6aa..a213655 100644 --- a/examples/custom_env_with_shared_content/custom_env_with_shared_content_test.go +++ b/examples/custom_env_with_shared_content/custom_env_with_shared_content_test.go @@ -1,12 +1,13 @@ package custom_env_with_shared_content import ( - "fixenv" "io" "net/http" "net/http/httptest" "testing" + "github.com/rekby/fixenv" + "github.com/stretchr/testify/assert" ) diff --git a/examples/simple/http_server_test.go b/examples/simple/http_server_test.go index 6c384c9..2504914 100644 --- a/examples/simple/http_server_test.go +++ b/examples/simple/http_server_test.go @@ -1,12 +1,13 @@ package simple import ( - "fixenv" "io" "net/http" "net/http/httptest" "testing" + "github.com/rekby/fixenv" + "github.com/stretchr/testify/assert" ) diff --git a/examples/simple/package_scope_test.go b/examples/simple/package_scope_test.go index 327ed6e..f95fffc 100644 --- a/examples/simple/package_scope_test.go +++ b/examples/simple/package_scope_test.go @@ -1,8 +1,9 @@ package simple import ( - "fixenv" "testing" + + "github.com/rekby/fixenv" ) var ( diff --git a/examples/simple/simple_test.go b/examples/simple/simple_test.go index a8b541b..44d05c7 100644 --- a/examples/simple/simple_test.go +++ b/examples/simple/simple_test.go @@ -1,8 +1,9 @@ package simple import ( - "fixenv" "testing" + + "github.com/rekby/fixenv" ) var ( diff --git a/go.mod b/go.mod index 05b8bfd..933bd5a 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module fixenv +module github.com/rekby/fixenv go 1.16 From 0137c96459330c0a860b0448300e5eb583f10df4 Mon Sep 17 00:00:00 2001 From: rekby Date: Sat, 28 Aug 2021 21:49:19 +0300 Subject: [PATCH 2/3] fix test --- env_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env_test.go b/env_test.go index 6f058ac..9ba354f 100644 --- a/env_test.go +++ b/env_test.go @@ -411,7 +411,7 @@ func Test_MakeCacheKey(t *testing.T) { envFunc() at.NoError(err) - expected := cacheKey(`{"func":"fixenv.Test_MakeCacheKey","fname":".../env_test.go","scope":0,"scope_name":"asdf","params":222}`) + expected := cacheKey(`{"func":"github.com/rekby/fixenv.Test_MakeCacheKey","fname":".../env_test.go","scope":0,"scope_name":"asdf","params":222}`) at.JSONEq(string(expected), string(res)) } From edb671b5cbecb3662560eadd037bdb285689fa63 Mon Sep 17 00:00:00 2001 From: rekby Date: Sun, 5 Sep 2021 21:32:46 +0300 Subject: [PATCH 3/3] * remove Cleanup method from env interface * improove documentation --- env.go | 23 +++++++++++++++++++---- env_test.go | 11 ----------- examples/custom_env/custom_env_test.go | 2 +- fixture.go | 1 - interface.go | 26 ++++++++++++++++++++++---- maintest.go | 9 +++++++++ 6 files changed, 51 insertions(+), 21 deletions(-) delete mode 100644 fixture.go diff --git a/env.go b/env.go index f0ac8c5..d181d25 100644 --- a/env.go +++ b/env.go @@ -20,6 +20,11 @@ var ( globalScopeInfo = make(map[string]*scopeInfo) ) +// EnvT - fixture cache and cleanup engine +// it created from test and pass to fixture function +// manage cache of fixtures, depends from fixture, param, test, scope. +// and call cleanup, when scope closed. +// It can be base to own, more powerful local environments. type EnvT struct { t T c *cache @@ -28,6 +33,7 @@ type EnvT struct { scopes map[string]*scopeInfo } +// NewEnv create EnvT from test func NewEnv(t T) *EnvT { env := newEnv(t, globalCache, globalMutex, globalScopeInfo) env.onCreate() @@ -43,10 +49,20 @@ func newEnv(t T, c *cache, m sync.Locker, scopes map[string]*scopeInfo) *EnvT { } } +// T return test from EnvT created func (e *EnvT) T() T { return e.t } +// Cache call from fixture and manage call f and cache it. +// Cache must be called direct from fixture - it use runtime stacktrace for +// detect called method - it is part of cache key. +// params - part of cache key. Usually - parameters, passed to fixture. +// it allow use parametrized fixtures with different results. +// params must be json serializable. +// opt - fixture options, nil for default options. +// f - callback - fixture body. +// Cache guarantee for call f exactly once for same Cache called and params combination. func (e *EnvT) Cache(params interface{}, opt *FixtureOptions, f FixtureCallbackFunc) interface{} { if opt == nil { opt = globalEmptyFixtureOptions @@ -68,10 +84,8 @@ func (e *EnvT) Cache(params interface{}, opt *FixtureOptions, f FixtureCallbackF return res } -func (e *EnvT) Cleanup(f func()) { - e.T().Cleanup(f) -} - +// tearDown called from base test cleanup +// it clean env cache and call fixture's cleanups for the scope. func (e *EnvT) tearDown() { e.m.Lock() defer e.m.Unlock() @@ -86,6 +100,7 @@ func (e *EnvT) tearDown() { } } +// onCreate register env in internal stuctures. func (e *EnvT) onCreate() { e.m.Lock() defer e.m.Unlock() diff --git a/env_test.go b/env_test.go index 9ba354f..a7501f9 100644 --- a/env_test.go +++ b/env_test.go @@ -316,17 +316,6 @@ func Test_FixtureWrapper(t *testing.T) { }) } -func Test_Env_Cleanup(t *testing.T) { - at := assert.New(t) - tMock := &testMock{} - - e := newTestEnv(tMock) - cleanups := len(tMock.cleanups) - - e.Cleanup(func() {}) - at.Len(tMock.cleanups, cleanups+1) -} - func Test_Env_T(t *testing.T) { at := assert.New(t) e := NewEnv(t) diff --git a/examples/custom_env/custom_env_test.go b/examples/custom_env/custom_env_test.go index 789cd94..36b39d6 100644 --- a/examples/custom_env/custom_env_test.go +++ b/examples/custom_env/custom_env_test.go @@ -22,7 +22,7 @@ func NewEnv(t *testing.T) (context.Context, *Env) { at := assert.New(t) fEnv := fixenv.NewEnv(t) ctx, ctxCancel := context.WithCancel(context.Background()) - fEnv.Cleanup(func() { + t.Cleanup(func() { ctxCancel() }) res := &Env{ diff --git a/fixture.go b/fixture.go deleted file mode 100644 index 28be818..0000000 --- a/fixture.go +++ /dev/null @@ -1 +0,0 @@ -package fixenv diff --git a/interface.go b/interface.go index 2a5fc1e..5f2e7e7 100644 --- a/interface.go +++ b/interface.go @@ -9,12 +9,11 @@ type Env interface { // f call exactly once for every combination of scope and params // params must be json serializable (deserialize not need) Cache(params interface{}, opt *FixtureOptions, f FixtureCallbackFunc) interface{} - - // Cleanup add callback cleanup function - // f called while env clean - Cleanup(f func()) } +// CacheScope define life time of fixture value +// and allow use independent fixture values for different scopes, but share same value for +// one scope, which can be more then one test type CacheScope int const ( @@ -37,6 +36,8 @@ const ( // then cache error about unexpected exit type FixtureCallbackFunc func() (res interface{}, err error) +// FixtureCleanupFunc - callback function for cleanup after +// fixture value out from lifetime scope type FixtureCleanupFunc func() type FixtureOptions struct { @@ -50,7 +51,24 @@ type FixtureOptions struct { // T is subtype of testing.TB type T interface { + // Cleanup registers a function to be called when the test (or subtest) and all its subtests complete. + // Cleanup functions will be called in last added, first called order. Cleanup(func()) + + // Fatalf is equivalent to Logf followed by FailNow. + // + // Logf formats its arguments according to the format, analogous to Printf, and records the text in the error log. + // A final newline is added if not provided. For tests, the text will be printed only if the test fails or the -test.v flag is set. + // For benchmarks, the text is always printed to avoid having performance depend on the value of the -test.v flag. + // + // FailNow marks the function as having failed and stops its execution by calling runtime.Goexit + // (which then runs all deferred calls in the current goroutine). Execution will continue at the next test or benchmark. FailNow must be called from the goroutine running the test or benchmark function, not from other goroutines created during the test. Calling FailNow does not stop those other goroutines. Fatalf(format string, args ...interface{}) + + // Name returns the name of the running (sub-) test or benchmark. + // + // The name will include the name of the test along with the names + // of any nested sub-tests. If two sibling sub-tests have the same name, + // Name will append a suffix to guarantee the returned name is unique. Name() string } diff --git a/maintest.go b/maintest.go index 2cba86b..f2248de 100644 --- a/maintest.go +++ b/maintest.go @@ -6,10 +6,18 @@ import ( ) type FatalfFunction func(format string, args ...interface{}) + type CreateMainTestEnvOpts struct { + // Fatalf equivalent of Fatalf in test. + // Must write log, then exit from goroutine. + // It may be panic. + // Fatalf called if main envinment can't continue work Fatalf FatalfFunction } +// CreateMainTestEnv called from TestMain for create global environment. +// It need only for use ScopePackage cache scope. +// If ScopePackage not used - no need to create main env. func CreateMainTestEnv(opts *CreateMainTestEnvOpts) (env *EnvT, tearDown func()) { globalMutex.Lock() packageLevelVirtualTest := newVirtualTest(opts) @@ -19,6 +27,7 @@ func CreateMainTestEnv(opts *CreateMainTestEnvOpts) (env *EnvT, tearDown func()) return env, packageLevelVirtualTest.cleanup } +// virtualTest implement T interface for global env scope type virtualTest struct { m sync.Mutex fatalf FatalfFunction