feat(defaults): expose a Default *Golden instance (#9)

Also change the Default* constants to variables so they can be modified
as well.
This commit is contained in:
2025-03-24 12:54:29 +00:00
committed by GitHub
parent 6817ec6101
commit e46dc124ff
2 changed files with 129 additions and 30 deletions

View File

@@ -122,30 +122,39 @@
package golden
import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
)
const (
DefaultDirMode = 0o755
DefaultFileMode = 0o644
DefaultSuffix = ".golden"
DefaultDirname = "testdata"
var (
// Default is the default *Golden instance. All package-level functions use
// the Default instance.
Default = New()
// DefaultDirMode is the default DirMode value used by New().
DefaultDirMode = os.FileMode(0o755)
// DefaultFileMode is the default FileMode value used by New().
DefaultFileMode = os.FileMode(0o644)
// DefaultSuffix is the default Suffix value used by New().
DefaultSuffix = ".golden"
// DefaultDirname is the default Dirname value used by New().
DefaultDirname = "testdata"
// DefaultUpdateFunc is the default UpdateFunc value used by New().
DefaultUpdateFunc = EnvUpdateFunc
)
var DefaultUpdateFunc = EnvUpdateFunc
var global = New()
// File returns the filename of the golden file for the given *testing.T
// instance as determined by t.Name().
func File(t *testing.T) string {
t.Helper()
return global.File(t)
return Default.File(t)
}
// Get returns the content of the golden file for the given *testing.T instance
@@ -154,7 +163,7 @@ func File(t *testing.T) string {
func Get(t *testing.T) []byte {
t.Helper()
return global.Get(t)
return Default.Get(t)
}
// Set writes given data to the golden file for the given *testing.T instance as
@@ -163,7 +172,7 @@ func Get(t *testing.T) []byte {
func Set(t *testing.T, data []byte) {
t.Helper()
global.Set(t, data)
Default.Set(t, data)
}
// FileP returns the filename of the specifically named golden file for the
@@ -171,7 +180,7 @@ func Set(t *testing.T, data []byte) {
func FileP(t *testing.T, name string) string {
t.Helper()
return global.FileP(t, name)
return Default.FileP(t, name)
}
// GetP returns the content of the specifically named golden file belonging
@@ -183,7 +192,7 @@ func FileP(t *testing.T, name string) string {
func GetP(t *testing.T, name string) []byte {
t.Helper()
return global.GetP(t, name)
return Default.GetP(t, name)
}
// SetP writes given data of the specifically named golden file belonging to
@@ -195,7 +204,7 @@ func GetP(t *testing.T, name string) []byte {
func SetP(t *testing.T, name string, data []byte) {
t.Helper()
global.SetP(t, name, data)
Default.SetP(t, name, data)
}
// Update returns true when golden is set to update golden files. Should be used
@@ -205,7 +214,7 @@ func SetP(t *testing.T, name string, data []byte) {
// environment variable is set to a truthy value. To customize create a custom
// *Golden instance with New() and set a new UpdateFunc value.
func Update() bool {
return global.Update()
return Default.Update()
}
// Golden handles all interactions with golden files. The top-level package
@@ -336,7 +345,7 @@ func (s *Golden) file(t *testing.T, name string) string {
func (s *Golden) get(t *testing.T, name string) []byte {
f := s.file(t, name)
b, err := ioutil.ReadFile(f)
b, err := os.ReadFile(f)
if err != nil {
t.Fatalf("golden: failed reading %s: %s", f, err.Error())
}
@@ -357,7 +366,7 @@ func (s *Golden) set(t *testing.T, name string, data []byte) {
return
}
err = ioutil.WriteFile(f, data, s.FileMode)
err = os.WriteFile(f, data, s.FileMode)
if err != nil {
t.Fatalf("golden: filed to write file: %s", err.Error())
}

View File

@@ -1,15 +1,105 @@
package golden
import (
"io/ioutil"
"os"
"path/filepath"
"reflect"
"runtime"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestDefaults(t *testing.T) {
t.Run("Default", func(t *testing.T) {
assert.IsType(t, &Golden{}, Default)
assert.Equal(t, DefaultDirMode, Default.DirMode)
assert.Equal(t, DefaultFileMode, Default.FileMode)
assert.Equal(t, DefaultSuffix, Default.Suffix)
assert.Equal(t, DefaultDirname, Default.Dirname)
// Use runtime.FuncForPC() to verify the UpdateFunc value is set to
// the EnvUpdateFunc function by default.
gotFP := reflect.ValueOf(Default.UpdateFunc).Pointer()
gotFuncName := runtime.FuncForPC(gotFP).Name()
wantFP := reflect.ValueOf(EnvUpdateFunc).Pointer()
wantFuncName := runtime.FuncForPC(wantFP).Name()
assert.Equal(t, wantFuncName, gotFuncName)
})
t.Run("DefaultDirMode", func(t *testing.T) {
assert.Equal(t, os.FileMode(0o755), DefaultDirMode)
})
t.Run("DefaultFileMode", func(t *testing.T) {
assert.Equal(t, os.FileMode(0o644), DefaultFileMode)
})
t.Run("DefaultSuffix", func(t *testing.T) {
assert.Equal(t, ".golden", DefaultSuffix)
})
t.Run("DefaultDirname", func(t *testing.T) {
assert.Equal(t, "testdata", DefaultDirname)
})
t.Run("DefaultUpdateFunc", func(t *testing.T) {
gotFP := reflect.ValueOf(DefaultUpdateFunc).Pointer()
gotFuncName := runtime.FuncForPC(gotFP).Name()
wantFP := reflect.ValueOf(EnvUpdateFunc).Pointer()
wantFuncName := runtime.FuncForPC(wantFP).Name()
assert.Equal(t, wantFuncName, gotFuncName)
})
}
// TestNew is a horribly hack to test that the New() function uses the
// package-level Default* variables.
func TestNew(t *testing.T) {
// Capture the default values before we change them.
defaultDirMode := DefaultDirMode
defaultFileMode := DefaultFileMode
defaultSuffix := DefaultSuffix
defaultDirname := DefaultDirname
defaultUpdateFunc := DefaultUpdateFunc
// Restore the default values after the test.
t.Cleanup(func() {
DefaultDirMode = defaultDirMode
DefaultFileMode = defaultFileMode
DefaultSuffix = defaultSuffix
DefaultDirname = defaultDirname
DefaultUpdateFunc = defaultUpdateFunc
})
// Set all the default values to new values.
DefaultDirMode = os.FileMode(0o700)
DefaultFileMode = os.FileMode(0o600)
DefaultSuffix = ".gold"
DefaultDirname = "goldenfiles"
updateFunc := func() bool { return true }
DefaultUpdateFunc = updateFunc
// Create a new Golden instance with the new values.
got := New()
assert.Equal(t, DefaultDirMode, got.DirMode)
assert.Equal(t, DefaultFileMode, got.FileMode)
assert.Equal(t, DefaultSuffix, got.Suffix)
assert.Equal(t, DefaultDirname, got.Dirname)
// Verify the UpdateFunc value is set to the new value.
gotFP := reflect.ValueOf(got.UpdateFunc).Pointer()
gotFuncName := runtime.FuncForPC(gotFP).Name()
wantFP := reflect.ValueOf(updateFunc).Pointer()
wantFuncName := runtime.FuncForPC(wantFP).Name()
assert.Equal(t, wantFuncName, gotFuncName)
}
func TestFile(t *testing.T) {
got := File(t)
@@ -57,8 +147,8 @@ func TestGet(t *testing.T) {
require.NoError(t, err)
content := []byte("foobar\nhello world :)")
err = ioutil.WriteFile( //nolint:gosec
filepath.Join("testdata", "TestGet.golden"), content, 0o644,
err = os.WriteFile(
filepath.Join("testdata", "TestGet.golden"), content, 0o600,
)
require.NoError(t, err)
@@ -108,7 +198,7 @@ func TestGet(t *testing.T) {
err := os.MkdirAll(dir, 0o755)
require.NoError(t, err)
err = ioutil.WriteFile(f, tt.want, 0o644) //nolint:gosec
err = os.WriteFile(f, tt.want, 0o600)
require.NoError(t, err)
got := Get(t)
@@ -130,7 +220,7 @@ func TestSet(t *testing.T) {
content := []byte("This is the default golden file for TestSet ^_^")
Set(t, content)
b, err := ioutil.ReadFile(filepath.Join("testdata", "TestSet.golden"))
b, err := os.ReadFile(filepath.Join("testdata", "TestSet.golden"))
require.NoError(t, err)
assert.Equal(t, content, b)
@@ -176,7 +266,7 @@ func TestSet(t *testing.T) {
Set(t, tt.content)
got, err := ioutil.ReadFile(f)
got, err := os.ReadFile(f)
require.NoError(t, err)
assert.Equal(t, tt.file, f)
@@ -246,9 +336,9 @@ func TestGetP(t *testing.T) {
require.NoError(t, err)
content := []byte("this is the named golden file for TestGetP")
err = ioutil.WriteFile( //nolint:gosec
err = os.WriteFile(
filepath.Join("testdata", "TestGetP", "sub-name.golden"),
content, 0o644,
content, 0o600,
)
require.NoError(t, err)
@@ -330,7 +420,7 @@ func TestGetP(t *testing.T) {
err := os.MkdirAll(dir, 0o755)
require.NoError(t, err)
err = ioutil.WriteFile(f, tt.want, 0o644) //nolint:gosec
err = os.WriteFile(f, tt.want, 0o600)
require.NoError(t, err)
got := GetP(t, tt.named)
@@ -350,7 +440,7 @@ func TestSetP(t *testing.T) {
content := []byte("This is the named golden file for TestSetP ^_^")
SetP(t, "sub-name", content)
b, err := ioutil.ReadFile(
b, err := os.ReadFile(
filepath.Join("testdata", "TestSetP", "sub-name.golden"),
)
require.NoError(t, err)
@@ -420,7 +510,7 @@ func TestSetP(t *testing.T) {
SetP(t, tt.named, tt.content)
got, err := ioutil.ReadFile(f)
got, err := os.ReadFile(f)
require.NoError(t, err)
assert.Equal(t, tt.file, f)