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  }