summaryrefslogtreecommitdiff
path: root/vendor/github.com/onsi/gomega/gstruct/elements.go
diff options
context:
space:
mode:
authorJhon Honce <jhonce@redhat.com>2021-09-13 14:29:22 -0700
committerMatthew Heon <mheon@redhat.com>2021-09-16 09:42:14 -0400
commit74bc365eb6f036a87313ffe5acd3561d3c44638f (patch)
treea758b7fc4fe7e35c1cfd344c4d432e75160b50fe /vendor/github.com/onsi/gomega/gstruct/elements.go
parente37883f13e6f9e659a044eaa5dba46bab166e3a6 (diff)
downloadpodman-74bc365eb6f036a87313ffe5acd3561d3c44638f.tar.gz
podman-74bc365eb6f036a87313ffe5acd3561d3c44638f.tar.bz2
podman-74bc365eb6f036a87313ffe5acd3561d3c44638f.zip
Enhance bindings for IDE hints
* Follow https://pkg.go.dev/cmd/go#hdr-Generate_Go_files_by_processing_source for leading comment * Add godoc strings for all exposed methods for IDE support * Copy field godoc strings into generated code as function godoc string * Remove unused/unnecessary fields from generator.go structures * Cleanup code regarding template usage Signed-off-by: Jhon Honce <jhonce@redhat.com>
Diffstat (limited to 'vendor/github.com/onsi/gomega/gstruct/elements.go')
-rw-r--r--vendor/github.com/onsi/gomega/gstruct/elements.go231
1 files changed, 231 insertions, 0 deletions
diff --git a/vendor/github.com/onsi/gomega/gstruct/elements.go b/vendor/github.com/onsi/gomega/gstruct/elements.go
new file mode 100644
index 000000000..b5e5ef2e4
--- /dev/null
+++ b/vendor/github.com/onsi/gomega/gstruct/elements.go
@@ -0,0 +1,231 @@
+// untested sections: 6
+
+package gstruct
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+ "runtime/debug"
+ "strconv"
+
+ "github.com/onsi/gomega/format"
+ errorsutil "github.com/onsi/gomega/gstruct/errors"
+ "github.com/onsi/gomega/types"
+)
+
+//MatchAllElements succeeds if every element of a slice matches the element matcher it maps to
+//through the id function, and every element matcher is matched.
+// idFn := func(element interface{}) string {
+// return fmt.Sprintf("%v", element)
+// }
+//
+// Expect([]string{"a", "b"}).To(MatchAllElements(idFn, Elements{
+// "a": Equal("a"),
+// "b": Equal("b"),
+// }))
+func MatchAllElements(identifier Identifier, elements Elements) types.GomegaMatcher {
+ return &ElementsMatcher{
+ Identifier: identifier,
+ Elements: elements,
+ }
+}
+
+//MatchAllElementsWithIndex succeeds if every element of a slice matches the element matcher it maps to
+//through the id with index function, and every element matcher is matched.
+// idFn := func(index int, element interface{}) string {
+// return strconv.Itoa(index)
+// }
+//
+// Expect([]string{"a", "b"}).To(MatchAllElements(idFn, Elements{
+// "0": Equal("a"),
+// "1": Equal("b"),
+// }))
+func MatchAllElementsWithIndex(identifier IdentifierWithIndex, elements Elements) types.GomegaMatcher {
+ return &ElementsMatcher{
+ Identifier: identifier,
+ Elements: elements,
+ }
+}
+
+//MatchElements succeeds if each element of a slice matches the element matcher it maps to
+//through the id function. It can ignore extra elements and/or missing elements.
+// idFn := func(element interface{}) string {
+// return fmt.Sprintf("%v", element)
+// }
+//
+// Expect([]string{"a", "b", "c"}).To(MatchElements(idFn, IgnoreExtras, Elements{
+// "a": Equal("a"),
+// "b": Equal("b"),
+// }))
+// Expect([]string{"a", "c"}).To(MatchElements(idFn, IgnoreMissing, Elements{
+// "a": Equal("a"),
+// "b": Equal("b"),
+// "c": Equal("c"),
+// "d": Equal("d"),
+// }))
+func MatchElements(identifier Identifier, options Options, elements Elements) types.GomegaMatcher {
+ return &ElementsMatcher{
+ Identifier: identifier,
+ Elements: elements,
+ IgnoreExtras: options&IgnoreExtras != 0,
+ IgnoreMissing: options&IgnoreMissing != 0,
+ AllowDuplicates: options&AllowDuplicates != 0,
+ }
+}
+
+//MatchElementsWithIndex succeeds if each element of a slice matches the element matcher it maps to
+//through the id with index function. It can ignore extra elements and/or missing elements.
+// idFn := func(index int, element interface{}) string {
+// return strconv.Itoa(index)
+// }
+//
+// Expect([]string{"a", "b", "c"}).To(MatchElements(idFn, IgnoreExtras, Elements{
+// "0": Equal("a"),
+// "1": Equal("b"),
+// }))
+// Expect([]string{"a", "c"}).To(MatchElements(idFn, IgnoreMissing, Elements{
+// "0": Equal("a"),
+// "1": Equal("b"),
+// "2": Equal("c"),
+// "3": Equal("d"),
+// }))
+func MatchElementsWithIndex(identifier IdentifierWithIndex, options Options, elements Elements) types.GomegaMatcher {
+ return &ElementsMatcher{
+ Identifier: identifier,
+ Elements: elements,
+ IgnoreExtras: options&IgnoreExtras != 0,
+ IgnoreMissing: options&IgnoreMissing != 0,
+ AllowDuplicates: options&AllowDuplicates != 0,
+ }
+}
+
+// ElementsMatcher is a NestingMatcher that applies custom matchers to each element of a slice mapped
+// by the Identifier function.
+// TODO: Extend this to work with arrays & maps (map the key) as well.
+type ElementsMatcher struct {
+ // Matchers for each element.
+ Elements Elements
+ // Function mapping an element to the string key identifying its matcher.
+ Identifier Identify
+
+ // Whether to ignore extra elements or consider it an error.
+ IgnoreExtras bool
+ // Whether to ignore missing elements or consider it an error.
+ IgnoreMissing bool
+ // Whether to key duplicates when matching IDs.
+ AllowDuplicates bool
+
+ // State.
+ failures []error
+}
+
+// Element ID to matcher.
+type Elements map[string]types.GomegaMatcher
+
+// Function for identifying (mapping) elements.
+type Identifier func(element interface{}) string
+
+// Calls the underlying fucntion with the provided params.
+// Identifier drops the index.
+func (i Identifier) WithIndexAndElement(index int, element interface{}) string {
+ return i(element)
+}
+
+// Uses the index and element to generate an element name
+type IdentifierWithIndex func(index int, element interface{}) string
+
+// Calls the underlying fucntion with the provided params.
+// IdentifierWithIndex uses the index.
+func (i IdentifierWithIndex) WithIndexAndElement(index int, element interface{}) string {
+ return i(index, element)
+}
+
+// Interface for identifing the element
+type Identify interface {
+ WithIndexAndElement(i int, element interface{}) string
+}
+
+// IndexIdentity is a helper function for using an index as
+// the key in the element map
+func IndexIdentity(index int, _ interface{}) string {
+ return strconv.Itoa(index)
+}
+
+func (m *ElementsMatcher) Match(actual interface{}) (success bool, err error) {
+ if reflect.TypeOf(actual).Kind() != reflect.Slice {
+ return false, fmt.Errorf("%v is type %T, expected slice", actual, actual)
+ }
+
+ m.failures = m.matchElements(actual)
+ if len(m.failures) > 0 {
+ return false, nil
+ }
+ return true, nil
+}
+
+func (m *ElementsMatcher) matchElements(actual interface{}) (errs []error) {
+ // Provide more useful error messages in the case of a panic.
+ defer func() {
+ if err := recover(); err != nil {
+ errs = append(errs, fmt.Errorf("panic checking %+v: %v\n%s", actual, err, debug.Stack()))
+ }
+ }()
+
+ val := reflect.ValueOf(actual)
+ elements := map[string]bool{}
+ for i := 0; i < val.Len(); i++ {
+ element := val.Index(i).Interface()
+ id := m.Identifier.WithIndexAndElement(i, element)
+ if elements[id] {
+ if !m.AllowDuplicates {
+ errs = append(errs, fmt.Errorf("found duplicate element ID %s", id))
+ continue
+ }
+ }
+ elements[id] = true
+
+ matcher, expected := m.Elements[id]
+ if !expected {
+ if !m.IgnoreExtras {
+ errs = append(errs, fmt.Errorf("unexpected element %s", id))
+ }
+ continue
+ }
+
+ match, err := matcher.Match(element)
+ if match {
+ continue
+ }
+
+ if err == nil {
+ if nesting, ok := matcher.(errorsutil.NestingMatcher); ok {
+ err = errorsutil.AggregateError(nesting.Failures())
+ } else {
+ err = errors.New(matcher.FailureMessage(element))
+ }
+ }
+ errs = append(errs, errorsutil.Nest(fmt.Sprintf("[%s]", id), err))
+ }
+
+ for id := range m.Elements {
+ if !elements[id] && !m.IgnoreMissing {
+ errs = append(errs, fmt.Errorf("missing expected element %s", id))
+ }
+ }
+
+ return errs
+}
+
+func (m *ElementsMatcher) FailureMessage(actual interface{}) (message string) {
+ failure := errorsutil.AggregateError(m.failures)
+ return format.Message(actual, fmt.Sprintf("to match elements: %v", failure))
+}
+
+func (m *ElementsMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+ return format.Message(actual, "not to match elements")
+}
+
+func (m *ElementsMatcher) Failures() []error {
+ return m.failures
+}