mirror of https://github.com/fluxcd/cli-utils.git
139 lines
3.5 KiB
Go
139 lines
3.5 KiB
Go
// Copyright 2020 The Kubernetes Authors.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package testutil
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/google/go-cmp/cmp/cmpopts"
|
|
"github.com/onsi/gomega/format"
|
|
)
|
|
|
|
// Equal returns a matcher for use with Gomega that uses go-cmp's cmp.Equal to
|
|
// compare and cmp.Diff to show the difference, if there is one.
|
|
//
|
|
// Example Usage:
|
|
// Expect(receivedEvents).To(testutil.Equal(expectedEvents))
|
|
func Equal(expected interface{}) *cmpMatcher {
|
|
return &cmpMatcher{expected: expected}
|
|
}
|
|
|
|
type cmpMatcher struct {
|
|
expected interface{}
|
|
explanation error
|
|
}
|
|
|
|
func (cm *cmpMatcher) Match(actual interface{}) (bool, error) {
|
|
match := cmp.Equal(actual, cm.expected, cmpopts.EquateErrors())
|
|
if !match {
|
|
cm.explanation = errors.New(cmp.Diff(actual, cm.expected, cmpopts.EquateErrors()))
|
|
}
|
|
return match, nil
|
|
}
|
|
|
|
func (cm *cmpMatcher) FailureMessage(actual interface{}) string {
|
|
return format.Message(actual, "to deeply equal", cm.expected) +
|
|
"\nDiff:\n" + indent(cm.explanation.Error(), 1)
|
|
}
|
|
|
|
func (cm *cmpMatcher) NegatedFailureMessage(actual interface{}) string {
|
|
return format.Message(actual, "not to deeply equal", cm.expected) +
|
|
"\nDiff:\n" + indent(cm.explanation.Error(), 1)
|
|
}
|
|
|
|
func indent(in string, indentation uint) string {
|
|
indent := strings.Repeat(format.Indent, int(indentation))
|
|
lines := strings.Split(in, "\n")
|
|
return indent + strings.Join(lines, fmt.Sprintf("\n%s", indent))
|
|
}
|
|
|
|
// EqualErrorType returns an error with an Is(error)bool function that matches
|
|
// any error with the same type as the supplied error.
|
|
//
|
|
// Use with testutil.Equal to handle error comparisons.
|
|
func EqualErrorType(err error) equalErrorType {
|
|
return equalErrorType{
|
|
err: err,
|
|
}
|
|
}
|
|
|
|
type equalErrorType struct {
|
|
err error
|
|
}
|
|
|
|
func (e equalErrorType) Error() string {
|
|
return "EqualErrorType"
|
|
}
|
|
|
|
func (e equalErrorType) Is(err error) bool {
|
|
if err == nil {
|
|
return false
|
|
}
|
|
return reflect.TypeOf(e.err) == reflect.TypeOf(err)
|
|
}
|
|
|
|
func (e equalErrorType) Unwrap() error {
|
|
return e.err
|
|
}
|
|
|
|
// EqualErrorString returns an error with an Is(error)bool function that matches
|
|
// any error with the same Error() as the supplied string value.
|
|
//
|
|
// Use with testutil.Equal to handle error comparisons.
|
|
func EqualErrorString(err string) equalErrorString {
|
|
return equalErrorString{
|
|
err: err,
|
|
}
|
|
}
|
|
|
|
// equalError is an error that matches any non-nil error of the specified type.
|
|
type equalErrorString struct {
|
|
err string
|
|
}
|
|
|
|
func (e equalErrorString) Error() string {
|
|
return e.err
|
|
}
|
|
|
|
func (e equalErrorString) Is(err error) bool {
|
|
if err == nil {
|
|
return false
|
|
}
|
|
return e.err == err.Error()
|
|
}
|
|
|
|
// AssertEqual fails the test if the actual value does not deeply equal the
|
|
// expected value. Prints a diff on failure.
|
|
func AssertEqual(t *testing.T, actual, expected interface{}) {
|
|
t.Helper() // print the caller's file:line, instead of this func, on failure
|
|
matcher := Equal(expected)
|
|
match, err := matcher.Match(actual)
|
|
if err != nil {
|
|
t.Errorf("errored testing equality: %s", err)
|
|
}
|
|
if !match {
|
|
t.Error(matcher.FailureMessage(actual))
|
|
}
|
|
}
|
|
|
|
// AssertNotEqual fails the test if the actual value deeply equals the
|
|
// expected value. Prints a diff on failure.
|
|
func AssertNotEqual(t *testing.T, actual, expected interface{}) {
|
|
t.Helper() // print the caller's file:line, instead of this func, on failure
|
|
matcher := Equal(expected)
|
|
match, err := matcher.Match(actual)
|
|
if err != nil {
|
|
t.Errorf("errored testing equality: %s", err)
|
|
}
|
|
if match {
|
|
t.Error(matcher.NegatedFailureMessage(actual))
|
|
}
|
|
}
|