diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 0b07b7e..40f55ab 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -29,10 +29,16 @@ jobs: - name: Build run: go build -v ./... + - name: Build examples + run: cd examples; go build -v ./... + - name: Test run: go test ./... - - name: Test with coverage profiler + - name: Test examples + run: cd examples; go test ./... + + - name: Test library with coverage profiler if: ${{ matrix.goVersion == env.GO_VERSION }} run: go test -test.count=10 -race -covermode atomic -coverprofile=covprofile.out ./... @@ -42,6 +48,13 @@ jobs: with: version: latest + - name: golangci-lint examples + if: ${{ matrix.goVersion == env.GO_VERSION }} + uses: golangci/golangci-lint-action@v2 + with: + version: latest + working-directory: examples + - name: Coveralls install goveralls if: ${{ matrix.goVersion == env.GO_VERSION }} run: go install github.com/mattn/goveralls@latest diff --git a/cache_test.go b/cache_test.go index dd145db..16f430a 100644 --- a/cache_test.go +++ b/cache_test.go @@ -8,16 +8,12 @@ import ( "sync/atomic" "testing" "time" - - "github.com/stretchr/testify/assert" ) const waitTime = time.Second / 10 func TestCache_DeleteKeys(t *testing.T) { t.Run("simple", func(t *testing.T) { - at := assert.New(t) - c := newCache() k1 := cacheKey("k1") k2 := cacheKey("k2") @@ -33,25 +29,23 @@ func TestCache_DeleteKeys(t *testing.T) { c.DeleteKeys(k1, k2) _, ok := c.get(k1) - at.False(ok) + requireFalse(t, ok) _, ok = c.get(k2) - at.False(ok) + requireFalse(t, ok) res, ok := c.get(k3) - at.True(ok) - at.Equal(val1, res.res.Value) + requireTrue(t, ok) + requireEquals(t, val1, res.res.Value.(string)) val2 := "test2" c.setOnce(k1, func() (res *Result, err error) { return NewResult(val2), nil }) res, ok = c.get(k1) - at.True(ok) - at.Equal(val2, res.res.Value) + requireTrue(t, ok) + requireEquals(t, val2, res.res.Value.(string)) }) t.Run("mutex", func(t *testing.T) { - at := assert.New(t) - c := newCache() c.setOnce("asd", func() (res *Result, err error) { return NewResult(nil), nil @@ -66,33 +60,31 @@ func TestCache_DeleteKeys(t *testing.T) { }() time.Sleep(waitTime) - at.Len(c.store, 1) - at.Len(c.setLocks, 1) + requireEquals(t, len(c.store), 1) + requireEquals(t, len(c.setLocks), 1) c.m.RUnlock() wg.Wait() - at.Len(c.store, 0) - at.Len(c.setLocks, 0) + requireEquals(t, len(c.store), 0) + requireEquals(t, len(c.setLocks), 0) }) } func TestCache_Get(t *testing.T) { t.Run("simple", func(t *testing.T) { - at := assert.New(t) c := newCache() _, ok := c.get("qwe") - at.False(ok) + requireFalse(t, ok) c.store["asd"] = cacheVal{res: NewResult("val")} res, ok := c.get("asd") - at.True(ok) - at.Equal(cacheVal{res: NewResult("val")}, res) + requireTrue(t, ok) + requireEquals(t, cacheVal{res: NewResult("val")}, res) }) t.Run("read_mutex", func(t *testing.T) { - at := assert.New(t) c := newCache() c.setOnce("asd", func() (res *Result, err error) { return NewResult(nil), nil @@ -100,11 +92,10 @@ func TestCache_Get(t *testing.T) { c.m.RLock() _, ok := c.get("asd") c.m.RUnlock() - at.True(ok) + requireTrue(t, ok) }) t.Run("write_mutex", func(t *testing.T) { - at := assert.New(t) c := newCache() c.setOnce("asd", func() (res *Result, err error) { return NewResult(nil), nil @@ -119,20 +110,18 @@ func TestCache_Get(t *testing.T) { }() time.Sleep(waitTime) - at.False(ok) + requireFalse(t, ok) c.m.Unlock() wg.Wait() - at.True(ok) + requireTrue(t, ok) }) } func TestCache_SetOnce(t *testing.T) { t.Run("save_new_key", func(t *testing.T) { - at := assert.New(t) - c := newCache() cnt := 0 key1 := cacheKey("1") @@ -140,21 +129,20 @@ func TestCache_SetOnce(t *testing.T) { cnt++ return NewResult(1), nil }) - at.Equal(1, cnt) - at.Equal(1, c.store[key1].res.Value) - at.NoError(c.store[key1].err) + requireEquals(t, 1, cnt) + requireEquals(t, 1, c.store[key1].res.Value) + noError(t, c.store[key1].err) c.setOnce(key1, func() (res *Result, err error) { cnt++ return NewResult(2), nil }) - at.Equal(1, cnt) - at.Equal(1, c.store[key1].res.Value) - at.NoError(c.store[key1].err) + requireEquals(t, 1, cnt) + requireEquals(t, 1, c.store[key1].res.Value) + noError(t, c.store[key1].err) }) t.Run("second_set_val", func(t *testing.T) { - at := assert.New(t) c := newCache() key1 := cacheKey("1") key2 := cacheKey("2") @@ -167,16 +155,15 @@ func TestCache_SetOnce(t *testing.T) { cnt++ return NewResult(2), nil }) - at.Equal(2, cnt) - at.Equal(1, c.store[key1].res.Value) - at.NoError(c.store[key1].err) - at.Equal(2, c.store[key2].res.Value) - at.NoError(c.store[key2].err) + requireEquals(t, 2, cnt) + requireEquals(t, 1, c.store[key1].res.Value) + noError(t, c.store[key1].err) + requireEquals(t, 2, c.store[key2].res.Value) + noError(t, c.store[key2].err) }) // exit without return value t.Run("exit_without_return", func(t *testing.T) { - at := assert.New(t) c := newCache() key := cacheKey("3") var wg sync.WaitGroup @@ -190,12 +177,11 @@ func TestCache_SetOnce(t *testing.T) { }() wg.Wait() - at.Nil(c.store[key].res) - at.Error(c.store[key].err) + requireNil(t, c.store[key].res) + isError(t, c.store[key].err) }) t.Run("second_func_same_key_wait", func(t *testing.T) { - at := assert.New(t) c := newCache() key := cacheKey("1") @@ -239,8 +225,8 @@ func TestCache_SetOnce(t *testing.T) { // second not work until first finished doneSecondVal := atomic.LoadInt64(&doneSecond) _, ok := c.store[key] - at.False(ok) - at.Equal(int64(0), doneSecondVal) + requireFalse(t, ok) + requireEquals(t, int64(0), doneSecondVal) close(firstMuNeedFinish) @@ -251,12 +237,11 @@ func TestCache_SetOnce(t *testing.T) { <-secondFinished doneSecondVal = atomic.LoadInt64(&doneSecond) - at.Equal(1, c.store[key].res.Value) - at.Equal(int64(1), doneSecondVal) + requireEquals(t, 1, c.store[key].res.Value) + requireEquals(t, int64(1), doneSecondVal) }) t.Run("second_func_other_key_work", func(t *testing.T) { - at := assert.New(t) c := newCache() key1 := cacheKey("1") key2 := cacheKey("2") @@ -295,8 +280,8 @@ func TestCache_SetOnce(t *testing.T) { // wait first func finished <-firstMuFinished - at.Equal(1, c.store[key1].res.Value) - at.Equal(2, c.store[key2].res.Value) + requireEquals(t, 1, c.store[key1].res.Value) + requireEquals(t, 2, c.store[key2].res.Value) }) } diff --git a/env_generic_sugar_test.go b/env_generic_sugar_test.go index 0ff0793..af0c347 100644 --- a/env_generic_sugar_test.go +++ b/env_generic_sugar_test.go @@ -6,11 +6,8 @@ package fixenv import ( "fmt" "github.com/rekby/fixenv/internal" - "github.com/stretchr/testify/assert" "math/rand" "testing" - - "github.com/stretchr/testify/require" ) func TestCacheGeneric(t *testing.T) { @@ -21,8 +18,8 @@ func TestCacheGeneric(t *testing.T) { env := envMock{ onCacheResult: func(opts CacheOptions, f FixtureFunction) interface{} { opts.additionlSkipExternalCalls-- - require.Equal(t, inParams, opts.CacheKey) - require.Equal(t, inOpt.Scope, opts.Scope) + requireEquals(t, inParams, opts.CacheKey) + requireEquals(t, inOpt.Scope, opts.Scope) res, _ := f() return res.Value }, @@ -31,7 +28,7 @@ func TestCacheGeneric(t *testing.T) { res := Cache(env, inParams, inOpt, func() (int, error) { return 2, nil }) - require.Equal(t, 2, res) + requireEquals(t, 2, res) }) t.Run("SkipAdditionalCache", func(t *testing.T) { test := &internal.TestMock{TestName: t.Name()} @@ -48,8 +45,8 @@ func TestCacheGeneric(t *testing.T) { }) } - require.Equal(t, 1, f1()) - require.Equal(t, 2, f2()) + requireEquals(t, 1, f1()) + requireEquals(t, 2, f2()) }) } @@ -62,8 +59,8 @@ func TestCacheWithCleanupGeneric(t *testing.T) { env := envMock{ onCacheResult: func(opts CacheOptions, f FixtureFunction) interface{} { - require.Equal(t, inParams, opts.CacheKey) - require.Equal(t, inOpt.Scope, opts.Scope) + requireEquals(t, inParams, opts.CacheKey) + requireEquals(t, inOpt.Scope, opts.Scope) res, _ := f() return res.Value }, @@ -75,7 +72,7 @@ func TestCacheWithCleanupGeneric(t *testing.T) { } return 2, cleanup, nil }) - require.Equal(t, 2, res) + requireEquals(t, 2, res) }) t.Run("SkipAdditionalCache", func(t *testing.T) { test := &internal.TestMock{TestName: t.Name()} @@ -92,8 +89,8 @@ func TestCacheWithCleanupGeneric(t *testing.T) { }) } - require.Equal(t, 1, f1()) - require.Equal(t, 2, f2()) + requireEquals(t, 1, f1()) + requireEquals(t, 2, f2()) }) } @@ -108,7 +105,7 @@ func TestCacheResultGeneric(t *testing.T) { env := envMock{onCacheResult: func(opt CacheOptions, f FixtureFunction) interface{} { opt.additionlSkipExternalCalls-- - require.Equal(t, inOpt, opt) + requireEquals(t, inOpt, opt) res, _ := f() return res.Value }} @@ -120,7 +117,7 @@ func TestCacheResultGeneric(t *testing.T) { return NewGenericResultWithCleanup(2, cleanup), nil } res := CacheResult(env, f, inOpt) - require.Equal(t, 2, res) + requireEquals(t, 2, res) }) t.Run("SkipAdditionalCache", func(t *testing.T) { test := &internal.TestMock{TestName: t.Name()} @@ -137,14 +134,13 @@ func TestCacheResultGeneric(t *testing.T) { }) } - require.Equal(t, 1, f1()) - require.Equal(t, 2, f2()) + requireEquals(t, 1, f1()) + requireEquals(t, 2, f2()) }) } func TestCacheResultPanic(t *testing.T) { t.Run("Simple", func(t *testing.T) { - at := assert.New(t) tMock := &internal.TestMock{TestName: "mock", SkipGoexit: true} e := New(tMock) @@ -156,10 +152,9 @@ func TestCacheResultPanic(t *testing.T) { first := rndFix(e) second := rndFix(e) - at.Equal(first, second) + requireEquals(t, first, second) }) t.Run("Options", func(t *testing.T) { - at := assert.New(t) tMock := &internal.TestMock{TestName: "mock", SkipGoexit: true} e := New(tMock) @@ -173,12 +168,11 @@ func TestCacheResultPanic(t *testing.T) { second1 := rndFix(e, "second") second2 := rndFix(e, "second") - at.Equal(first1, first2) - at.Equal(second1, second2) - at.NotEqual(first1, second1) + requireEquals(t, first1, first2) + requireEquals(t, second1, second2) + requireNotEquals(t, first1, second1) }) t.Run("Panic", func(t *testing.T) { - at := assert.New(t) tMock := &internal.TestMock{TestName: "mock", SkipGoexit: true} e := New(tMock) @@ -187,7 +181,7 @@ func TestCacheResultPanic(t *testing.T) { return NewGenericResult(rand.Int()), nil }, CacheOptions{CacheKey: name}, CacheOptions{CacheKey: name}) } - at.Panics(func() { + requirePanic(t, func() { rndFix(e, "first") }) }) diff --git a/env_test.go b/env_test.go index 72b5b5b..c2a053d 100644 --- a/env_test.go +++ b/env_test.go @@ -7,9 +7,6 @@ import ( "runtime" "sync" "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func (e *EnvT) cloneWithTest(t T) *EnvT { @@ -27,40 +24,36 @@ func newTestEnv(t T) *EnvT { func Test_Env__NewEnv(t *testing.T) { t.Run("create_new_env", func(t *testing.T) { initGlobalState() - at := assert.New(t) tMock := &internal.TestMock{TestName: "mock"} defer tMock.CallCleanup() e := New(tMock) - at.Equal(tMock, e.t) - at.Equal(globalCache, e.c) - at.Equal(&globalMutex, e.m) - at.Equal(globalScopeInfo, e.scopes) - at.Len(globalCache.store, 0) - at.Len(globalScopeInfo, 1) - at.Len(tMock.Cleanups, 1) + requireEquals(t, tMock, e.t) + requireEquals(t, globalCache, e.c) + requireEquals(t, &globalMutex, e.m) + requireEquals(t, globalScopeInfo, e.scopes) + requireEquals(t, len(globalCache.store), 0) + requireEquals(t, len(globalScopeInfo), 1) + requireEquals(t, len(tMock.Cleanups), 1) }) t.Run("global_info_cleaned", func(t *testing.T) { - at := assert.New(t) - at.Len(globalCache.store, 0) - at.Len(globalScopeInfo, 0) + requireEquals(t, len(globalCache.store), 0) + requireEquals(t, len(globalScopeInfo), 0) }) t.Run("double_env_same_scope_same_time", func(t *testing.T) { - at := assert.New(t) - tMock := &internal.TestMock{TestName: "mock"} defer tMock.CallCleanup() _ = New(tMock) - at.Len(tMock.Fatals, 0) + requireEquals(t, len(tMock.Fatals), 0) runUntilFatal(func() { _ = New(tMock) }) - at.Len(tMock.Fatals, 1) + requireEquals(t, len(tMock.Fatals), 1) }) t.Run("double_env_similar_scope_different_time", func(t *testing.T) { @@ -81,7 +74,6 @@ func testFailedFixture(env Env) { func Test_Env_Cache(t *testing.T) { t.Run("simple", func(t *testing.T) { - at := assert.New(t) e := New(t) val := 0 @@ -94,15 +86,14 @@ func Test_Env_Cache(t *testing.T) { return res.(int) } - at.Equal(1, cntF()) - at.Equal(1, cntF()) + requireEquals(t, 1, cntF()) + requireEquals(t, 1, cntF()) val = 2 - at.Equal(1, cntF()) + requireEquals(t, 1, cntF()) }) t.Run("subtest_and_test_scope", func(t *testing.T) { - at := assert.New(t) e := New(t) val := 0 @@ -114,22 +105,20 @@ func Test_Env_Cache(t *testing.T) { return res.(int) } - at.Equal(1, cntF(e)) - at.Equal(1, cntF(e)) + requireEquals(t, 1, cntF(e)) + requireEquals(t, 1, cntF(e)) t.Run("subtest", func(t *testing.T) { - at := assert.New(t) subEnv := New(t) - at.Equal(2, cntF(subEnv)) - at.Equal(2, cntF(subEnv)) + requireEquals(t, 2, cntF(subEnv)) + requireEquals(t, 2, cntF(subEnv)) }) - at.Equal(1, cntF(e)) + requireEquals(t, 1, cntF(e)) }) t.Run("subtest_and_package_scope", func(t *testing.T) { - at := assert.New(t) e := New(t) _, mainClose := CreateMainTestEnv(nil) defer mainClose() @@ -143,41 +132,36 @@ func Test_Env_Cache(t *testing.T) { return res.(int) } - at.Equal(1, cntF(e)) - at.Equal(1, cntF(e)) + requireEquals(t, 1, cntF(e)) + requireEquals(t, 1, cntF(e)) t.Run("subtest", func(t *testing.T) { - at := assert.New(t) subEnv := New(t) - at.Equal(1, cntF(subEnv)) - at.Equal(1, cntF(subEnv)) + requireEquals(t, 1, cntF(subEnv)) + requireEquals(t, 1, cntF(subEnv)) }) - at.Equal(1, cntF(e)) + requireEquals(t, 1, cntF(e)) }) t.Run("fail_on_fixture_err", func(t *testing.T) { - at := assert.New(t) - tMock := &internal.TestMock{TestName: "mock"} defer tMock.CallCleanup() e := newTestEnv(tMock) - at.Len(tMock.Fatals, 0) + requireEquals(t, len(tMock.Fatals), 0) runUntilFatal(func() { testFailedFixture(e) }) - at.Len(tMock.Fatals, 1) + requireEquals(t, len(tMock.Fatals), 1) // log message contains fixture name - at.Contains(tMock.Fatals[0].ResultString, "testFailedFixture") + requireContains(t, tMock.Fatals[0].ResultString, "testFailedFixture") }) t.Run("not_serializable_param", func(t *testing.T) { - at := assert.New(t) - type paramT struct { F func() // can't serialize func to json } @@ -190,11 +174,10 @@ func Test_Env_Cache(t *testing.T) { return nil, nil }) }) - at.Len(tMock.Fatals, 1) + requireEquals(t, len(tMock.Fatals), 1) }) t.Run("cache_by_caller_func", func(t *testing.T) { - at := assert.New(t) tMock := &internal.TestMock{TestName: "mock"} e := newTestEnv(tMock) @@ -203,17 +186,16 @@ func Test_Env_Cache(t *testing.T) { cnt++ return cnt, nil }) - at.Equal(1, res) + requireEquals(t, 1, res) res = e.Cache(nil, &FixtureOptions{Scope: ScopeTest}, func() (res interface{}, err error) { cnt++ return cnt, nil }) - at.Equal(1, res) + requireEquals(t, 1, res) }) t.Run("different_cache_for_diff_anonim_function", func(t *testing.T) { - at := assert.New(t) tMock := &internal.TestMock{TestName: "mock"} e := newTestEnv(tMock) @@ -223,7 +205,7 @@ func Test_Env_Cache(t *testing.T) { cnt++ return cnt, nil }) - at.Equal(1, res) + requireEquals(t, 1, res) }() func() { @@ -231,22 +213,20 @@ func Test_Env_Cache(t *testing.T) { cnt++ return cnt, nil }) - at.Equal(2, res) + requireEquals(t, 2, res) }() }) t.Run("check_unreachable_code", func(t *testing.T) { - at := assert.New(t) - tMock := &internal.TestMock{TestName: "mock", SkipGoexit: true} e := New(tMock) - at.Panics(func() { + requirePanic(t, func() { e.Cache(nil, nil, func() (res interface{}, err error) { return nil, ErrSkipTest }) }) - at.Equal(1, tMock.SkipCount) + requireEquals(t, 1, tMock.SkipCount) }) } @@ -262,13 +242,13 @@ func Test_Env_CacheWithCleanup(t *testing.T) { } res := env.CacheWithCleanup(nil, nil, callbackFunc) - require.Equal(t, 1, res) - require.Equal(t, 1, callbackCalled) + requireEquals(t, 1, res) + requireEquals(t, 1, callbackCalled) // got value from cache res = env.CacheWithCleanup(nil, nil, callbackFunc) - require.Equal(t, 1, res) - require.Equal(t, 1, callbackCalled) + requireEquals(t, 1, res) + requireEquals(t, 1, callbackCalled) }) t.Run("WithCleanup", func(t *testing.T) { @@ -286,25 +266,24 @@ func Test_Env_CacheWithCleanup(t *testing.T) { } res := env.CacheWithCleanup(nil, nil, callbackFunc) - require.Equal(t, 1, res) - require.Equal(t, 1, callbackCalled) - require.Equal(t, cleanupCalled, 0) + requireEquals(t, 1, res) + requireEquals(t, 1, callbackCalled) + requireEquals(t, cleanupCalled, 0) // got value from cache res = env.CacheWithCleanup(nil, nil, callbackFunc) - require.Equal(t, 1, res) - require.Equal(t, 1, callbackCalled) - require.Equal(t, cleanupCalled, 0) + requireEquals(t, 1, res) + requireEquals(t, 1, callbackCalled) + requireEquals(t, cleanupCalled, 0) tMock.CallCleanup() - require.Equal(t, 1, callbackCalled) - require.Equal(t, 1, cleanupCalled) + requireEquals(t, 1, callbackCalled) + requireEquals(t, 1, cleanupCalled) }) } func Test_Env_CacheResult(t *testing.T) { t.Run("Simple", func(t *testing.T) { - at := assert.New(t) tMock := &internal.TestMock{TestName: "mock", SkipGoexit: true} e := New(tMock) @@ -316,10 +295,9 @@ func Test_Env_CacheResult(t *testing.T) { first := rndFix(e) second := rndFix(e) - at.Equal(first, second) + requireEquals(t, first, second) }) t.Run("Options", func(t *testing.T) { - at := assert.New(t) tMock := &internal.TestMock{TestName: "mock", SkipGoexit: true} e := New(tMock) @@ -333,9 +311,9 @@ func Test_Env_CacheResult(t *testing.T) { second1 := rndFix(e, "second") second2 := rndFix(e, "second") - at.Equal(first1, first2) - at.Equal(second1, second2) - at.NotEqual(first1, second1) + requireEquals(t, first1, first2) + requireEquals(t, second1, second2) + requireNotEquals(t, first1, second1) }) t.Run("WithCleanup", func(t *testing.T) { tMock := &internal.TestMock{TestName: t.Name()} @@ -352,22 +330,21 @@ func Test_Env_CacheResult(t *testing.T) { } res := env.CacheResult(callbackFunc) - require.Equal(t, 1, res) - require.Equal(t, 1, callbackCalled) - require.Equal(t, cleanupCalled, 0) + requireEquals(t, 1, res) + requireEquals(t, 1, callbackCalled) + requireEquals(t, cleanupCalled, 0) // got value from cache res = env.CacheResult(callbackFunc) - require.Equal(t, 1, res) - require.Equal(t, 1, callbackCalled) - require.Equal(t, cleanupCalled, 0) + requireEquals(t, 1, res) + requireEquals(t, 1, callbackCalled) + requireEquals(t, cleanupCalled, 0) tMock.CallCleanup() - require.Equal(t, 1, callbackCalled) - require.Equal(t, 1, cleanupCalled) + requireEquals(t, 1, callbackCalled) + requireEquals(t, 1, cleanupCalled) }) t.Run("Panic", func(t *testing.T) { - at := assert.New(t) tMock := &internal.TestMock{TestName: "mock", SkipGoexit: true} e := New(tMock) @@ -376,12 +353,11 @@ func Test_Env_CacheResult(t *testing.T) { return NewResult(rand.Int()), nil }, CacheOptions{CacheKey: name}, CacheOptions{CacheKey: name}).(int) } - at.Panics(func() { + requirePanic(t, func() { rndFix(e, "first") }) }) t.Run("WithNilResult", func(t *testing.T) { - at := assert.New(t) tMock := &internal.TestMock{TestName: "mock"} e := newTestEnv(tMock) @@ -398,14 +374,12 @@ func Test_Env_CacheResult(t *testing.T) { failedFix(e) }() <-done - at.Equal(1, len(tMock.Fatals)) + requireEquals(t, 1, len(tMock.Fatals)) }) } func Test_FixtureWrapper(t *testing.T) { t.Run("ok", func(t *testing.T) { - at := assert.New(t) - tMock := &internal.TestMock{TestName: "mock"} defer tMock.CallCleanup() @@ -418,13 +392,13 @@ func Test_FixtureWrapper(t *testing.T) { return NewResult(cnt), errors.New("test") }, CacheOptions{}) si := e.scopes[makeScopeName(tMock.Name(), ScopeTest)] - at.Equal(0, cnt) - at.Len(si.cacheKeys, 0) + requireEquals(t, 0, cnt) + requireEquals(t, len(si.cacheKeys), 0) res1, err := w() - at.Equal(1, res1.Value) - at.EqualError(err, "test") - at.Equal(1, cnt) - at.Equal([]cacheKey{key}, si.cacheKeys) + requireEquals(t, 1, res1.Value) + requireEquals(t, err.Error(), "test") + requireEquals(t, 1, cnt) + requireEquals(t, []cacheKey{key}, si.cacheKeys) cnt = 0 key2 := cacheKey("asd") @@ -434,15 +408,13 @@ func Test_FixtureWrapper(t *testing.T) { cleanup := func() {} return NewResultWithCleanup(cnt, cleanup), nil }, CacheOptions{}) - at.Len(tMock.Cleanups, cleanupsLen) + requireEquals(t, len(tMock.Cleanups), cleanupsLen) _, _ = w() - at.Equal([]cacheKey{key, key2}, si.cacheKeys) - at.Len(tMock.Cleanups, cleanupsLen+1) + requireEquals(t, []cacheKey{key, key2}, si.cacheKeys) + requireEquals(t, len(tMock.Cleanups), cleanupsLen+1) }) t.Run("unknown_scope_info", func(t *testing.T) { - at := assert.New(t) - tMock := &internal.TestMock{TestName: "mock"} defer tMock.CallCleanup() e := newTestEnv(tMock) @@ -457,12 +429,11 @@ func Test_FixtureWrapper(t *testing.T) { // revert test name for good cleanup tMock.TestName = "mock" - at.Len(tMock.Fatals, 1) + requireEquals(t, len(tMock.Fatals), 1) }) } func Test_Env_Skip(t *testing.T) { - at := assert.New(t) tm := &internal.TestMock{TestName: "mock"} tEnv := newTestEnv(tm) @@ -483,11 +454,11 @@ func Test_Env_Skip(t *testing.T) { go func() { callbackExited := true defer func() { - at.True(callbackExited) + requireTrue(t, callbackExited) panicValue := recover() // no panic value (go exit) - at.Nil(panicValue) + requireNil(t, panicValue) wg.Done() }() @@ -508,9 +479,9 @@ func Test_Env_Skip(t *testing.T) { executionStopped = false }) - at.True(executionStarted) - at.True(executionStopped) - at.Equal(1, skipFixtureCallTimes) + requireTrue(t, executionStarted) + requireTrue(t, executionStopped) + requireEquals(t, 1, skipFixtureCallTimes) // skip second time, without call fixture - from cache executionStarted = false @@ -522,29 +493,26 @@ func Test_Env_Skip(t *testing.T) { executionStopped = false }) - at.True(executionStarted) - at.True(executionStopped) - at.Equal(1, skipFixtureCallTimes) + requireTrue(t, executionStarted) + requireTrue(t, executionStopped) + requireEquals(t, 1, skipFixtureCallTimes) } func Test_Env_T(t *testing.T) { - at := assert.New(t) e := New(t) - at.Equal(t, e.T()) + requireEquals(t, t, e.T()) } func Test_Env_TearDown(t *testing.T) { t.Run("ok", func(t *testing.T) { - at := assert.New(t) - t1 := &internal.TestMock{TestName: "mock"} // defer t1.callCleanup - direct call e1.tearDown - for test e1 := newTestEnv(t1) - at.Len(e1.scopes, 1) - at.Len(e1.scopes[makeScopeName(t1.TestName, ScopeTest)].Keys(), 0) - at.Len(e1.c.store, 0) + requireEquals(t, len(e1.scopes), 1) + requireEquals(t, len(e1.scopes[makeScopeName(t1.TestName, ScopeTest)].Keys()), 0) + requireEquals(t, len(e1.c.store), 0) e1.CacheResult(func() (*Result, error) { return NewResult(nil), nil @@ -552,41 +520,40 @@ func Test_Env_TearDown(t *testing.T) { e1.CacheResult(func() (*Result, error) { return nil, nil }, CacheOptions{CacheKey: 2}) - at.Len(e1.scopes, 1) - at.Len(e1.scopes[makeScopeName(t1.TestName, ScopeTest)].Keys(), 2) - at.Len(e1.c.store, 2) + requireEquals(t, len(e1.scopes), 1) + requireEquals(t, len(e1.scopes[makeScopeName(t1.TestName, ScopeTest)].Keys()), 2) + requireEquals(t, len(e1.c.store), 2) t2 := &internal.TestMock{TestName: "mock2"} // defer t2.callCleanup - direct call e2.tearDown - for test e2 := e1.cloneWithTest(t2) - at.Len(e1.scopes, 2) - at.Len(e1.scopes[makeScopeName(t1.TestName, ScopeTest)].Keys(), 2) - at.Len(e1.scopes[makeScopeName(t2.TestName, ScopeTest)].Keys(), 0) - at.Len(e1.c.store, 2) + requireEquals(t, len(e1.scopes), 2) + requireEquals(t, len(e1.scopes[makeScopeName(t1.TestName, ScopeTest)].Keys()), 2) + requireEquals(t, len(e1.scopes[makeScopeName(t2.TestName, ScopeTest)].Keys()), 0) + requireEquals(t, len(e1.c.store), 2) e2.CacheResult(func() (*Result, error) { return nil, nil }, CacheOptions{CacheKey: 1}) - at.Len(e1.scopes, 2) - at.Len(e1.scopes[makeScopeName(t1.TestName, ScopeTest)].Keys(), 2) - at.Len(e1.scopes[makeScopeName(t2.TestName, ScopeTest)].Keys(), 1) - at.Len(e1.c.store, 3) + requireEquals(t, len(e1.scopes), 2) + requireEquals(t, len(e1.scopes[makeScopeName(t1.TestName, ScopeTest)].Keys()), 2) + requireEquals(t, len(e1.scopes[makeScopeName(t2.TestName, ScopeTest)].Keys()), 1) + requireEquals(t, len(e1.c.store), 3) // finish first test and tearDown e1 e1.tearDown() - at.Len(e1.scopes, 1) - at.Len(e1.scopes[makeScopeName(t2.TestName, ScopeTest)].Keys(), 1) - at.Len(e1.c.store, 1) + requireEquals(t, len(e1.scopes), 1) + requireEquals(t, len(e1.scopes[makeScopeName(t2.TestName, ScopeTest)].Keys()), 1) + requireEquals(t, len(e1.c.store), 1) e2.tearDown() - at.Len(e1.scopes, 0) - at.Len(e1.c.store, 0) + requireEquals(t, len(e1.scopes), 0) + requireEquals(t, len(e1.c.store), 0) }) t.Run("tearDown on unexisted scope", func(t *testing.T) { - at := assert.New(t) tMock := &internal.TestMock{TestName: "mock"} // defer tMock.callCleanups. e.tearDown will call directly for test e := newTestEnv(tMock) @@ -597,13 +564,11 @@ func Test_Env_TearDown(t *testing.T) { runUntilFatal(e.tearDown) - at.Len(tMock.Fatals, 1) + requireEquals(t, len(tMock.Fatals), 1) }) } func Test_MakeCacheKey(t *testing.T) { - at := assert.New(t) - var res cacheKey var err error @@ -615,23 +580,21 @@ func Test_MakeCacheKey(t *testing.T) { privateEnvFunc() } publicEnvFunc() // external caller - at.NoError(err) + noError(t, err) 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)) + requireJsonEquals(t, string(expected), string(res)) } func Test_MakeCacheKeyFromFrame(t *testing.T) { t.Run("ok", func(t *testing.T) { - at := assert.New(t) - key, err := makeCacheKeyFromFrame(123, ScopeTest, runtime.Frame{ PC: 0, Function: "func_name", File: "/asd/file_name.go", }, "scope-name", false) - at.NoError(err) - at.JSONEq(`{ + noError(t, err) + requireJsonEquals(t, `{ "scope": 0, "scope_name": "scope-name", "func": "func_name", @@ -641,15 +604,13 @@ func Test_MakeCacheKeyFromFrame(t *testing.T) { }) t.Run("test_call", func(t *testing.T) { - at := assert.New(t) - key, err := makeCacheKeyFromFrame(123, ScopeTest, runtime.Frame{ PC: 0, Function: "func_name", File: "/asd/file_name.go", }, "scope-name", true) - at.NoError(err) - at.JSONEq(`{ + noError(t, err) + requireJsonEquals(t, `{ "scope": 0, "scope_name": "scope-name", "func": "func_name", @@ -659,30 +620,24 @@ func Test_MakeCacheKeyFromFrame(t *testing.T) { }) t.Run("no_func_name", func(t *testing.T) { - at := assert.New(t) - _, err := makeCacheKeyFromFrame(123, ScopeTest, runtime.Frame{ PC: 0, Function: "", File: "/asd/file_name.go", }, "scope-name", true) - at.Error(err) + isError(t, err) }) t.Run("no_file_name", func(t *testing.T) { - at := assert.New(t) - _, err := makeCacheKeyFromFrame(123, ScopeTest, runtime.Frame{ PC: 0, Function: "func_name", File: "", }, "scope-name", true) - at.Error(err) + isError(t, err) }) t.Run("not_serializable_param", func(t *testing.T) { - at := assert.New(t) - type TStruct struct { F func() } @@ -692,7 +647,7 @@ func Test_MakeCacheKeyFromFrame(t *testing.T) { Function: "func_name", File: "/asd/file_name.go", }, "scope-name", true) - at.Error(err) + isError(t, err) }) } @@ -732,15 +687,13 @@ func Test_ScopeName(t *testing.T) { for _, c := range table { t.Run(c.name, func(t *testing.T) { - at := assert.New(t) - at.Equal(c.result, makeScopeName(c.testName, c.scope)) + requireEquals(t, c.result, makeScopeName(c.testName, c.scope)) }) } }) t.Run("unexpected_scope", func(t *testing.T) { - at := assert.New(t) - at.Panics(func() { + requirePanic(t, func() { makeScopeName("asd", -1) }) }) diff --git a/examples/go.mod b/examples/go.mod new file mode 100644 index 0000000..e1d9e77 --- /dev/null +++ b/examples/go.mod @@ -0,0 +1,16 @@ +module examples + +go 1.22.2 + +require ( + github.com/rekby/fixenv v0.0.0-00010101000000-000000000000 + github.com/stretchr/testify v1.9.0 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +replace github.com/rekby/fixenv => ../ diff --git a/examples/go.sum b/examples/go.sum new file mode 100644 index 0000000..60ce688 --- /dev/null +++ b/examples/go.sum @@ -0,0 +1,10 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/simple/use_cache_params_test.go b/examples/simple/use_cache_params_test.go index fb8fc45..641ca92 100644 --- a/examples/simple/use_cache_params_test.go +++ b/examples/simple/use_cache_params_test.go @@ -4,11 +4,11 @@ package simple import ( + "github.com/stretchr/testify/require" "math/rand" "testing" "github.com/rekby/fixenv" - "github.com/stretchr/testify/require" ) // namedRandom return random number for new name args diff --git a/go.mod b/go.mod index 27c0904..c65bece 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,3 @@ module github.com/rekby/fixenv go 1.18 - -require github.com/stretchr/testify v1.7.0 - -require ( - github.com/davecgh/go-spew v1.1.0 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect -) diff --git a/go.sum b/go.sum index 26500d5..e69de29 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +0,0 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/maintest_test.go b/maintest_test.go index ddea0f2..3d988fe 100644 --- a/maintest_test.go +++ b/maintest_test.go @@ -5,33 +5,29 @@ import ( "runtime" "sync" "testing" - - "github.com/stretchr/testify/assert" ) func TestCreateMainTestEnv(t *testing.T) { t.Run("simple", func(t *testing.T) { - at := assert.New(t) e, cancel := CreateMainTestEnv(nil) e.T().Logf("env created") - at.Equal(packageScopeName, e.t.Name()) - at.NotNil(globalScopeInfo[packageScopeName]) + + requireEquals(t, packageScopeName, e.t.Name()) + requireNotNil(t, globalScopeInfo[packageScopeName]) cancel() - at.Nil(globalScopeInfo[packageScopeName]) + requireNil(t, globalScopeInfo[packageScopeName]) }) t.Run("fatal_as_panic", func(t *testing.T) { - at := assert.New(t) e, cancel := CreateMainTestEnv(nil) defer cancel() - at.Panics(func() { + requirePanic(t, func() { e.T().Fatalf("asd") }) }) t.Run("opt_fatal", func(t *testing.T) { - at := assert.New(t) var fFormat string var fArgs []interface{} e, cancel := CreateMainTestEnv(&CreateMainTestEnvOpts{Fatalf: func(format string, args ...interface{}) { @@ -41,23 +37,21 @@ func TestCreateMainTestEnv(t *testing.T) { defer cancel() e.T().Fatalf("asd", 1, 2, 3) - at.Equal("asd", fFormat) - at.Equal([]interface{}{1, 2, 3}, fArgs) + requireEquals(t, "asd", fFormat) + requireEquals(t, []interface{}{1, 2, 3}, fArgs) }) t.Run("skip_now", func(t *testing.T) { t.Run("default", func(t *testing.T) { - at := assert.New(t) e, cancel := CreateMainTestEnv(nil) defer cancel() - at.Panics(func() { + requirePanic(t, func() { e.T().SkipNow() }) - at.True(e.T().Skipped()) + requireTrue(t, e.T().Skipped()) }) t.Run("opt", func(t *testing.T) { - at := assert.New(t) skipCalled := 0 e, cancel := CreateMainTestEnv(&CreateMainTestEnvOpts{SkipNow: func() { skipCalled++ @@ -72,8 +66,8 @@ func TestCreateMainTestEnv(t *testing.T) { e.T().SkipNow() }() wg.Wait() - at.Equal(1, skipCalled) - at.True(e.T().Skipped()) + requireEquals(t, 1, skipCalled) + requireTrue(t, e.T().Skipped()) }) }) } diff --git a/scope_info_test.go b/scope_info_test.go index be68fc0..435966f 100644 --- a/scope_info_test.go +++ b/scope_info_test.go @@ -6,21 +6,17 @@ import ( "sync" "testing" "time" - - "github.com/stretchr/testify/assert" ) func TestScopeInfo_AddKey(t *testing.T) { - at := assert.New(t) - t.Run("simple", func(t *testing.T) { si := newScopeInfo(t) - at.Equal(t, si.t) - at.Len(si.cacheKeys, 0) + requireEquals(t, t, si.t) + requireEquals(t, len(si.cacheKeys), 0) si.AddKey("asd") si.AddKey("ddd") - at.Equal([]cacheKey{"asd", "ddd"}, si.cacheKeys) + requireEquals(t, []cacheKey{"asd", "ddd"}, si.cacheKeys) }) t.Run("race", func(t *testing.T) { @@ -49,26 +45,21 @@ func TestScopeInfo_AddKey(t *testing.T) { return iInt < jInt }) - at := assert.New(t) - at.Equal(source, si.cacheKeys) + requireEquals(t, source, si.cacheKeys) }) } func TestScopeInfo_Keys(t *testing.T) { t.Run("simple", func(t *testing.T) { - at := assert.New(t) - si := newScopeInfo(t) si.AddKey("asd") si.AddKey("kkk") keys := si.Keys() - at.Equal([]cacheKey{"asd", "kkk"}, keys) + requireEquals(t, []cacheKey{"asd", "kkk"}, keys) }) t.Run("mutex", func(t *testing.T) { - at := assert.New(t) - si := newScopeInfo(t) si.AddKey("asd") si.AddKey("kkk") @@ -83,10 +74,10 @@ func TestScopeInfo_Keys(t *testing.T) { }() time.Sleep(waitTime) - at.Len(keys, 0) + requireEquals(t, len(keys), 0) si.m.Unlock() wg.Wait() - at.Equal([]cacheKey{"asd", "kkk"}, keys) + requireEquals(t, []cacheKey{"asd", "kkk"}, keys) }) } diff --git a/test_helpers.go b/test_helpers.go new file mode 100644 index 0000000..f56b072 --- /dev/null +++ b/test_helpers.go @@ -0,0 +1,114 @@ +package fixenv + +import ( + "encoding/json" + "reflect" + "strings" + "testing" +) + +func requireTrue(t *testing.T, val bool) { + t.Helper() + if !val { + t.Fatal("Must be true") + } +} + +func requireFalse(t *testing.T, val bool) { + t.Helper() + if val { + t.Fatal("Must be false") + } +} + +func requireEquals(t *testing.T, v1, v2 interface{}) { + t.Helper() + + if !reflect.DeepEqual(v1, v2) { + t.Fatal("Must be equals") + } +} + +func requireNotEquals(t *testing.T, v1, v2 interface{}) { + if reflect.DeepEqual(v1, v2) { + t.Fatal("Must be not equals") + } + +} + +func isError(t *testing.T, err error) { + t.Helper() + if err == nil { + t.Fatal("Must be error") + } +} +func noError(t *testing.T, err error) { + t.Helper() + if err != nil { + t.Fatalf("err must be nil, but got: %+v", err) + } +} + +func requireNil(t *testing.T, v interface{}) { + t.Helper() + if v == nil { + return + } + + val := reflect.ValueOf(v) + if !val.IsNil() { + t.Fatal("Must be nil") + } +} + +func requireNotNil(t *testing.T, v interface{}) { + t.Helper() + if v == nil { + return + } + + val := reflect.ValueOf(v) + if val.IsNil() { + t.Fatal("Must be not nil") + } +} + +func requireContains(t *testing.T, s, substr string) { + t.Helper() + if !strings.Contains(s, substr) { + t.Fatalf("'%s' must contains '%s'", s, substr) + } +} + +func requirePanic(t *testing.T, f func()) { + t.Helper() + defer func() { + recover() + }() + + f() + t.Fatal("the function must raise panic") +} + +func requireJsonEquals(t *testing.T, v1 string, v2 string) { + t.Helper() + var vj1 interface{} + var vj2 interface{} + + err := json.Unmarshal([]byte(v1), &vj1) + noError(t, err) + + err = json.Unmarshal([]byte(v2), &vj2) + noError(t, err) + + data1, err := json.Marshal(vj1) + noError(t, err) + + data2, err := json.Marshal(vj2) + noError(t, err) + + normalized1 := string(data1) + normalized2 := string(data2) + + requireEquals(t, normalized1, normalized2) +}