sigs.k8s.io/cluster-api-provider-azure@v1.14.3/internal/test/matchers/gomock/matchers.go (about) 1 /* 2 Copyright 2020 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package gomock 18 19 import ( 20 "context" 21 "fmt" 22 23 "github.com/google/go-cmp/cmp" 24 "github.com/onsi/gomega/types" 25 "go.uber.org/mock/gomock" 26 ) 27 28 type ( 29 cmpMatcher struct { 30 x interface{} 31 diff string 32 } 33 34 errStrEq struct { 35 expected string 36 actual string 37 } 38 39 contextMatcher struct { 40 actual interface{} 41 } 42 43 // LogMatcher is a Gomega matcher for logs. 44 LogMatcher interface { 45 types.GomegaMatcher 46 WithLevel(int) LogMatcher 47 WithLogFunc(string) LogMatcher 48 } 49 50 customMatcher struct { 51 state map[string]interface{} 52 matcher func(x interface{}, state map[string]interface{}) bool 53 stringer func(state map[string]interface{}) string 54 } 55 ) 56 57 // DiffEq will verify cmp.Diff(expected, actual) == "" using github.com/google/go-cmp/cmp. 58 func DiffEq(x interface{}) gomock.Matcher { 59 return &cmpMatcher{ 60 x: x, 61 } 62 } 63 64 func (c *cmpMatcher) Matches(x interface{}) bool { 65 c.diff = cmp.Diff(x, c.x) 66 return c.diff == "" 67 } 68 69 func (c *cmpMatcher) String() string { 70 want := fmt.Sprintf("is equal to %v", c.x) 71 if c.diff != "" { 72 want = fmt.Sprintf("%s, but difference is %s", want, c.diff) 73 } 74 return want 75 } 76 77 // ErrStrEq will verify the string matches error.Error(). 78 func ErrStrEq(expected string) gomock.Matcher { 79 return &errStrEq{ 80 expected: expected, 81 } 82 } 83 84 func (e *errStrEq) Matches(y interface{}) bool { 85 err, ok := y.(error) 86 if !ok { 87 return false 88 } 89 e.actual = err.Error() 90 return e.expected == e.actual 91 } 92 93 func (e *errStrEq) String() string { 94 return fmt.Sprintf("error.Error() %q, but got %q", e.expected, e.actual) 95 } 96 97 // AContext returns a matcher that matches a context.Context. 98 func AContext() gomock.Matcher { 99 return &contextMatcher{} 100 } 101 102 func (e *contextMatcher) Matches(y interface{}) bool { 103 _, ok := y.(context.Context) 104 e.actual = y 105 return ok 106 } 107 108 func (e *contextMatcher) String() string { 109 return fmt.Sprintf("expected a context.Context, but got %T", e.actual) 110 } 111 112 // CustomMatcher creates a matcher from two funcs rather than having to make a new struct and implement Matcher. 113 func CustomMatcher(matcher func(x interface{}, state map[string]interface{}) bool, stringer func(state map[string]interface{}) string) gomock.Matcher { 114 return &customMatcher{ 115 state: make(map[string]interface{}), 116 matcher: matcher, 117 stringer: stringer, 118 } 119 } 120 121 func (c customMatcher) Matches(x interface{}) bool { 122 return c.matcher(x, c.state) 123 } 124 125 func (c customMatcher) String() string { 126 return c.stringer(c.state) 127 }