matchers

package module
v0.1.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 9, 2025 License: Apache-2.0 Imports: 4 Imported by: 0

README

ProtoEqual Matcher for Gomega

Go Report Card Go Reference Test PRs Welcome GitHub License

ProtoEqual is a custom matcher designed for comparing Protocol Buffer messages in Go. It allows you to focus on the meaningful fields of protobuf messages and ignores internal fields such as state, sizeCache, and unknownFields, which are generated by the google.golang.org/protobuf package.

Features

  • Protobuf-specific comparison: Uses proto.Equal to compare the actual content of protobuf messages, ignoring any internal state or metadata fields.
  • Seamless integration with Gomega: Works like other Gomega matchers for easy use in unit tests.
  • Support for nested protobuf messages: Handles complex protobuf structures with nested messages.

Installation

To add the ProtoEqual dependency to your project, you can reference this repository. Use the following command to add it:

go get github.com/afritzler/protoequal

Make sure you also have the Protocol Buffers Go plugin installed if you're working with .proto files. You can install it using:

go get google.golang.org/protobuf

Usage

Using ProtoEqual in Unit Tests

The ProtoEqual matcher is used to compare Protocol Buffer messages within Gomega-based tests. It helps you compare protobuf messages without worrying about internal fields added by the protobuf compiler.

Example Protobuf Messages

Assume you have the following .proto file defining Foo and Qux messages:

syntax = "proto3";

package api.v1;
option go_package = "github.com/afritzler/protoequal/test/api/v1";

// The Foo message with Bar, Baz fields and a nested message Qux.
message Foo {
  string bar = 1; // Bar field
  string baz = 2; // Baz field
  Qux qux = 3;    // Qux is a nested message
}

// The Qux message with Driver and Handle fields.
message Qux {
  string driver = 1; // Driver field
  string handle = 2; // Handle field
}

After generating the Go code using protoc, you can now write tests comparing Foo messages using ProtoEqual.

Example Test with Gomega

Here is an example of how to use the ProtoEqual matcher in a test:

package matchers_test

import (
    "testing"
    
    "google.golang.org/protobuf/proto"
    . "github.com/afritzler/protoequal" 
    "github.com/afritzler/protoequal/test/api/v1"
    "github.com/onsi/gomega"
)

func TestProtoEqualMatcher(t *testing.T) {
    g := gomega.NewWithT(t)

    // Define two identical Foo messages
    actualMessage := &test.Foo{
        Bar: "foo-bar",
        Baz: "foo-baz",
        Qux: &test.Qux{
            Driver: "foo-driver",
            Handle: "foo-handle",
        },
    }

    expectedMessage := &test.Foo{
        Bar: "foo-bar",
        Baz: "foo-baz",
        Qux: &test.Qux{
            Driver: "foo-driver",
            Handle: "foo-handle",
        },
    }

    // Use ProtoEqual to assert that actualMessage matches expectedMessage
    g.Expect(actualMessage).To(ProtoEqual(expectedMessage))
}
Using Nested Protobuf Messages

Since ProtoEqual uses proto.Equal internally, it automatically handles nested messages. For example, in the Foo message, the nested Qux message is compared as part of the overall structure.

Why Use ProtoEqual?

When comparing protobuf messages directly in Go, the default equality check will include internal fields generated by the Protobuf compiler (e.g., state, sizeCache). These fields are not relevant to the content of the message and can cause tests to fail even when the message data is identical. ProtoEqual solves this by ignoring these internal fields and focusing only on the actual message content.

License

This project is licensed under the Apache 2.0 License. See the LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ProtoConsistOf added in v0.1.7

func ProtoConsistOf(elements ...proto.Message) types.GomegaMatcher

ProtoConsistOf returns a Gomega matcher that checks if a slice of Protobuf messages contains all the specified elements. It verifies that the input is a slice of proto.Message implementations and that each specified element is present in the actual slice (in any order), using proto.Equal for comparisons. The actual slice may contain additional elements beyond those specified.

This matcher is useful for testing scenarios where you want to ensure certain Protobuf messages are present in a collection, regardless of order or additional elements. It accepts variadic arguments, allowing individual elements to be passed directly.

Example usage:

Expect(items).To(ProtoConsistOf(
    &v1.Foo{Bar: "test1"},
    &v1.Foo{Bar: "test2"},
)) // Passes if items contains both elements (and possibly more)
Expect(missing).ToNot(ProtoConsistOf(
    &v1.Foo{Bar: "test1"},
    &v1.Foo{Bar: "test2"},
)) // Passes if missing lacks at least one of these elements

func ProtoEqual

func ProtoEqual(expected proto.Message) types.GomegaMatcher

ProtoEqual returns a Gomega matcher that checks if a Protobuf message is equal to the expected message. It verifies that the input implements proto.Message and matches the expected message using proto.Equal. If the input is not a proto.Message or does not match the expected message, the matcher fails.

This matcher is useful for testing scenarios where a single Protobuf message should exactly match an expected template. It performs a deep comparison of all fields, including nested messages, as defined by proto.Equal.

Example usage:

expected := &v1.Foo{Bar: "test", Baz: "baz"}
item := &v1.Foo{Bar: "test", Baz: "baz"}
Expect(item).To(ProtoEqual(expected)) // Passes
mismatched := &v1.Foo{Bar: "different", Baz: "baz"}
Expect(mismatched).ToNot(ProtoEqual(expected)) // Passes

Types

type ProtoConsistOfMatcher added in v0.1.7

type ProtoConsistOfMatcher struct {
	Elements []proto.Message
}

ProtoConsistOfMatcher is a custom Gomega matcher to check if a slice of protocol buffers contains specific elements

func (*ProtoConsistOfMatcher) FailureMessage added in v0.1.7

func (matcher *ProtoConsistOfMatcher) FailureMessage(actual interface{}) (message string)

func (*ProtoConsistOfMatcher) Match added in v0.1.7

func (matcher *ProtoConsistOfMatcher) Match(actual interface{}) (success bool, err error)

func (*ProtoConsistOfMatcher) NegatedFailureMessage added in v0.1.7

func (matcher *ProtoConsistOfMatcher) NegatedFailureMessage(actual interface{}) (message string)

type ProtoEqualMatcher

type ProtoEqualMatcher struct {
	Expected proto.Message
}

ProtoEqualMatcher is a custom Gomega matcher for protocol buffers

func (*ProtoEqualMatcher) FailureMessage

func (matcher *ProtoEqualMatcher) FailureMessage(actual interface{}) (message string)

func (*ProtoEqualMatcher) Match

func (matcher *ProtoEqualMatcher) Match(actual interface{}) (success bool, err error)

func (*ProtoEqualMatcher) NegatedFailureMessage

func (matcher *ProtoEqualMatcher) NegatedFailureMessage(actual interface{}) (message string)

Directories

Path Synopsis
test

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL