github.com/m3db/m3@v1.5.0/src/query/graphite/testing/test_utils.go (about) 1 // Copyright (c) 2019 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package testing 22 23 import ( 24 "fmt" 25 "math" 26 27 "github.com/stretchr/testify/assert" 28 ) 29 30 func toFloat(x interface{}) (float64, bool) { 31 var xf float64 32 xok := true 33 34 switch xn := x.(type) { 35 case uint8: 36 xf = float64(xn) 37 case uint16: 38 xf = float64(xn) 39 case uint32: 40 xf = float64(xn) 41 case uint64: 42 xf = float64(xn) 43 case int: 44 xf = float64(xn) 45 case int8: 46 xf = float64(xn) 47 case int16: 48 xf = float64(xn) 49 case int32: 50 xf = float64(xn) 51 case int64: 52 xf = float64(xn) 53 case float32: 54 xf = float64(xn) 55 case float64: 56 xf = xn 57 default: 58 xok = false 59 } 60 61 return xf, xok 62 } 63 64 func castToFloats( 65 t assert.TestingT, 66 expected, actual interface{}, 67 ) (float64, float64, bool) { 68 af, aok := toFloat(expected) 69 bf, bok := toFloat(actual) 70 71 if !aok || !bok { 72 return 0, 0, assert.Fail(t, "expected or actual are unexpected types") 73 } 74 75 return af, bf, true 76 } 77 78 // EqualWithNaNs compares two numbers for equality, accounting for NaNs. 79 func EqualWithNaNs( 80 t assert.TestingT, 81 expected, actual interface{}, 82 msgAndArgs ...interface{}, 83 ) bool { 84 af, bf, ok := castToFloats(t, expected, actual) 85 if !ok { 86 return ok 87 } 88 89 if math.IsNaN(af) && math.IsNaN(bf) { 90 return true 91 } 92 93 return assert.Equal(t, af, bf, msgAndArgs) 94 } 95 96 // InDeltaWithNaNs compares two floats for equality within a delta, 97 // accounting for NaNs. 98 func InDeltaWithNaNs( 99 t assert.TestingT, 100 expected, actual interface{}, 101 delta float64, 102 msgAndArgs ...interface{}, 103 ) bool { 104 af, bf, ok := castToFloats(t, expected, actual) 105 if !ok { 106 return ok 107 } 108 109 if math.IsNaN(af) && math.IsNaN(bf) { 110 return true 111 } 112 113 dt := af - bf 114 if dt < -delta || dt > delta { 115 return assert.Fail(t, 116 fmt.Sprintf( 117 "Max difference between %v and %v allowed is %v, but difference was %v", 118 expected, actual, delta, dt), msgAndArgs...) 119 } 120 121 return true 122 } 123 124 // Equalish asserts that two objects are equal. Looser than assert.Equal since 125 // it checks for equality of printing expected vs printing actual. 126 // 127 // assert.Equal(t, 123, 123, "123 and 123 should be equal") 128 // 129 // Returns whether the assertion was successful (true) or not (false). 130 func Equalish( 131 t assert.TestingT, 132 expected, actual interface{}, 133 msgAndArgs ...interface{}, 134 ) bool { 135 if assert.ObjectsAreEqual(expected, actual) { 136 return true 137 } 138 139 // Last ditch effort 140 if fmt.Sprintf("%#v", expected) == fmt.Sprintf("%#v", actual) { 141 return true 142 } 143 144 return assert.Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+ 145 " != %#v (actual)", expected, actual), msgAndArgs...) 146 }