launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/testing/testbase/patch.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package testbase 5 6 import ( 7 "os" 8 "reflect" 9 ) 10 11 // Restorer holds a function that can be used 12 // to restore some previous state. 13 type Restorer func() 14 15 // Add returns a Restorer that restores first f1 16 // and then f. It is valid to call this on a nil 17 // Restorer. 18 func (f Restorer) Add(f1 Restorer) Restorer { 19 return func() { 20 f1.Restore() 21 if f != nil { 22 f.Restore() 23 } 24 } 25 } 26 27 // Restore restores some previous state. 28 func (r Restorer) Restore() { 29 r() 30 } 31 32 // PatchValue sets the value pointed to by the given destination to the given 33 // value, and returns a function to restore it to its original value. The 34 // value must be assignable to the element type of the destination. 35 func PatchValue(dest, value interface{}) Restorer { 36 destv := reflect.ValueOf(dest).Elem() 37 oldv := reflect.New(destv.Type()).Elem() 38 oldv.Set(destv) 39 valuev := reflect.ValueOf(value) 40 if !valuev.IsValid() { 41 // This isn't quite right when the destination type is not 42 // nilable, but it's better than the complex alternative. 43 valuev = reflect.Zero(destv.Type()) 44 } 45 destv.Set(valuev) 46 return func() { 47 destv.Set(oldv) 48 } 49 } 50 51 // PatchEnvironment provides a test a simple way to override a single 52 // environment variable. A function is returned that will return the 53 // environment to what it was before. 54 func PatchEnvironment(name, value string) Restorer { 55 oldValue := os.Getenv(name) 56 os.Setenv(name, value) 57 return func() { 58 os.Setenv(name, oldValue) 59 } 60 }