Skip to content

Commit

Permalink
added be_equivalent_to matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
Onsi Fakhouri committed Oct 27, 2013
1 parent ce22a0b commit 27c7621
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 9 deletions.
15 changes: 13 additions & 2 deletions matchers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,25 @@ import (
"github.com/onsi/gomega/matchers"
)

//Equal uses reflect.DeepEqual to compare actual with expected
//Equal uses reflect.DeepEqual to compare actual with expected. Equal is strict about
//types when performing comparisons.
//It is an error for both actual and expected to be nil. Use BeNil() instead.
func Equal(expected interface{}) OmegaMatcher {
return &matchers.EqualMatcher{
Expected: expected,
}
}

//BeEquivalentTo is more lax than Equal, allowing equality between different types.
//This is done by converting actual to have the type of expected before
//attempting equality with reflect.DeepEqual.
//It is an error for actual and expected to be nil. Use BeNil() instead.
func BeEquivalentTo(expected interface{}) OmegaMatcher {
return &matchers.BeEquivalentToMatcher{
Expected: expected,
}
}

//BeNil succeeds if actual is nil
func BeNil() OmegaMatcher {
return &matchers.BeNilMatcher{}
Expand Down Expand Up @@ -117,7 +128,7 @@ func BeNumerically(comparator string, compareTo ...interface{}) OmegaMatcher {
}
}

//BeAssignableToTypeOf succeeds if actual is assignable to the type of actual.
//BeAssignableToTypeOf succeeds if actual is assignable to the type of expected.
//It will return an error when one of the values is nil.
//
// Ω(0).Should(BeAssignableToTypeOf(0)) // Same values
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
. "github.com/onsi/gomega/matchers"
)

var _ = Describe("AssignableTo", func() {
Context("When asserting equality between types", func() {
var _ = Describe("AssignableToTypeOf", func() {
Context("When asserting assignability between types", func() {
It("should do the right thing", func() {
Ω(0).Should(BeAssignableToTypeOf(0))
Ω(5).Should(BeAssignableToTypeOf(-1))
Expand Down
28 changes: 28 additions & 0 deletions matchers/be_equivalent_to_matcher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package matchers

import (
"fmt"
"reflect"
)

type BeEquivalentToMatcher struct {
Expected interface{}
}

func (matcher *BeEquivalentToMatcher) Match(actual interface{}) (success bool, message string, err error) {
if actual == nil && matcher.Expected == nil {
return false, "", fmt.Errorf("Both actual and expected must not be nil.")
}

convertedActual := actual

if actual != nil && matcher.Expected != nil && reflect.TypeOf(actual).ConvertibleTo(reflect.TypeOf(matcher.Expected)) {
convertedActual = reflect.ValueOf(actual).Convert(reflect.TypeOf(matcher.Expected)).Interface()
}

if reflect.DeepEqual(convertedActual, matcher.Expected) {
return true, formatMessage(actual, "not to equal", matcher.Expected), nil
} else {
return false, formatMessage(actual, "to equal", matcher.Expected), nil
}
}
50 changes: 50 additions & 0 deletions matchers/be_equivalent_to_matcher_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package matchers_test

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
. "github.com/onsi/gomega/matchers"
)

var _ = Describe("BeEquivalentTo", func() {
Context("when asserting that nil is equivalent to nil", func() {
It("should error", func() {
success, _, err := (&BeEquivalentToMatcher{Expected: nil}).Match(nil)

Ω(success).Should(BeFalse())
Ω(err).Should(HaveOccured())
})
})

Context("When asserting on nil", func() {
It("should do the right thing", func() {
Ω("foo").ShouldNot(BeEquivalentTo(nil))
Ω(nil).ShouldNot(BeEquivalentTo(3))
Ω([]int{1, 2}).ShouldNot(BeEquivalentTo(nil))
})
})

Context("When asserting on type aliases", func() {
It("should the right thing", func() {
Ω(StringAlias("foo")).Should(BeEquivalentTo("foo"))
Ω("foo").Should(BeEquivalentTo(StringAlias("foo")))
Ω(StringAlias("foo")).ShouldNot(BeEquivalentTo("bar"))
Ω("foo").ShouldNot(BeEquivalentTo(StringAlias("bar")))
})
})

Context("When asserting on numbers", func() {
It("should convert actual to expected and do the right thing", func() {
Ω(5).Should(BeEquivalentTo(5))
Ω(5.0).Should(BeEquivalentTo(5.0))
Ω(5).Should(BeEquivalentTo(5.0))

Ω(5).ShouldNot(BeEquivalentTo("5"))
Ω(5).ShouldNot(BeEquivalentTo(3))

//Here be dragons!
Ω(5.1).Should(BeEquivalentTo(5))
Ω(5).ShouldNot(BeEquivalentTo(5.1))
})
})
})
10 changes: 5 additions & 5 deletions matchers/be_numerically_matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,16 @@ func (matcher *BeNumericallyMatcher) Match(actual interface{}) (success bool, me
return false, "", fmt.Errorf("Unknown comparator: %s", matcher.Comparator)
}

if isInteger(actual) {
success = matcher.matchIntegers(toInteger(actual), toInteger(matcher.CompareTo[0]))
} else if isUnsignedInteger(actual) {
success = matcher.matchUnsignedIntegers(toUnsignedInteger(actual), toUnsignedInteger(matcher.CompareTo[0]))
} else if isFloat(actual) {
if isFloat(actual) || isFloat(matcher.CompareTo[0]) {
var secondOperand float64 = 1e-8
if len(matcher.CompareTo) == 2 {
secondOperand = toFloat(matcher.CompareTo[1])
}
success = matcher.matchFloats(toFloat(actual), toFloat(matcher.CompareTo[0]), secondOperand)
} else if isInteger(actual) {
success = matcher.matchIntegers(toInteger(actual), toInteger(matcher.CompareTo[0]))
} else if isUnsignedInteger(actual) {
success = matcher.matchUnsignedIntegers(toUnsignedInteger(actual), toUnsignedInteger(matcher.CompareTo[0]))
} else {
return false, "", fmt.Errorf("Failed to compare:%s\n%s:%s", formatObject(actual), matcher.Comparator, formatObject(matcher.CompareTo[0]))
}
Expand Down
5 changes: 5 additions & 0 deletions matchers/be_numerically_matcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ var _ = Describe("BeNumerically", func() {
Ω(int8(5)).Should(BeNumerically("==", 5))
})

It("should not have false positives", func() {
Ω(5.1).ShouldNot(BeNumerically("==", 5))
Ω(5).ShouldNot(BeNumerically("==", 5.1))
})

It("should support >", func() {
Ω(uint32(5)).Should(BeNumerically(">", 4))
Ω(float64(5.0)).Should(BeNumerically(">", 4.9))
Expand Down
2 changes: 2 additions & 0 deletions matchers/matcher_tests_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ func (s *myStringer) String() string {
return s.a
}

type StringAlias string

type myCustomType struct {
s string
n int
Expand Down

0 comments on commit 27c7621

Please sign in to comment.