Skip to content

Commit

Permalink
Merge branch 'master' into pass-msg
Browse files Browse the repository at this point in the history
  • Loading branch information
hendrywiranto committed Feb 21, 2024
2 parents 0cd093d + 7caada5 commit b7a58e0
Show file tree
Hide file tree
Showing 12 changed files with 216 additions and 84 deletions.
23 changes: 23 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
name: Bug report
about: Format to report a bug
title: ''
labels: bug
assignees: ''

---

<!-- If this is a question, consider using the discussion section of this repo -->
<!-- Here: https://github.com/stretchr/testify/discussions/new?category=q-a -->

## Description
<!-- A detailed description of the bug -->

## Step To Reproduce
<!-- Steps or code snippet to reproduce the behaviour -->

## Expected behaviour
<!-- A clear and concise description of what you expected to happen -->

## Actual behaviour
<!-- What testify does -->
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Feature request
about: Propose a new feature
title: ''
labels: enhancement
assignees: ''

---

<!-- If this is a question, consider using the discussion section of this repo -->
<!-- Here: https://github.com/stretchr/testify/discussions/new?category=q-a -->

## Description
<!-- A clear and concise description of what feature you are proposing -->

## Proposed solution
<!-- Optionally a suggested implementation -->

## Use case
<!-- What is the motivation? What workarounds have you used? -->
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ jobs:
strategy:
matrix:
go_version:
- "1.20"
- "1.21"
- stable
- oldstable
steps:
- uses: actions/checkout@v4
- name: Setup Go
Expand Down
12 changes: 12 additions & 0 deletions EMERITUS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Emeritus

We would like to acknowledge previous testify maintainers and their huge contributions to our collective success:

* @matryer
* @glesica
* @ernesto-jimenez
* @mvdkleijn
* @georgelesica-wf
* @bencampbell-wf

We thank these members for their service to this community.
6 changes: 4 additions & 2 deletions MAINTAINERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
The individuals listed below are active in the project and have the ability to approve and merge
pull requests.

* @glesica
* @boyan-soubachov

* @dolmen
* @MovieStoreGuy
* @arjunmahishi
* @brackendawson
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Testify - Thou Shalt Write Tests

ℹ️ We are working on testify v2 and would love to hear what you'd like to see in it, have your say here: https://cutt.ly/testify

[![Build Status](https://travis-ci.org/stretchr/testify.svg)](https://travis-ci.org/stretchr/testify) [![Go Report Card](https://goreportcard.com/badge/github.com/stretchr/testify)](https://goreportcard.com/report/github.com/stretchr/testify) [![PkgGoDev](https://pkg.go.dev/badge/github.com/stretchr/testify)](https://pkg.go.dev/github.com/stretchr/testify)
[![Build Status](https://github.com/stretchr/testify/actions/workflows/main.yml/badge.svg?branch=master)](https://github.com/stretchr/testify/actions/workflows/main.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/stretchr/testify)](https://goreportcard.com/report/github.com/stretchr/testify) [![PkgGoDev](https://pkg.go.dev/badge/github.com/stretchr/testify)](https://pkg.go.dev/github.com/stretchr/testify)

Go code (golang) set of packages that provide many tools for testifying that your code will behave as you intend.

Expand Down
68 changes: 43 additions & 25 deletions assert/assertions.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,25 +59,20 @@ func ObjectsAreEqual(expected, actual interface{}) bool {
if expected == nil || actual == nil {
return expected == actual
}
switch exp := expected.(type) {
case []byte:
act, ok := actual.([]byte)
if !ok {
return false
}
if exp == nil || act == nil {
return exp == nil && act == nil
}
return bytes.Equal(exp, act)
case time.Time:
act, ok := actual.(time.Time)
if !ok {
return false
}
return exp.Equal(act)
default:

exp, ok := expected.([]byte)
if !ok {
return reflect.DeepEqual(expected, actual)
}

act, ok := actual.([]byte)
if !ok {
return false
}
if exp == nil || act == nil {
return exp == nil && act == nil
}
return bytes.Equal(exp, act)
}

// copyExportedFields iterates downward through nested data structures and creates a copy
Expand Down Expand Up @@ -165,17 +160,40 @@ func ObjectsAreEqualValues(expected, actual interface{}) bool {
return true
}

actualType := reflect.TypeOf(actual)
if actualType == nil {
expectedValue := reflect.ValueOf(expected)
actualValue := reflect.ValueOf(actual)
if !expectedValue.IsValid() || !actualValue.IsValid() {
return false
}
expectedValue := reflect.ValueOf(expected)
if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) {

expectedType := expectedValue.Type()
actualType := actualValue.Type()
if !expectedType.ConvertibleTo(actualType) {
return false
}

if !isNumericType(expectedType) || !isNumericType(actualType) {
// Attempt comparison after type conversion
return reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual)
return reflect.DeepEqual(
expectedValue.Convert(actualType).Interface(), actual,
)
}

return false
// If BOTH values are numeric, there are chances of false positives due
// to overflow or underflow. So, we need to make sure to always convert
// the smaller type to a larger type before comparing.
if expectedType.Size() >= actualType.Size() {
return actualValue.Convert(expectedType).Interface() == expected
}

return expectedValue.Convert(actualType).Interface() == actual
}

// isNumericType returns true if the type is one of:
// int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64,
// float32, float64, complex64, complex128
func isNumericType(t reflect.Type) bool {
return t.Kind() >= reflect.Int && t.Kind() <= reflect.Complex128
}

/* CallerInfo is necessary because the assert functions use the testing object
Expand Down Expand Up @@ -749,11 +767,11 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{})
}
l, ok := getLen(object)
if !ok {
return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...)
return Fail(t, fmt.Sprintf("\"%v\" could not be applied builtin len()", object), msgAndArgs...)
}

if l != length {
return Fail(t, fmt.Sprintf("\"%s\" should have %d item(s), but has %d", object, length, l), msgAndArgs...)
return Fail(t, fmt.Sprintf("\"%v\" should have %d item(s), but has %d", object, length, l), msgAndArgs...)
}
return true
}
Expand Down
120 changes: 68 additions & 52 deletions assert/assertions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,24 +135,42 @@ func TestObjectsAreEqual(t *testing.T) {

})
}
}

// Cases where type differ but values are equal
if !ObjectsAreEqualValues(uint32(10), int32(10)) {
t.Error("ObjectsAreEqualValues should return true")
}
if ObjectsAreEqualValues(0, nil) {
t.Fail()
}
if ObjectsAreEqualValues(nil, 0) {
t.Fail()
}
func TestObjectsAreEqualValues(t *testing.T) {
now := time.Now()

tm := time.Now()
tz := tm.In(time.Local)
if !ObjectsAreEqualValues(tm, tz) {
t.Error("ObjectsAreEqualValues should return true for time.Time objects with different time zones")
cases := []struct {
expected interface{}
actual interface{}
result bool
}{
{uint32(10), int32(10), true},
{0, nil, false},
{nil, 0, false},
{now, now.In(time.Local), false}, // should not be time zone independent
{int(270), int8(14), false}, // should handle overflow/underflow
{int8(14), int(270), false},
{[]int{270, 270}, []int8{14, 14}, false},
{complex128(1e+100 + 1e+100i), complex64(complex(math.Inf(0), math.Inf(0))), false},
{complex64(complex(math.Inf(0), math.Inf(0))), complex128(1e+100 + 1e+100i), false},
{complex128(1e+100 + 1e+100i), 270, false},
{270, complex128(1e+100 + 1e+100i), false},
{complex128(1e+100 + 1e+100i), 3.14, false},
{3.14, complex128(1e+100 + 1e+100i), false},
{complex128(1e+10 + 1e+10i), complex64(1e+10 + 1e+10i), true},
{complex64(1e+10 + 1e+10i), complex128(1e+10 + 1e+10i), true},
}

for _, c := range cases {
t.Run(fmt.Sprintf("ObjectsAreEqualValues(%#v, %#v)", c.expected, c.actual), func(t *testing.T) {
res := ObjectsAreEqualValues(c.expected, c.actual)

if res != c.result {
t.Errorf("ObjectsAreEqualValues(%#v, %#v) should return %#v", c.expected, c.actual, c.result)
}
})
}
}

type Nested struct {
Expand Down Expand Up @@ -1643,49 +1661,33 @@ func TestLen(t *testing.T) {
ch <- 3

cases := []struct {
v interface{}
l int
v interface{}
l int
expected1234567 string // message when expecting 1234567 items
}{
{[]int{1, 2, 3}, 3},
{[...]int{1, 2, 3}, 3},
{"ABC", 3},
{map[int]int{1: 2, 2: 4, 3: 6}, 3},
{ch, 3},
{[]int{1, 2, 3}, 3, `"[1 2 3]" should have 1234567 item(s), but has 3`},
{[...]int{1, 2, 3}, 3, `"[1 2 3]" should have 1234567 item(s), but has 3`},
{"ABC", 3, `"ABC" should have 1234567 item(s), but has 3`},
{map[int]int{1: 2, 2: 4, 3: 6}, 3, `"map[1:2 2:4 3:6]" should have 1234567 item(s), but has 3`},
{ch, 3, ""},

{[]int{}, 0},
{map[int]int{}, 0},
{make(chan int), 0},
{[]int{}, 0, `"[]" should have 1234567 item(s), but has 0`},
{map[int]int{}, 0, `"map[]" should have 1234567 item(s), but has 0`},
{make(chan int), 0, ""},

{[]int(nil), 0},
{map[int]int(nil), 0},
{(chan int)(nil), 0},
{[]int(nil), 0, `"[]" should have 1234567 item(s), but has 0`},
{map[int]int(nil), 0, `"map[]" should have 1234567 item(s), but has 0`},
{(chan int)(nil), 0, `"<nil>" should have 1234567 item(s), but has 0`},
}

for _, c := range cases {
True(t, Len(mockT, c.v, c.l), "%#v have %d items", c.v, c.l)
}

cases = []struct {
v interface{}
l int
}{
{[]int{1, 2, 3}, 4},
{[...]int{1, 2, 3}, 2},
{"ABC", 2},
{map[int]int{1: 2, 2: 4, 3: 6}, 4},
{ch, 2},

{[]int{}, 1},
{map[int]int{}, 1},
{make(chan int), 1},

{[]int(nil), 1},
{map[int]int(nil), 1},
{(chan int)(nil), 1},
}

for _, c := range cases {
False(t, Len(mockT, c.v, c.l), "%#v have %d items", c.v, c.l)
False(t, Len(mockT, c.v, c.l+1), "%#v have %d items", c.v, c.l)
if c.expected1234567 != "" {
msgMock := new(mockTestingT)
Len(msgMock, c.v, 1234567)
Contains(t, msgMock.errorString(), c.expected1234567)
}
}
}

Expand Down Expand Up @@ -2935,12 +2937,26 @@ func TestNeverTrue(t *testing.T) {
False(t, Never(mockT, condition, 100*time.Millisecond, 20*time.Millisecond))
}

func TestEventuallyIssue805(t *testing.T) {
// Check that a long running condition doesn't block Eventually.
// See issue 805 (and its long tail of following issues)
func TestEventuallyTimeout(t *testing.T) {
mockT := new(testing.T)

NotPanics(t, func() {
condition := func() bool { <-time.After(time.Millisecond); return true }
done, done2 := make(chan struct{}), make(chan struct{})

// A condition function that returns after the Eventually timeout
condition := func() bool {
// Wait until Eventually times out and terminates
<-done
close(done2)
return true
}

False(t, Eventually(mockT, condition, time.Millisecond, time.Microsecond))

close(done)
<-done2
})
}

Expand Down
3 changes: 3 additions & 0 deletions mock/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,9 @@ func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool {
// AssertExpectations asserts that everything specified with On and Return was
// in fact called as expected. Calls may have occurred in any order.
func (m *Mock) AssertExpectations(t TestingT) bool {
if s, ok := t.(interface{ Skipped() bool }); ok && s.Skipped() {
return true
}
if h, ok := t.(tHelper); ok {
h.Helper()
}
Expand Down
10 changes: 10 additions & 0 deletions mock/mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1493,6 +1493,16 @@ func Test_Mock_AssertExpectations_With_Repeatability(t *testing.T) {

}

func Test_Mock_AssertExpectations_Skipped_Test(t *testing.T) {

var mockedService = new(TestExampleImplementation)

mockedService.On("Test_Mock_AssertExpectations_Skipped_Test", 1, 2, 3).Return(5, 6, 7)
defer mockedService.AssertExpectations(t)

t.Skip("skipping test to ensure AssertExpectations does not fail")
}

func Test_Mock_TwoCallsWithDifferentArguments(t *testing.T) {

var mockedService = new(TestExampleImplementation)
Expand Down
Loading

0 comments on commit b7a58e0

Please sign in to comment.