gopkg.in/rethinkdb/rethinkdb-go.v6@v6.2.2/internal/integration/reql_tests/common.go (about)

     1  package reql_tests
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"reflect"
     7  	"regexp"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/stretchr/testify/suite"
    12  	r "gopkg.in/rethinkdb/rethinkdb-go.v6"
    13  	"gopkg.in/rethinkdb/rethinkdb-go.v6/internal/compare"
    14  )
    15  
    16  func maybeRun(query interface{}, session *r.Session, opts r.RunOpts) interface{} {
    17  	switch query := query.(type) {
    18  	case r.Term:
    19  		cursor, err := query.Run(session, opts)
    20  		if err != nil {
    21  			return err
    22  		}
    23  
    24  		switch cursor.Type() {
    25  		case "Cursor":
    26  			results, err := cursor.Interface()
    27  			if err != nil {
    28  				return err
    29  			}
    30  
    31  			return results
    32  		default:
    33  			// If this is a changefeed then return the cursor without attempting
    34  			// to read any documents
    35  			return cursor
    36  		}
    37  	default:
    38  		return query
    39  	}
    40  }
    41  
    42  func runAndAssert(suite suite.Suite, expected, v interface{}, session *r.Session, opts r.RunOpts) {
    43  	var cursor *r.Cursor
    44  	var err error
    45  
    46  	switch v := v.(type) {
    47  	case r.Term:
    48  		cursor, err = v.Run(session, opts)
    49  	case *r.Cursor:
    50  		cursor = v
    51  	case error:
    52  		err = v
    53  	}
    54  
    55  	assertExpected(suite, expected, cursor, err)
    56  }
    57  
    58  func fetchAndAssert(suite suite.Suite, expected, result interface{}, count int) {
    59  	switch v := expected.(type) {
    60  	case compare.Expected:
    61  		v.Fetch = true
    62  		v.FetchCount = count
    63  
    64  		expected = v
    65  	default:
    66  		expected = compare.Expected(compare.Expected{
    67  			Val:        v,
    68  			Fetch:      true,
    69  			FetchCount: count,
    70  		})
    71  	}
    72  
    73  	var cursor *r.Cursor
    74  	var err error
    75  
    76  	switch result := result.(type) {
    77  	case *r.Cursor:
    78  		cursor = result
    79  	case error:
    80  		err = result
    81  	}
    82  
    83  	assertExpected(suite, expected, cursor, err)
    84  }
    85  
    86  func maybeLen(v interface{}) interface{} {
    87  	switch v := v.(type) {
    88  	case *r.Cursor:
    89  		results := []interface{}{}
    90  		v.All(&results)
    91  		return len(results)
    92  	case []interface{}:
    93  		return len(v)
    94  	default:
    95  		return v
    96  	}
    97  }
    98  
    99  func assertExpected(suite suite.Suite, expected interface{}, obtainedCursor *r.Cursor, obtainedErr error) {
   100  	if expected == compare.AnythingIsFine {
   101  		suite.NoError(obtainedErr, "Query returned unexpected error")
   102  		return
   103  	}
   104  
   105  	switch expected := expected.(type) {
   106  	case Err:
   107  		expected.assert(suite, obtainedCursor, obtainedErr)
   108  	case compare.Expected:
   109  		assert(suite, expected, obtainedCursor, obtainedErr)
   110  	default:
   111  		assert(suite, compare.Expected{Val: expected}, obtainedCursor, obtainedErr)
   112  	}
   113  }
   114  
   115  func assert(suite suite.Suite, expected compare.Expected, obtainedCursor *r.Cursor, obtainedErr error) {
   116  	if !suite.NoError(obtainedErr, "Query returned unexpected error") {
   117  		return
   118  	}
   119  
   120  	expectedVal := reflect.ValueOf(expected.Val)
   121  
   122  	// If expected value is nil then ensure cursor is nil (assume that an
   123  	// invalid reflect value is because expected value is nil)
   124  	if !expectedVal.IsValid() || (expectedVal.Kind() == reflect.Ptr && expectedVal.IsNil()) {
   125  		suite.True(obtainedCursor.IsNil(), "Expected nil cursor")
   126  		return
   127  	}
   128  
   129  	expectedType := expectedVal.Type()
   130  	expectedKind := expectedType.Kind()
   131  
   132  	if expectedKind == reflect.Array || expectedKind == reflect.Slice || expected.Fetch {
   133  		if expectedType.Elem().Kind() == reflect.Uint8 {
   134  			// Decode byte slices slightly differently
   135  			var obtained = []byte{}
   136  			err := obtainedCursor.One(&obtained)
   137  			suite.NoError(err, "Error returned when reading query response")
   138  			compare.Assert(suite.T(), expected, obtained)
   139  		} else {
   140  			var obtained = []interface{}{}
   141  			if expected.Fetch {
   142  				var v interface{}
   143  				for obtainedCursor.Next(&v) {
   144  					obtained = append(obtained, v)
   145  
   146  					if expected.FetchCount != 0 && len(obtained) >= expected.FetchCount {
   147  						break
   148  					}
   149  				}
   150  				suite.NoError(obtainedCursor.Err(), "Error returned when reading query response")
   151  			} else {
   152  				err := obtainedCursor.All(&obtained)
   153  				suite.NoError(err, "Error returned when reading query response")
   154  			}
   155  
   156  			compare.Assert(suite.T(), expected, obtained)
   157  		}
   158  	} else if expectedKind == reflect.Map {
   159  		var obtained map[string]interface{}
   160  		err := obtainedCursor.One(&obtained)
   161  		suite.NoError(err, "Error returned when reading query response")
   162  		compare.Assert(suite.T(), expected, obtained)
   163  	} else {
   164  		var obtained interface{}
   165  		err := obtainedCursor.One(&obtained)
   166  		suite.NoError(err, "Error returned when reading query response")
   167  		compare.Assert(suite.T(), expected, obtained)
   168  	}
   169  }
   170  
   171  func int_cmp(i int) int {
   172  	return i
   173  }
   174  
   175  func float_cmp(i float64) float64 {
   176  	return i
   177  }
   178  
   179  func arrlen(length int, vs ...interface{}) []interface{} {
   180  	var v interface{} = compare.AnythingIsFine
   181  	if len(vs) == 1 {
   182  		v = vs[0]
   183  	}
   184  
   185  	arr := make([]interface{}, length)
   186  	for i := 0; i < length; i++ {
   187  		arr[i] = v
   188  	}
   189  	return arr
   190  }
   191  
   192  func str(v interface{}) string {
   193  	return fmt.Sprintf("%v", v)
   194  }
   195  
   196  func wait(s int) interface{} {
   197  	time.Sleep(time.Duration(s) * time.Second)
   198  
   199  	return nil
   200  }
   201  
   202  type Err struct {
   203  	Type    string
   204  	Message string
   205  	Regex   string
   206  }
   207  
   208  var exceptionRegex = regexp.MustCompile("^(?P<message>[^\n]*?)((?: in:)?\n|\nFailed assertion:)(?s).*$")
   209  
   210  func (expected Err) assert(suite suite.Suite, obtainerCursor *r.Cursor, obtainedErr error) {
   211  	// If the error is nil then attempt to read from the cursor and see if an
   212  	// error is returned
   213  	if obtainedErr == nil {
   214  		var res []interface{}
   215  		obtainedErr = obtainerCursor.All(&res)
   216  	}
   217  
   218  	if !suite.Error(obtainedErr) {
   219  		return
   220  	}
   221  
   222  	obtainedType := reflect.TypeOf(obtainedErr).String()
   223  	obtainedMessage := strings.TrimPrefix(obtainedErr.Error(), "rethinkdb: ")
   224  	obtainedMessage = exceptionRegex.ReplaceAllString(obtainedMessage, "${message}")
   225  
   226  	suite.Equal(expected.Type, obtainedType)
   227  	if expected.Regex != "" {
   228  		suite.Regexp(expected.Regex, obtainedMessage)
   229  	}
   230  	if expected.Message != "" {
   231  		suite.Equal(expected.Message, obtainedMessage)
   232  	}
   233  }
   234  
   235  func err(errType, message string) Err {
   236  	return Err{
   237  		Type:    "rethinkdb.RQL" + errType[4:],
   238  		Message: message,
   239  	}
   240  }
   241  
   242  func err_regex(errType, expr string) Err {
   243  	return Err{
   244  		Type:  "rethinkdb.RQL" + errType[4:],
   245  		Regex: expr,
   246  	}
   247  }
   248  
   249  var Ast = struct {
   250  	RqlTzinfo     func(tz string) *time.Location
   251  	Fromtimestamp func(ts float64, loc *time.Location) time.Time
   252  	Now           func() time.Time
   253  }{
   254  	func(tz string) *time.Location {
   255  		t, _ := time.Parse("-07:00 UTC", tz+" UTC")
   256  
   257  		return t.Location()
   258  	},
   259  	func(ts float64, loc *time.Location) time.Time {
   260  		sec, nsec := math.Modf(ts)
   261  
   262  		return time.Unix(int64(sec), int64(nsec*1000)*1000000).In(loc)
   263  	},
   264  	time.Now,
   265  }
   266  
   267  func UTCTimeZone() *time.Location {
   268  	return time.UTC
   269  }
   270  
   271  func PacificTimeZone() *time.Location {
   272  	return Ast.RqlTzinfo("-07:00")
   273  }
   274  
   275  var FloatInfo = struct {
   276  	Min, Max float64
   277  }{math.SmallestNonzeroFloat64, math.MaxFloat64}
   278  
   279  var sys = struct {
   280  	FloatInfo struct {
   281  		Min, Max float64
   282  	}
   283  }{FloatInfo}