...

Source file src/github.com/stretchr/testify/assert/assertion_compare_test.go

Documentation: github.com/stretchr/testify/assert

     1  package assert
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"reflect"
     7  	"runtime"
     8  	"testing"
     9  	"time"
    10  )
    11  
    12  func TestCompare(t *testing.T) {
    13  	type customString string
    14  	type customInt int
    15  	type customInt8 int8
    16  	type customInt16 int16
    17  	type customInt32 int32
    18  	type customInt64 int64
    19  	type customUInt uint
    20  	type customUInt8 uint8
    21  	type customUInt16 uint16
    22  	type customUInt32 uint32
    23  	type customUInt64 uint64
    24  	type customFloat32 float32
    25  	type customFloat64 float64
    26  	type customUintptr uintptr
    27  	type customTime time.Time
    28  	type customBytes []byte
    29  	for _, currCase := range []struct {
    30  		less    interface{}
    31  		greater interface{}
    32  		cType   string
    33  	}{
    34  		{less: customString("a"), greater: customString("b"), cType: "string"},
    35  		{less: "a", greater: "b", cType: "string"},
    36  		{less: customInt(1), greater: customInt(2), cType: "int"},
    37  		{less: int(1), greater: int(2), cType: "int"},
    38  		{less: customInt8(1), greater: customInt8(2), cType: "int8"},
    39  		{less: int8(1), greater: int8(2), cType: "int8"},
    40  		{less: customInt16(1), greater: customInt16(2), cType: "int16"},
    41  		{less: int16(1), greater: int16(2), cType: "int16"},
    42  		{less: customInt32(1), greater: customInt32(2), cType: "int32"},
    43  		{less: int32(1), greater: int32(2), cType: "int32"},
    44  		{less: customInt64(1), greater: customInt64(2), cType: "int64"},
    45  		{less: int64(1), greater: int64(2), cType: "int64"},
    46  		{less: customUInt(1), greater: customUInt(2), cType: "uint"},
    47  		{less: uint8(1), greater: uint8(2), cType: "uint8"},
    48  		{less: customUInt8(1), greater: customUInt8(2), cType: "uint8"},
    49  		{less: uint16(1), greater: uint16(2), cType: "uint16"},
    50  		{less: customUInt16(1), greater: customUInt16(2), cType: "uint16"},
    51  		{less: uint32(1), greater: uint32(2), cType: "uint32"},
    52  		{less: customUInt32(1), greater: customUInt32(2), cType: "uint32"},
    53  		{less: uint64(1), greater: uint64(2), cType: "uint64"},
    54  		{less: customUInt64(1), greater: customUInt64(2), cType: "uint64"},
    55  		{less: float32(1.23), greater: float32(2.34), cType: "float32"},
    56  		{less: customFloat32(1.23), greater: customFloat32(2.23), cType: "float32"},
    57  		{less: float64(1.23), greater: float64(2.34), cType: "float64"},
    58  		{less: customFloat64(1.23), greater: customFloat64(2.34), cType: "float64"},
    59  		{less: uintptr(1), greater: uintptr(2), cType: "uintptr"},
    60  		{less: customUintptr(1), greater: customUintptr(2), cType: "uint64"},
    61  		{less: time.Now(), greater: time.Now().Add(time.Hour), cType: "time.Time"},
    62  		{less: customTime(time.Now()), greater: customTime(time.Now().Add(time.Hour)), cType: "time.Time"},
    63  		{less: []byte{1, 1}, greater: []byte{1, 2}, cType: "[]byte"},
    64  		{less: customBytes([]byte{1, 1}), greater: customBytes([]byte{1, 2}), cType: "[]byte"},
    65  	} {
    66  		resLess, isComparable := compare(currCase.less, currCase.greater, reflect.ValueOf(currCase.less).Kind())
    67  		if !isComparable {
    68  			t.Error("object should be comparable for type " + currCase.cType)
    69  		}
    70  
    71  		if resLess != compareLess {
    72  			t.Errorf("object less (%v) should be less than greater (%v) for type "+currCase.cType,
    73  				currCase.less, currCase.greater)
    74  		}
    75  
    76  		resGreater, isComparable := compare(currCase.greater, currCase.less, reflect.ValueOf(currCase.less).Kind())
    77  		if !isComparable {
    78  			t.Error("object are comparable for type " + currCase.cType)
    79  		}
    80  
    81  		if resGreater != compareGreater {
    82  			t.Errorf("object greater should be greater than less for type " + currCase.cType)
    83  		}
    84  
    85  		resEqual, isComparable := compare(currCase.less, currCase.less, reflect.ValueOf(currCase.less).Kind())
    86  		if !isComparable {
    87  			t.Error("object are comparable for type " + currCase.cType)
    88  		}
    89  
    90  		if resEqual != 0 {
    91  			t.Errorf("objects should be equal for type " + currCase.cType)
    92  		}
    93  	}
    94  }
    95  
    96  type outputT struct {
    97  	buf     *bytes.Buffer
    98  	helpers map[string]struct{}
    99  }
   100  
   101  // Implements TestingT
   102  func (t *outputT) Errorf(format string, args ...interface{}) {
   103  	s := fmt.Sprintf(format, args...)
   104  	t.buf.WriteString(s)
   105  }
   106  
   107  func (t *outputT) Helper() {
   108  	if t.helpers == nil {
   109  		t.helpers = make(map[string]struct{})
   110  	}
   111  	t.helpers[callerName(1)] = struct{}{}
   112  }
   113  
   114  // callerName gives the function name (qualified with a package path)
   115  // for the caller after skip frames (where 0 means the current function).
   116  func callerName(skip int) string {
   117  	// Make room for the skip PC.
   118  	var pc [1]uintptr
   119  	n := runtime.Callers(skip+2, pc[:]) // skip + runtime.Callers + callerName
   120  	if n == 0 {
   121  		panic("testing: zero callers found")
   122  	}
   123  	frames := runtime.CallersFrames(pc[:n])
   124  	frame, _ := frames.Next()
   125  	return frame.Function
   126  }
   127  
   128  func TestGreater(t *testing.T) {
   129  	mockT := new(testing.T)
   130  
   131  	if !Greater(mockT, 2, 1) {
   132  		t.Error("Greater should return true")
   133  	}
   134  
   135  	if Greater(mockT, 1, 1) {
   136  		t.Error("Greater should return false")
   137  	}
   138  
   139  	if Greater(mockT, 1, 2) {
   140  		t.Error("Greater should return false")
   141  	}
   142  
   143  	// Check error report
   144  	for _, currCase := range []struct {
   145  		less    interface{}
   146  		greater interface{}
   147  		msg     string
   148  	}{
   149  		{less: "a", greater: "b", msg: `"a" is not greater than "b"`},
   150  		{less: int(1), greater: int(2), msg: `"1" is not greater than "2"`},
   151  		{less: int8(1), greater: int8(2), msg: `"1" is not greater than "2"`},
   152  		{less: int16(1), greater: int16(2), msg: `"1" is not greater than "2"`},
   153  		{less: int32(1), greater: int32(2), msg: `"1" is not greater than "2"`},
   154  		{less: int64(1), greater: int64(2), msg: `"1" is not greater than "2"`},
   155  		{less: uint8(1), greater: uint8(2), msg: `"1" is not greater than "2"`},
   156  		{less: uint16(1), greater: uint16(2), msg: `"1" is not greater than "2"`},
   157  		{less: uint32(1), greater: uint32(2), msg: `"1" is not greater than "2"`},
   158  		{less: uint64(1), greater: uint64(2), msg: `"1" is not greater than "2"`},
   159  		{less: float32(1.23), greater: float32(2.34), msg: `"1.23" is not greater than "2.34"`},
   160  		{less: float64(1.23), greater: float64(2.34), msg: `"1.23" is not greater than "2.34"`},
   161  		{less: uintptr(1), greater: uintptr(2), msg: `"1" is not greater than "2"`},
   162  		{less: time.Time{}, greater: time.Time{}.Add(time.Hour), msg: `"0001-01-01 00:00:00 +0000 UTC" is not greater than "0001-01-01 01:00:00 +0000 UTC"`},
   163  		{less: []byte{1, 1}, greater: []byte{1, 2}, msg: `"[1 1]" is not greater than "[1 2]"`},
   164  	} {
   165  		out := &outputT{buf: bytes.NewBuffer(nil)}
   166  		False(t, Greater(out, currCase.less, currCase.greater))
   167  		Contains(t, out.buf.String(), currCase.msg)
   168  		Contains(t, out.helpers, "github.com/stretchr/testify/assert.Greater")
   169  	}
   170  }
   171  
   172  func TestGreaterOrEqual(t *testing.T) {
   173  	mockT := new(testing.T)
   174  
   175  	if !GreaterOrEqual(mockT, 2, 1) {
   176  		t.Error("GreaterOrEqual should return true")
   177  	}
   178  
   179  	if !GreaterOrEqual(mockT, 1, 1) {
   180  		t.Error("GreaterOrEqual should return true")
   181  	}
   182  
   183  	if GreaterOrEqual(mockT, 1, 2) {
   184  		t.Error("GreaterOrEqual should return false")
   185  	}
   186  
   187  	// Check error report
   188  	for _, currCase := range []struct {
   189  		less    interface{}
   190  		greater interface{}
   191  		msg     string
   192  	}{
   193  		{less: "a", greater: "b", msg: `"a" is not greater than or equal to "b"`},
   194  		{less: int(1), greater: int(2), msg: `"1" is not greater than or equal to "2"`},
   195  		{less: int8(1), greater: int8(2), msg: `"1" is not greater than or equal to "2"`},
   196  		{less: int16(1), greater: int16(2), msg: `"1" is not greater than or equal to "2"`},
   197  		{less: int32(1), greater: int32(2), msg: `"1" is not greater than or equal to "2"`},
   198  		{less: int64(1), greater: int64(2), msg: `"1" is not greater than or equal to "2"`},
   199  		{less: uint8(1), greater: uint8(2), msg: `"1" is not greater than or equal to "2"`},
   200  		{less: uint16(1), greater: uint16(2), msg: `"1" is not greater than or equal to "2"`},
   201  		{less: uint32(1), greater: uint32(2), msg: `"1" is not greater than or equal to "2"`},
   202  		{less: uint64(1), greater: uint64(2), msg: `"1" is not greater than or equal to "2"`},
   203  		{less: float32(1.23), greater: float32(2.34), msg: `"1.23" is not greater than or equal to "2.34"`},
   204  		{less: float64(1.23), greater: float64(2.34), msg: `"1.23" is not greater than or equal to "2.34"`},
   205  		{less: uintptr(1), greater: uintptr(2), msg: `"1" is not greater than or equal to "2"`},
   206  		{less: time.Time{}, greater: time.Time{}.Add(time.Hour), msg: `"0001-01-01 00:00:00 +0000 UTC" is not greater than or equal to "0001-01-01 01:00:00 +0000 UTC"`},
   207  		{less: []byte{1, 1}, greater: []byte{1, 2}, msg: `"[1 1]" is not greater than or equal to "[1 2]"`},
   208  	} {
   209  		out := &outputT{buf: bytes.NewBuffer(nil)}
   210  		False(t, GreaterOrEqual(out, currCase.less, currCase.greater))
   211  		Contains(t, out.buf.String(), currCase.msg)
   212  		Contains(t, out.helpers, "github.com/stretchr/testify/assert.GreaterOrEqual")
   213  	}
   214  }
   215  
   216  func TestLess(t *testing.T) {
   217  	mockT := new(testing.T)
   218  
   219  	if !Less(mockT, 1, 2) {
   220  		t.Error("Less should return true")
   221  	}
   222  
   223  	if Less(mockT, 1, 1) {
   224  		t.Error("Less should return false")
   225  	}
   226  
   227  	if Less(mockT, 2, 1) {
   228  		t.Error("Less should return false")
   229  	}
   230  
   231  	// Check error report
   232  	for _, currCase := range []struct {
   233  		less    interface{}
   234  		greater interface{}
   235  		msg     string
   236  	}{
   237  		{less: "a", greater: "b", msg: `"b" is not less than "a"`},
   238  		{less: int(1), greater: int(2), msg: `"2" is not less than "1"`},
   239  		{less: int8(1), greater: int8(2), msg: `"2" is not less than "1"`},
   240  		{less: int16(1), greater: int16(2), msg: `"2" is not less than "1"`},
   241  		{less: int32(1), greater: int32(2), msg: `"2" is not less than "1"`},
   242  		{less: int64(1), greater: int64(2), msg: `"2" is not less than "1"`},
   243  		{less: uint8(1), greater: uint8(2), msg: `"2" is not less than "1"`},
   244  		{less: uint16(1), greater: uint16(2), msg: `"2" is not less than "1"`},
   245  		{less: uint32(1), greater: uint32(2), msg: `"2" is not less than "1"`},
   246  		{less: uint64(1), greater: uint64(2), msg: `"2" is not less than "1"`},
   247  		{less: float32(1.23), greater: float32(2.34), msg: `"2.34" is not less than "1.23"`},
   248  		{less: float64(1.23), greater: float64(2.34), msg: `"2.34" is not less than "1.23"`},
   249  		{less: uintptr(1), greater: uintptr(2), msg: `"2" is not less than "1"`},
   250  		{less: time.Time{}, greater: time.Time{}.Add(time.Hour), msg: `"0001-01-01 01:00:00 +0000 UTC" is not less than "0001-01-01 00:00:00 +0000 UTC"`},
   251  		{less: []byte{1, 1}, greater: []byte{1, 2}, msg: `"[1 2]" is not less than "[1 1]"`},
   252  	} {
   253  		out := &outputT{buf: bytes.NewBuffer(nil)}
   254  		False(t, Less(out, currCase.greater, currCase.less))
   255  		Contains(t, out.buf.String(), currCase.msg)
   256  		Contains(t, out.helpers, "github.com/stretchr/testify/assert.Less")
   257  	}
   258  }
   259  
   260  func TestLessOrEqual(t *testing.T) {
   261  	mockT := new(testing.T)
   262  
   263  	if !LessOrEqual(mockT, 1, 2) {
   264  		t.Error("LessOrEqual should return true")
   265  	}
   266  
   267  	if !LessOrEqual(mockT, 1, 1) {
   268  		t.Error("LessOrEqual should return true")
   269  	}
   270  
   271  	if LessOrEqual(mockT, 2, 1) {
   272  		t.Error("LessOrEqual should return false")
   273  	}
   274  
   275  	// Check error report
   276  	for _, currCase := range []struct {
   277  		less    interface{}
   278  		greater interface{}
   279  		msg     string
   280  	}{
   281  		{less: "a", greater: "b", msg: `"b" is not less than or equal to "a"`},
   282  		{less: int(1), greater: int(2), msg: `"2" is not less than or equal to "1"`},
   283  		{less: int8(1), greater: int8(2), msg: `"2" is not less than or equal to "1"`},
   284  		{less: int16(1), greater: int16(2), msg: `"2" is not less than or equal to "1"`},
   285  		{less: int32(1), greater: int32(2), msg: `"2" is not less than or equal to "1"`},
   286  		{less: int64(1), greater: int64(2), msg: `"2" is not less than or equal to "1"`},
   287  		{less: uint8(1), greater: uint8(2), msg: `"2" is not less than or equal to "1"`},
   288  		{less: uint16(1), greater: uint16(2), msg: `"2" is not less than or equal to "1"`},
   289  		{less: uint32(1), greater: uint32(2), msg: `"2" is not less than or equal to "1"`},
   290  		{less: uint64(1), greater: uint64(2), msg: `"2" is not less than or equal to "1"`},
   291  		{less: float32(1.23), greater: float32(2.34), msg: `"2.34" is not less than or equal to "1.23"`},
   292  		{less: float64(1.23), greater: float64(2.34), msg: `"2.34" is not less than or equal to "1.23"`},
   293  		{less: uintptr(1), greater: uintptr(2), msg: `"2" is not less than or equal to "1"`},
   294  		{less: time.Time{}, greater: time.Time{}.Add(time.Hour), msg: `"0001-01-01 01:00:00 +0000 UTC" is not less than or equal to "0001-01-01 00:00:00 +0000 UTC"`},
   295  		{less: []byte{1, 1}, greater: []byte{1, 2}, msg: `"[1 2]" is not less than or equal to "[1 1]"`},
   296  	} {
   297  		out := &outputT{buf: bytes.NewBuffer(nil)}
   298  		False(t, LessOrEqual(out, currCase.greater, currCase.less))
   299  		Contains(t, out.buf.String(), currCase.msg)
   300  		Contains(t, out.helpers, "github.com/stretchr/testify/assert.LessOrEqual")
   301  	}
   302  }
   303  
   304  func TestPositive(t *testing.T) {
   305  	mockT := new(testing.T)
   306  
   307  	if !Positive(mockT, 1) {
   308  		t.Error("Positive should return true")
   309  	}
   310  
   311  	if !Positive(mockT, 1.23) {
   312  		t.Error("Positive should return true")
   313  	}
   314  
   315  	if Positive(mockT, -1) {
   316  		t.Error("Positive should return false")
   317  	}
   318  
   319  	if Positive(mockT, -1.23) {
   320  		t.Error("Positive should return false")
   321  	}
   322  
   323  	// Check error report
   324  	for _, currCase := range []struct {
   325  		e   interface{}
   326  		msg string
   327  	}{
   328  		{e: int(-1), msg: `"-1" is not positive`},
   329  		{e: int8(-1), msg: `"-1" is not positive`},
   330  		{e: int16(-1), msg: `"-1" is not positive`},
   331  		{e: int32(-1), msg: `"-1" is not positive`},
   332  		{e: int64(-1), msg: `"-1" is not positive`},
   333  		{e: float32(-1.23), msg: `"-1.23" is not positive`},
   334  		{e: float64(-1.23), msg: `"-1.23" is not positive`},
   335  	} {
   336  		out := &outputT{buf: bytes.NewBuffer(nil)}
   337  		False(t, Positive(out, currCase.e))
   338  		Contains(t, out.buf.String(), currCase.msg)
   339  		Contains(t, out.helpers, "github.com/stretchr/testify/assert.Positive")
   340  	}
   341  }
   342  
   343  func TestNegative(t *testing.T) {
   344  	mockT := new(testing.T)
   345  
   346  	if !Negative(mockT, -1) {
   347  		t.Error("Negative should return true")
   348  	}
   349  
   350  	if !Negative(mockT, -1.23) {
   351  		t.Error("Negative should return true")
   352  	}
   353  
   354  	if Negative(mockT, 1) {
   355  		t.Error("Negative should return false")
   356  	}
   357  
   358  	if Negative(mockT, 1.23) {
   359  		t.Error("Negative should return false")
   360  	}
   361  
   362  	// Check error report
   363  	for _, currCase := range []struct {
   364  		e   interface{}
   365  		msg string
   366  	}{
   367  		{e: int(1), msg: `"1" is not negative`},
   368  		{e: int8(1), msg: `"1" is not negative`},
   369  		{e: int16(1), msg: `"1" is not negative`},
   370  		{e: int32(1), msg: `"1" is not negative`},
   371  		{e: int64(1), msg: `"1" is not negative`},
   372  		{e: float32(1.23), msg: `"1.23" is not negative`},
   373  		{e: float64(1.23), msg: `"1.23" is not negative`},
   374  	} {
   375  		out := &outputT{buf: bytes.NewBuffer(nil)}
   376  		False(t, Negative(out, currCase.e))
   377  		Contains(t, out.buf.String(), currCase.msg)
   378  		Contains(t, out.helpers, "github.com/stretchr/testify/assert.Negative")
   379  	}
   380  }
   381  
   382  func Test_compareTwoValuesDifferentValuesTypes(t *testing.T) {
   383  	mockT := new(testing.T)
   384  
   385  	for _, currCase := range []struct {
   386  		v1            interface{}
   387  		v2            interface{}
   388  		compareResult bool
   389  	}{
   390  		{v1: 123, v2: "abc"},
   391  		{v1: "abc", v2: 123456},
   392  		{v1: float64(12), v2: "123"},
   393  		{v1: "float(12)", v2: float64(1)},
   394  	} {
   395  		compareResult := compareTwoValues(mockT, currCase.v1, currCase.v2, []CompareType{compareLess, compareEqual, compareGreater}, "testFailMessage")
   396  		False(t, compareResult)
   397  	}
   398  }
   399  
   400  func Test_compareTwoValuesNotComparableValues(t *testing.T) {
   401  	mockT := new(testing.T)
   402  
   403  	type CompareStruct struct {
   404  	}
   405  
   406  	for _, currCase := range []struct {
   407  		v1 interface{}
   408  		v2 interface{}
   409  	}{
   410  		{v1: CompareStruct{}, v2: CompareStruct{}},
   411  		{v1: map[string]int{}, v2: map[string]int{}},
   412  		{v1: make([]int, 5), v2: make([]int, 5)},
   413  	} {
   414  		compareResult := compareTwoValues(mockT, currCase.v1, currCase.v2, []CompareType{compareLess, compareEqual, compareGreater}, "testFailMessage")
   415  		False(t, compareResult)
   416  	}
   417  }
   418  
   419  func Test_compareTwoValuesCorrectCompareResult(t *testing.T) {
   420  	mockT := new(testing.T)
   421  
   422  	for _, currCase := range []struct {
   423  		v1           interface{}
   424  		v2           interface{}
   425  		compareTypes []CompareType
   426  	}{
   427  		{v1: 1, v2: 2, compareTypes: []CompareType{compareLess}},
   428  		{v1: 1, v2: 2, compareTypes: []CompareType{compareLess, compareEqual}},
   429  		{v1: 2, v2: 2, compareTypes: []CompareType{compareGreater, compareEqual}},
   430  		{v1: 2, v2: 2, compareTypes: []CompareType{compareEqual}},
   431  		{v1: 2, v2: 1, compareTypes: []CompareType{compareEqual, compareGreater}},
   432  		{v1: 2, v2: 1, compareTypes: []CompareType{compareGreater}},
   433  	} {
   434  		compareResult := compareTwoValues(mockT, currCase.v1, currCase.v2, currCase.compareTypes, "testFailMessage")
   435  		True(t, compareResult)
   436  	}
   437  }
   438  
   439  func Test_containsValue(t *testing.T) {
   440  	for _, currCase := range []struct {
   441  		values []CompareType
   442  		value  CompareType
   443  		result bool
   444  	}{
   445  		{values: []CompareType{compareGreater}, value: compareGreater, result: true},
   446  		{values: []CompareType{compareGreater, compareLess}, value: compareGreater, result: true},
   447  		{values: []CompareType{compareGreater, compareLess}, value: compareLess, result: true},
   448  		{values: []CompareType{compareGreater, compareLess}, value: compareEqual, result: false},
   449  	} {
   450  		compareResult := containsValue(currCase.values, currCase.value)
   451  		Equal(t, currCase.result, compareResult)
   452  	}
   453  }
   454  
   455  func TestComparingMsgAndArgsForwarding(t *testing.T) {
   456  	msgAndArgs := []interface{}{"format %s %x", "this", 0xc001}
   457  	expectedOutput := "format this c001\n"
   458  	funcs := []func(t TestingT){
   459  		func(t TestingT) { Greater(t, 1, 2, msgAndArgs...) },
   460  		func(t TestingT) { GreaterOrEqual(t, 1, 2, msgAndArgs...) },
   461  		func(t TestingT) { Less(t, 2, 1, msgAndArgs...) },
   462  		func(t TestingT) { LessOrEqual(t, 2, 1, msgAndArgs...) },
   463  		func(t TestingT) { Positive(t, 0, msgAndArgs...) },
   464  		func(t TestingT) { Negative(t, 0, msgAndArgs...) },
   465  	}
   466  	for _, f := range funcs {
   467  		out := &outputT{buf: bytes.NewBuffer(nil)}
   468  		f(out)
   469  		Contains(t, out.buf.String(), expectedOutput)
   470  	}
   471  }
   472  

View as plain text