1/* 2Gomega matchers 3 4This package implements the Gomega matchers and does not typically need to be imported. 5See the docs for Gomega for documentation on the matchers 6 7http://onsi.github.io/gomega/ 8*/ 9package matchers 10 11import ( 12 "fmt" 13 "reflect" 14) 15 16type omegaMatcher interface { 17 Match(actual interface{}) (success bool, err error) 18 FailureMessage(actual interface{}) (message string) 19 NegatedFailureMessage(actual interface{}) (message string) 20} 21 22func isBool(a interface{}) bool { 23 return reflect.TypeOf(a).Kind() == reflect.Bool 24} 25 26func isNumber(a interface{}) bool { 27 if a == nil { 28 return false 29 } 30 kind := reflect.TypeOf(a).Kind() 31 return reflect.Int <= kind && kind <= reflect.Float64 32} 33 34func isInteger(a interface{}) bool { 35 kind := reflect.TypeOf(a).Kind() 36 return reflect.Int <= kind && kind <= reflect.Int64 37} 38 39func isUnsignedInteger(a interface{}) bool { 40 kind := reflect.TypeOf(a).Kind() 41 return reflect.Uint <= kind && kind <= reflect.Uint64 42} 43 44func isFloat(a interface{}) bool { 45 kind := reflect.TypeOf(a).Kind() 46 return reflect.Float32 <= kind && kind <= reflect.Float64 47} 48 49func toInteger(a interface{}) int64 { 50 if isInteger(a) { 51 return reflect.ValueOf(a).Int() 52 } else if isUnsignedInteger(a) { 53 return int64(reflect.ValueOf(a).Uint()) 54 } else if isFloat(a) { 55 return int64(reflect.ValueOf(a).Float()) 56 } 57 panic(fmt.Sprintf("Expected a number! Got <%T> %#v", a, a)) 58} 59 60func toUnsignedInteger(a interface{}) uint64 { 61 if isInteger(a) { 62 return uint64(reflect.ValueOf(a).Int()) 63 } else if isUnsignedInteger(a) { 64 return reflect.ValueOf(a).Uint() 65 } else if isFloat(a) { 66 return uint64(reflect.ValueOf(a).Float()) 67 } 68 panic(fmt.Sprintf("Expected a number! Got <%T> %#v", a, a)) 69} 70 71func toFloat(a interface{}) float64 { 72 if isInteger(a) { 73 return float64(reflect.ValueOf(a).Int()) 74 } else if isUnsignedInteger(a) { 75 return float64(reflect.ValueOf(a).Uint()) 76 } else if isFloat(a) { 77 return reflect.ValueOf(a).Float() 78 } 79 panic(fmt.Sprintf("Expected a number! Got <%T> %#v", a, a)) 80} 81 82func isError(a interface{}) bool { 83 _, ok := a.(error) 84 return ok 85} 86 87func isChan(a interface{}) bool { 88 if isNil(a) { 89 return false 90 } 91 return reflect.TypeOf(a).Kind() == reflect.Chan 92} 93 94func isMap(a interface{}) bool { 95 if a == nil { 96 return false 97 } 98 return reflect.TypeOf(a).Kind() == reflect.Map 99} 100 101func isArrayOrSlice(a interface{}) bool { 102 if a == nil { 103 return false 104 } 105 switch reflect.TypeOf(a).Kind() { 106 case reflect.Array, reflect.Slice: 107 return true 108 default: 109 return false 110 } 111} 112 113func isString(a interface{}) bool { 114 if a == nil { 115 return false 116 } 117 return reflect.TypeOf(a).Kind() == reflect.String 118} 119 120func toString(a interface{}) (string, bool) { 121 aString, isString := a.(string) 122 if isString { 123 return aString, true 124 } 125 126 aBytes, isBytes := a.([]byte) 127 if isBytes { 128 return string(aBytes), true 129 } 130 131 aStringer, isStringer := a.(fmt.Stringer) 132 if isStringer { 133 return aStringer.String(), true 134 } 135 136 return "", false 137} 138 139func lengthOf(a interface{}) (int, bool) { 140 if a == nil { 141 return 0, false 142 } 143 switch reflect.TypeOf(a).Kind() { 144 case reflect.Map, reflect.Array, reflect.String, reflect.Chan, reflect.Slice: 145 return reflect.ValueOf(a).Len(), true 146 default: 147 return 0, false 148 } 149} 150func capOf(a interface{}) (int, bool) { 151 if a == nil { 152 return 0, false 153 } 154 switch reflect.TypeOf(a).Kind() { 155 case reflect.Array, reflect.Chan, reflect.Slice: 156 return reflect.ValueOf(a).Cap(), true 157 default: 158 return 0, false 159 } 160} 161 162func isNil(a interface{}) bool { 163 if a == nil { 164 return true 165 } 166 167 switch reflect.TypeOf(a).Kind() { 168 case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: 169 return reflect.ValueOf(a).IsNil() 170 } 171 172 return false 173} 174