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 */