Skip to content

Commit

Permalink
* remove Cleanup method from env interface
Browse files Browse the repository at this point in the history
* improove documentation
  • Loading branch information
rekby committed Sep 5, 2021
1 parent 0137c96 commit edb671b
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 21 deletions.
23 changes: 19 additions & 4 deletions env.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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()
Expand All @@ -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
Expand All @@ -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()
Expand All @@ -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()
Expand Down
11 changes: 0 additions & 11 deletions env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion examples/custom_env/custom_env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down
1 change: 0 additions & 1 deletion fixture.go

This file was deleted.

26 changes: 22 additions & 4 deletions interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand All @@ -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 {
Expand All @@ -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
}
9 changes: 9 additions & 0 deletions maintest.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down

0 comments on commit edb671b

Please sign in to comment.