launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/testing/checkers/bool.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package checkers 5 6 import ( 7 "fmt" 8 "reflect" 9 10 gc "launchpad.net/gocheck" 11 ) 12 13 type isTrueChecker struct { 14 *gc.CheckerInfo 15 } 16 17 // IsTrue checks whether a value has an underlying 18 // boolean type and is true. 19 var IsTrue gc.Checker = &isTrueChecker{ 20 &gc.CheckerInfo{Name: "IsTrue", Params: []string{"obtained"}}, 21 } 22 23 // IsTrue checks whether a value has an underlying 24 // boolean type and is false. 25 var IsFalse gc.Checker = gc.Not(IsTrue) 26 27 func (checker *isTrueChecker) Check(params []interface{}, names []string) (result bool, error string) { 28 29 value := reflect.ValueOf(params[0]) 30 31 switch value.Kind() { 32 case reflect.Bool: 33 return value.Bool(), "" 34 } 35 36 return false, fmt.Sprintf("expected type bool, received type %s", value.Type()) 37 } 38 39 type satisfiesChecker struct { 40 *gc.CheckerInfo 41 } 42 43 // Satisfies checks whether a value causes the argument 44 // function to return true. The function must be of 45 // type func(T) bool where the value being checked 46 // is assignable to T. 47 var Satisfies gc.Checker = &satisfiesChecker{ 48 &gc.CheckerInfo{ 49 Name: "Satisfies", 50 Params: []string{"obtained", "func(T) bool"}, 51 }, 52 } 53 54 func (checker *satisfiesChecker) Check(params []interface{}, names []string) (result bool, error string) { 55 f := reflect.ValueOf(params[1]) 56 ft := f.Type() 57 if ft.Kind() != reflect.Func || 58 ft.NumIn() != 1 || 59 ft.NumOut() != 1 || 60 ft.Out(0) != reflect.TypeOf(true) { 61 return false, fmt.Sprintf("expected func(T) bool, got %s", ft) 62 } 63 v := reflect.ValueOf(params[0]) 64 if !v.IsValid() { 65 if !canBeNil(ft.In(0)) { 66 return false, fmt.Sprintf("cannot assign nil to argument %T", ft.In(0)) 67 } 68 v = reflect.Zero(ft.In(0)) 69 } 70 if !v.Type().AssignableTo(ft.In(0)) { 71 return false, fmt.Sprintf("wrong argument type %s for %s", v.Type(), ft) 72 } 73 return f.Call([]reflect.Value{v})[0].Interface().(bool), "" 74 } 75 76 func canBeNil(t reflect.Type) bool { 77 switch t.Kind() { 78 case reflect.Chan, 79 reflect.Func, 80 reflect.Interface, 81 reflect.Map, 82 reflect.Ptr, 83 reflect.Slice: 84 return true 85 } 86 return false 87 } 88 89 type deepEqualsChecker struct { 90 *gc.CheckerInfo 91 } 92 93 // The DeepEquals checker verifies that the obtained value is deep-equal to 94 // the expected value. The check will work correctly even when facing 95 // slices, interfaces, and values of different types (which always fail 96 // the test). 97 // 98 // For example: 99 // 100 // c.Assert(value, DeepEquals, 42) 101 // c.Assert(array, DeepEquals, []string{"hi", "there"}) 102 // 103 // This checker differs from gocheck.DeepEquals in that 104 // it will compare a nil slice equal to an empty slice, 105 // and a nil map equal to an empty map. 106 var DeepEquals gc.Checker = &deepEqualsChecker{ 107 &gc.CheckerInfo{Name: "DeepEquals", Params: []string{"obtained", "expected"}}, 108 } 109 110 func (checker *deepEqualsChecker) Check(params []interface{}, names []string) (result bool, error string) { 111 if ok, err := DeepEqual(params[0], params[1]); !ok { 112 return false, err.Error() 113 } 114 return true, "" 115 }