github.com/onsi/gomega@v1.32.0/matchers/be_comparable_to_matcher_test.go (about) 1 package matchers_test 2 3 import ( 4 "errors" 5 "time" 6 7 "github.com/google/go-cmp/cmp" 8 "github.com/google/go-cmp/cmp/cmpopts" 9 10 . "github.com/onsi/ginkgo/v2" 11 . "github.com/onsi/gomega" 12 . "github.com/onsi/gomega/matchers" 13 ) 14 15 type wrapError struct { 16 msg string 17 err error 18 } 19 20 func (e wrapError) Error() string { 21 return e.msg 22 } 23 24 func (e wrapError) Unwrap() error { 25 return e.err 26 } 27 28 var _ = Describe("BeComparableTo", func() { 29 When("asserting that nil is comparable to nil", func() { 30 It("should error", func() { 31 success, err := (&BeComparableToMatcher{Expected: nil}).Match(nil) 32 33 Expect(success).Should(BeFalse()) 34 Expect(err).Should(HaveOccurred()) 35 }) 36 }) 37 38 Context("When asserting on nil", func() { 39 It("should do the right thing", func() { 40 Expect("foo").ShouldNot(BeComparableTo(nil)) 41 Expect(nil).ShouldNot(BeComparableTo(3)) 42 Expect([]int{1, 2}).ShouldNot(BeComparableTo(nil)) 43 }) 44 }) 45 46 Context("When asserting time with different location ", func() { 47 var t1, t2, t3 time.Time 48 49 BeforeEach(func() { 50 t1 = time.Time{} 51 t2 = time.Time{}.Local() 52 t3 = t1.Add(time.Second) 53 }) 54 55 It("should do the right thing", func() { 56 Expect(t1).Should(BeComparableTo(t2)) 57 Expect(t1).ShouldNot(BeComparableTo(t3)) 58 }) 59 }) 60 61 Context("When struct contain unexported fields", func() { 62 type structWithUnexportedFields struct { 63 unexported string 64 Exported string 65 } 66 67 var s1, s2 structWithUnexportedFields 68 69 BeforeEach(func() { 70 s1 = structWithUnexportedFields{unexported: "unexported", Exported: "Exported"} 71 s2 = structWithUnexportedFields{unexported: "unexported", Exported: "Exported"} 72 }) 73 74 It("should get match err", func() { 75 success, err := (&BeComparableToMatcher{Expected: s1}).Match(s2) 76 Expect(success).Should(BeFalse()) 77 Expect(err).Should(HaveOccurred()) 78 }) 79 80 It("should do the right thing", func() { 81 Expect(s1).Should(BeComparableTo(s2, cmpopts.IgnoreUnexported(structWithUnexportedFields{}))) 82 }) 83 }) 84 85 Context("When compare error", func() { 86 var err1, err2 error 87 88 It("not equal", func() { 89 err1 = errors.New("error") 90 err2 = errors.New("error") 91 Expect(err1).ShouldNot(BeComparableTo(err2, cmpopts.EquateErrors())) 92 }) 93 94 It("equal if err1 is err2", func() { 95 err1 = errors.New("error") 96 err2 = &wrapError{ 97 msg: "some error", 98 err: err1, 99 } 100 101 Expect(err1).Should(BeComparableTo(err2, cmpopts.EquateErrors())) 102 }) 103 }) 104 105 Context("When asserting equal between objects", func() { 106 Context("with no additional cmp.Options", func() { 107 It("should do the right thing", func() { 108 Expect(5).Should(BeComparableTo(5)) 109 Expect(5.0).Should(BeComparableTo(5.0)) 110 111 Expect(5).ShouldNot(BeComparableTo("5")) 112 Expect(5).ShouldNot(BeComparableTo(5.0)) 113 Expect(5).ShouldNot(BeComparableTo(3)) 114 115 Expect("5").Should(BeComparableTo("5")) 116 Expect([]int{1, 2}).Should(BeComparableTo([]int{1, 2})) 117 Expect([]int{1, 2}).ShouldNot(BeComparableTo([]int{2, 1})) 118 Expect([]byte{'f', 'o', 'o'}).Should(BeComparableTo([]byte{'f', 'o', 'o'})) 119 Expect([]byte{'f', 'o', 'o'}).ShouldNot(BeComparableTo([]byte{'b', 'a', 'r'})) 120 Expect(map[string]string{"a": "b", "c": "d"}).Should(BeComparableTo(map[string]string{"a": "b", "c": "d"})) 121 Expect(map[string]string{"a": "b", "c": "d"}).ShouldNot(BeComparableTo(map[string]string{"a": "b", "c": "e"})) 122 }) 123 }) 124 125 Context("with custom cmp.Options", func() { 126 It("should do the right thing", func() { 127 Expect(myCustomType{s: "abc", n: 3, f: 2.0, arr: []string{"a", "b"}}).Should(BeComparableTo(myCustomType{s: "foo", n: 3, f: 2.0, arr: []string{"a", "b"}}, cmpopts.IgnoreUnexported(myCustomType{}))) 128 129 Expect(myCustomType{s: "foo", n: 3, f: 2.0, arr: []string{"a", "b"}}).Should(BeComparableTo(myCustomType{s: "foo", n: 3, f: 2.0, arr: []string{"a", "b"}}, cmp.AllowUnexported(myCustomType{}))) 130 Expect(myCustomType{s: "foo", n: 3, f: 2.0, arr: []string{"a", "b"}}).ShouldNot(BeComparableTo(myCustomType{s: "bar", n: 3, f: 2.0, arr: []string{"a", "b"}}, cmp.AllowUnexported(myCustomType{}))) 131 Expect(myCustomType{s: "foo", n: 3, f: 2.0, arr: []string{"a", "b"}}).ShouldNot(BeComparableTo(myCustomType{s: "foo", n: 2, f: 2.0, arr: []string{"a", "b"}}, cmp.AllowUnexported(myCustomType{}))) 132 Expect(myCustomType{s: "foo", n: 3, f: 2.0, arr: []string{"a", "b"}}).ShouldNot(BeComparableTo(myCustomType{s: "foo", n: 3, f: 3.0, arr: []string{"a", "b"}}, cmp.AllowUnexported(myCustomType{}))) 133 Expect(myCustomType{s: "foo", n: 3, f: 2.0, arr: []string{"a", "b"}}).ShouldNot(BeComparableTo(myCustomType{s: "foo", n: 3, f: 2.0, arr: []string{"a", "b", "c"}}, cmp.AllowUnexported(myCustomType{}))) 134 }) 135 136 type structWithUnexportedFields struct { 137 unexported string 138 Exported string 139 } 140 141 It("should produce failure message according to passed cmp.Option", func() { 142 actual := structWithUnexportedFields{unexported: "xxx", Exported: "exported field value"} 143 expectedEqual := structWithUnexportedFields{unexported: "yyy", Exported: "exported field value"} 144 matcherWithEqual := BeComparableTo(expectedEqual, cmpopts.IgnoreUnexported(structWithUnexportedFields{})) 145 146 Expect(matcherWithEqual.FailureMessage(actual)).To(BeEquivalentTo("Expected object to be comparable, diff: ")) 147 148 expectedDiffernt := structWithUnexportedFields{unexported: "xxx", Exported: "other value"} 149 matcherWithDifference := BeComparableTo(expectedDiffernt, cmpopts.IgnoreUnexported(structWithUnexportedFields{})) 150 Expect(matcherWithDifference.FailureMessage(actual)).To(ContainSubstring("1 ignored field")) 151 Expect(matcherWithDifference.FailureMessage(actual)).To(ContainSubstring("Exported: \"other value\"")) 152 Expect(matcherWithDifference.FailureMessage(actual)).To(ContainSubstring("Exported: \"exported field value\"")) 153 }) 154 }) 155 }) 156 })