Skip to content

Commit

Permalink
Merge pull request #2 from 243826/main
Browse files Browse the repository at this point in the history
got rid of the Env interface because it wasn't necessary
  • Loading branch information
243826 authored Aug 30, 2023
2 parents 2315fbd + 98c9781 commit fcbdd24
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 29 deletions.
38 changes: 21 additions & 17 deletions env.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,27 @@ import (
"reflect"
)

type Env interface {
Mock(env interface{}) func()
}

var registered []Env
var registered []interface{}

func Publish(envs ...Env) {
// Introduce introduces (akin to registers) environments which are
// likely to be mocked in future using MockMany function
func Introduce(envs ...interface{}) {
registered = append(registered, envs...)
}

func Mock(envs ...Env) func() {
// MockMany is a convenience method for mocking many environments
// at once that were previously introduced using Introduce function.
// Each of the envs is matched to a previously introduced environment
// based on type commonality and the introduced environment is
// mocked using the passed environment.
func MockMany(envs ...interface{}) func() {
var funcs []func()

for _, unknown := range envs {
unknownType := reflect.ValueOf(unknown).Type()
for _, known := range registered {
if reflect.ValueOf(known).Type() == unknownType {
funcs = append(funcs, mock(known, reflect.ValueOf(unknown).Elem().Interface()))
funcs = append(funcs, MockOne(known, reflect.ValueOf(unknown).Elem().Interface()))
unknownType = nil
}
}
Expand All @@ -33,17 +36,18 @@ func Mock(envs ...Env) func() {
}

return func() {
Unmock(funcs...)
}
}

func Unmock(unmockers ...func()) {
for _, function := range unmockers {
defer function()
for _, function := range funcs {
defer function()
}
}
}

func mock(old Env, new interface{}) func() {
// MockOne mocks the old environment using the values in the new environment
// If the type for old environment is identical to the type of the new environment
// then any attribute with value identical to default value for its type is
// not mocked. But if types are different then the attribute is mocked regardless
// of its value
func MockOne(old interface{}, new interface{}) func() {
valueOfNew := reflect.ValueOf(new)
typeOfNew := reflect.TypeOf(new)

Expand Down Expand Up @@ -78,7 +82,7 @@ func mock(old Env, new interface{}) func() {
blank := valueOfBlank.Interface()

return func() {
mock(old, blank)
MockOne(old, blank)
}
}

Expand Down
16 changes: 4 additions & 12 deletions env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,6 @@ type UtilEnv struct {
Log func(...interface{}) (int, error)
}

func (e *OsEnv) Mock(iface interface{}) func() {
return mock(e, iface)
}

func (e *UtilEnv) Mock(iface interface{}) func() {
return mock(e, iface)
}

func TestEnvMockRandom(t *testing.T) {
path := "file:///this/is/sample/path"
var env = OsEnv{
Expand All @@ -42,7 +34,7 @@ func TestEnvMockRandom(t *testing.T) {
}

url := "http://host:port/this/is/sample/path"
defer env.Mock(struct {
defer MockOne(&env, struct {
Create func(string) (*os.File, error)
Path string
umask int
Expand Down Expand Up @@ -74,7 +66,7 @@ func TestEnvMockSame(t *testing.T) {
}

url := "http://host:port/this/is/sample/path"
defer env.Mock(OsEnv{
defer MockOne(&env, OsEnv{
Create: func(s string) (*os.File, error) {
return nil, errors.New("cant create a file")
},
Expand All @@ -100,9 +92,9 @@ func TestMock(t *testing.T) {
umask: 0x022,
}

Publish(&env, &UtilEnv{})
Introduce(&env, &UtilEnv{})

defer Mock(
defer MockMany(
&OsEnv{
Create: func(s string) (*os.File, error) {
return nil, errors.New("cant mock")
Expand Down

0 comments on commit fcbdd24

Please sign in to comment.