gopkg.in/rethinkdb/rethinkdb-go.v6@v6.2.2/internal/integration/tests/checkers.go (about) 1 package tests 2 3 import ( 4 "encoding/json" 5 "fmt" 6 7 test "gopkg.in/check.v1" 8 9 "gopkg.in/rethinkdb/rethinkdb-go.v6/types" 10 ) 11 12 type jsonChecker struct { 13 *test.CheckerInfo 14 } 15 16 func (j jsonChecker) Check(params []interface{}, names []string) (result bool, error string) { 17 var jsonParams []interface{} 18 for _, param := range params { 19 jsonParam, err := json.Marshal(param) 20 if err != nil { 21 return false, err.Error() 22 } 23 jsonParams = append(jsonParams, jsonParam) 24 } 25 return test.DeepEquals.Check(jsonParams, names) 26 } 27 28 // JsonEquals compares two interface{} objects by converting them to JSON and 29 // seeing if the strings match 30 var JsonEquals = &jsonChecker{ 31 &test.CheckerInfo{Name: "JsonEquals", Params: []string{"obtained", "expected"}}, 32 } 33 34 type geometryChecker struct { 35 *test.CheckerInfo 36 } 37 38 func (j geometryChecker) Check(params []interface{}, names []string) (result bool, error string) { 39 obtained, ok := params[0].(types.Geometry) 40 if !ok { 41 return false, "obtained must be a Geometry" 42 } 43 expectedType, ok := params[1].(string) 44 if !ok { 45 return false, "expectedType must be a string" 46 } 47 48 switch expectedType { 49 case "Polygon": 50 expectedCoords, ok := params[2].([][][]float64) 51 if !ok { 52 return false, "expectedCoords must be a [][][]float64" 53 } 54 55 return comparePolygon(expectedCoords, obtained) 56 case "LineString": 57 expectedCoords, ok := params[2].([][]float64) 58 if !ok { 59 return false, "expectedCoords must be a [][]float64" 60 } 61 62 return compareLineString(expectedCoords, obtained) 63 case "Point": 64 expectedCoords, ok := params[2].([]float64) 65 if !ok { 66 return false, "expectedCoords must be a []float64" 67 } 68 69 return comparePoint(expectedCoords, obtained) 70 default: 71 return false, "unknown expectedType" 72 } 73 } 74 75 // geometryEquals compares two geometry values, all coordinates are compared with a small amount of tolerance 76 var geometryEquals = &geometryChecker{ 77 &test.CheckerInfo{Name: "geometryEquals", Params: []string{"obtained", "expectedType", "expectedCoords"}}, 78 } 79 80 /* BEGIN FLOAT HELPERS */ 81 82 // totally ripped off from math/all_test.go 83 // https://github.com/golang/go/blob/master/src/math/all_test.go#L1723-L1749 84 func tolerance(a, b, e float64) bool { 85 d := a - b 86 if d < 0 { 87 d = -d 88 89 } 90 91 if a != 0 { 92 e = e * a 93 if e < 0 { 94 e = -e 95 96 } 97 98 } 99 return d < e 100 } 101 102 func mehclose(a, b float64) bool { return tolerance(a, b, 1e-2) } 103 func kindaclose(a, b float64) bool { return tolerance(a, b, 1e-8) } 104 func prettyclose(a, b float64) bool { return tolerance(a, b, 1e-14) } 105 func veryclose(a, b float64) bool { return tolerance(a, b, 4e-16) } 106 func soclose(a, b, e float64) bool { return tolerance(a, b, e) } 107 108 func comparePolygon(expected [][][]float64, obtained types.Geometry) (result bool, error string) { 109 if obtained.Type != "Polygon" { 110 return false, fmt.Sprintf("obtained geometry has incorrect type, has %s but expected Polygon", obtained.Type) 111 } 112 113 for i, line := range obtained.Lines { 114 for j, point := range line { 115 ok, err := assertPointsEqual( 116 expected[i][j][0], point.Lon, // Lon 117 expected[i][j][1], point.Lat, // Lat 118 ) 119 if !ok { 120 return false, err 121 } 122 } 123 } 124 125 return true, "" 126 } 127 128 func compareLineString(expected [][]float64, obtained types.Geometry) (result bool, error string) { 129 if obtained.Type != "LineString" { 130 return false, fmt.Sprintf("obtained geometry has incorrect type, has %s but expected LineString", obtained.Type) 131 } 132 133 for j, point := range obtained.Line { 134 ok, err := assertPointsEqual( 135 expected[j][0], point.Lon, // Lon 136 expected[j][1], point.Lat, // Lat 137 ) 138 if !ok { 139 return false, err 140 } 141 } 142 143 return true, "" 144 } 145 146 func comparePoint(expected []float64, obtained types.Geometry) (result bool, error string) { 147 if obtained.Type != "Point" { 148 return false, fmt.Sprintf("obtained geometry has incorrect type, has %s but expected Point", obtained.Type) 149 } 150 151 return assertPointsEqual( 152 expected[0], obtained.Point.Lon, // Lon 153 expected[1], obtained.Point.Lat, // Lat 154 ) 155 } 156 157 func assertPointsEqual(expectedLon, obtainedLon, expectedLat, obtainedLat float64) (result bool, error string) { 158 if !kindaclose(expectedLon, obtainedLon) { 159 return false, fmt.Sprintf("the deviation between the compared floats is too great [%v:%v]", expectedLon, obtainedLon) 160 } 161 if !kindaclose(expectedLat, obtainedLat) { 162 return false, fmt.Sprintf("the deviation between the compared floats is too great [%v:%v]", expectedLat, obtainedLat) 163 } 164 165 return true, "" 166 } 167 168 /* END FLOAT HELPERS */