Skip to content

Commit 7290afe

Browse files
authored
Rename ProtoSliceContains matcher to ProtoContains (#25)
Also remove not needed matchers.
1 parent bac53ac commit 7290afe

File tree

2 files changed

+25
-424
lines changed

2 files changed

+25
-424
lines changed

matchers.go

Lines changed: 21 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -49,150 +49,12 @@ func ProtoEqual(expected proto.Message) types.GomegaMatcher {
4949
}
5050
}
5151

52-
// AllProtoEqualMatcher is a custom Gomega matcher to check if all elements in a slice match a protocol buffer
53-
type AllProtoEqualMatcher struct {
54-
Expected proto.Message
55-
}
56-
57-
func (matcher *AllProtoEqualMatcher) Match(actual interface{}) (success bool, err error) {
58-
v := reflect.ValueOf(actual)
59-
if v.Kind() != reflect.Slice {
60-
return false, nil // Return false, nil for non-slice types, consistent with ProtoEqualMatcher
61-
}
62-
63-
for i := 0; i < v.Len(); i++ {
64-
elem := v.Index(i).Interface()
65-
actualMessage, ok := elem.(proto.Message)
66-
if !ok {
67-
return false, nil // Return false if an element isn’t a proto.Message
68-
}
69-
if !proto.Equal(actualMessage, matcher.Expected) {
70-
return false, nil
71-
}
72-
}
73-
return true, nil
74-
}
75-
76-
func (matcher *AllProtoEqualMatcher) FailureMessage(actual interface{}) (message string) {
77-
return format.Message(actual, "to have all elements equal", matcher.Expected)
78-
}
79-
80-
func (matcher *AllProtoEqualMatcher) NegatedFailureMessage(actual interface{}) (message string) {
81-
return format.Message(actual, "not to have all elements equal", matcher.Expected)
82-
}
83-
84-
// AllProtoEqual returns a Gomega matcher that checks if all elements in a slice are equal to the expected Protobuf message.
85-
// It verifies that the input is a slice and that each element implements proto.Message and matches the expected message
86-
// using proto.Equal. If the input is not a slice or any element does not match, the matcher fails.
87-
//
88-
// This matcher is useful for testing scenarios where a collection of Protobuf messages should all conform to a single
89-
// expected template, ignoring order. An empty slice is considered a match (vacuously true), and non-slice inputs
90-
// result in a mismatch without error.
91-
//
92-
// Example usage:
93-
//
94-
// expected := &v1.Foo{Bar: "test", Baz: "baz"}
95-
// items := []*v1.Foo{{Bar: "test", Baz: "baz"}, {Bar: "test", Baz: "baz"}}
96-
// Expect(items).To(AllProtoEqual(expected)) // Passes
97-
// mismatched := []*v1.Foo{{Bar: "test", Baz: "baz"}, {Bar: "different", Baz: "baz"}}
98-
// Expect(mismatched).ToNot(AllProtoEqual(expected)) // Passes
99-
func AllProtoEqual(expected proto.Message) types.GomegaMatcher {
100-
return &AllProtoEqualMatcher{
101-
Expected: expected,
102-
}
103-
}
104-
105-
// ProtoSliceEqualMatcher is a custom Gomega matcher to check if a slice of protocol buffers matches an expected slice
106-
type ProtoSliceEqualMatcher struct {
107-
Expected []proto.Message
108-
}
109-
110-
func (matcher *ProtoSliceEqualMatcher) Match(actual interface{}) (success bool, err error) {
111-
v := reflect.ValueOf(actual)
112-
if v.Kind() != reflect.Slice {
113-
return false, nil
114-
}
115-
116-
if v.Len() != len(matcher.Expected) {
117-
return false, nil
118-
}
119-
120-
// Convert actual slice to []proto.Message
121-
actualSlice := make([]proto.Message, v.Len())
122-
for i := 0; i < v.Len(); i++ {
123-
elem := v.Index(i).Interface()
124-
actualMessage, ok := elem.(proto.Message)
125-
if !ok {
126-
return false, nil
127-
}
128-
actualSlice[i] = actualMessage
129-
}
130-
131-
// Check if slices match in any order
132-
return slicesMatch(actualSlice, matcher.Expected), nil
133-
}
134-
135-
// slicesMatch checks if two slices contain the same elements in any order
136-
func slicesMatch(actual, expected []proto.Message) bool {
137-
if len(actual) != len(expected) {
138-
return false
139-
}
140-
141-
// Create a map to track matched expected elements
142-
matched := make([]bool, len(expected))
143-
144-
// For each actual element, try to find a matching expected element
145-
for _, actualMsg := range actual {
146-
foundMatch := false
147-
for j, expectedMsg := range expected {
148-
if !matched[j] && proto.Equal(actualMsg, expectedMsg) {
149-
matched[j] = true
150-
foundMatch = true
151-
break
152-
}
153-
}
154-
if !foundMatch {
155-
return false
156-
}
157-
}
158-
return true
159-
}
160-
161-
func (matcher *ProtoSliceEqualMatcher) FailureMessage(actual interface{}) (message string) {
162-
return format.Message(actual, "to equal slice", matcher.Expected)
163-
}
164-
165-
func (matcher *ProtoSliceEqualMatcher) NegatedFailureMessage(actual interface{}) (message string) {
166-
return format.Message(actual, "not to equal slice", matcher.Expected)
167-
}
168-
169-
// ProtoSliceEqual returns a Gomega matcher that checks if a slice of Protobuf messages matches the expected slice.
170-
// It verifies that the input is a slice of proto.Message implementations and contains the same elements as the
171-
// expected slice in any order, using proto.Equal for comparisons. The slices must be the same length and contain
172-
// equivalent messages, but order doesn't matter.
173-
//
174-
// This matcher is useful for testing scenarios where a collection of Protobuf messages should match an expected
175-
// set of messages regardless of their order.
176-
//
177-
// Example usage:
178-
//
179-
// expected := []proto.Message{&v1.Foo{Bar: "test"}, &v1.Foo{Bar: "baz"}}
180-
// items := []proto.Message{&v1.Foo{Bar: "baz"}, &v1.Foo{Bar: "test"}}
181-
// Expect(items).To(ProtoSliceEqual(expected)) // Passes
182-
// mismatched := []proto.Message{&v1.Foo{Bar: "test"}, &v1.Foo{Bar: "different"}}
183-
// Expect(mismatched).ToNot(ProtoSliceEqual(expected)) // Passes
184-
func ProtoSliceEqual(expected []proto.Message) types.GomegaMatcher {
185-
return &ProtoSliceEqualMatcher{
186-
Expected: expected,
187-
}
188-
}
189-
190-
// ProtoSliceContainsMatcher is a custom Gomega matcher to check if a slice of protocol buffers contains specific elements
191-
type ProtoSliceContainsMatcher struct {
52+
// ProtoContainsMatcher is a custom Gomega matcher to check if a slice of protocol buffers contains specific elements
53+
type ProtoContainsMatcher struct {
19254
Elements []proto.Message
19355
}
19456

195-
func (matcher *ProtoSliceContainsMatcher) Match(actual interface{}) (success bool, err error) {
57+
func (matcher *ProtoContainsMatcher) Match(actual interface{}) (success bool, err error) {
19658
v := reflect.ValueOf(actual)
19759
if v.Kind() != reflect.Slice {
19860
return false, nil
@@ -225,31 +87,35 @@ func (matcher *ProtoSliceContainsMatcher) Match(actual interface{}) (success boo
22587
return true, nil
22688
}
22789

228-
func (matcher *ProtoSliceContainsMatcher) FailureMessage(actual interface{}) (message string) {
90+
func (matcher *ProtoContainsMatcher) FailureMessage(actual interface{}) (message string) {
22991
return format.Message(actual, "to contain elements", matcher.Elements)
23092
}
23193

232-
func (matcher *ProtoSliceContainsMatcher) NegatedFailureMessage(actual interface{}) (message string) {
94+
func (matcher *ProtoContainsMatcher) NegatedFailureMessage(actual interface{}) (message string) {
23395
return format.Message(actual, "not to contain elements", matcher.Elements)
23496
}
23597

236-
// ProtoSliceContains returns a Gomega matcher that checks if a slice of Protobuf messages contains all the specified elements.
237-
// It verifies that the input is a slice of proto.Message implementations and that each element in the expected slice is
238-
// present in the actual slice (in any order), using proto.Equal for comparisons. The actual slice may contain additional
239-
// elements beyond those specified.
98+
// ProtoContains returns a Gomega matcher that checks if a slice of Protobuf messages contains all the specified elements.
99+
// It verifies that the input is a slice of proto.Message implementations and that each specified element is present in the
100+
// actual slice (in any order), using proto.Equal for comparisons. The actual slice may contain additional elements beyond
101+
// those specified.
240102
//
241103
// This matcher is useful for testing scenarios where you want to ensure certain Protobuf messages are present in a
242-
// collection, regardless of order or additional elements.
104+
// collection, regardless of order or additional elements. It accepts variadic arguments, allowing individual elements to
105+
// be passed directly.
243106
//
244107
// Example usage:
245108
//
246-
// expected := []proto.Message{&v1.Foo{Bar: "test1"}, &v1.Foo{Bar: "test2"}}
247-
// items := []proto.Message{&v1.Foo{Bar: "test1"}, &v1.Foo{Bar: "test2"}, &v1.Foo{Bar: "test3"}}
248-
// Expect(items).To(ProtoSliceContains(expected)) // Passes
249-
// missing := []proto.Message{&v1.Foo{Bar: "test1"}}
250-
// Expect(missing).ToNot(ProtoSliceContains(expected)) // Passes
251-
func ProtoSliceContains(elements ...proto.Message) types.GomegaMatcher {
252-
return &ProtoSliceContainsMatcher{
109+
// Expect(items).To(ProtoContains(
110+
// &v1.Foo{Bar: "test1"},
111+
// &v1.Foo{Bar: "test2"},
112+
// )) // Passes if items contains both elements (and possibly more)
113+
// Expect(missing).ToNot(ProtoContains(
114+
// &v1.Foo{Bar: "test1"},
115+
// &v1.Foo{Bar: "test2"},
116+
// )) // Passes if missing lacks at least one of these elements
117+
func ProtoContains(elements ...proto.Message) types.GomegaMatcher {
118+
return &ProtoContainsMatcher{
253119
Elements: elements,
254120
}
255121
}

0 commit comments

Comments
 (0)