Merge pull request #5054 from containers/dependabot/go_modules/github.com/onsi/gomega-1.9.0

build(deps): bump github.com/onsi/gomega from 1.8.1 to 1.9.0
This commit is contained in:
Daniel J Walsh
2020-02-03 09:26:59 -05:00
committed by GitHub
12 changed files with 184 additions and 60 deletions

2
go.mod
View File

@ -47,7 +47,7 @@ require (
github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618 github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618
github.com/olekukonko/tablewriter v0.0.4 // indirect github.com/olekukonko/tablewriter v0.0.4 // indirect
github.com/onsi/ginkgo v1.11.0 github.com/onsi/ginkgo v1.11.0
github.com/onsi/gomega v1.8.1 github.com/onsi/gomega v1.9.0
github.com/opencontainers/go-digest v1.0.0-rc1 github.com/opencontainers/go-digest v1.0.0-rc1
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6
github.com/opencontainers/runc v1.0.0-rc9 github.com/opencontainers/runc v1.0.0-rc9

2
go.sum
View File

@ -390,6 +390,8 @@ github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34= github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34=
github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg=
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=

View File

@ -1,3 +1,10 @@
## 1.9.0
### Features
- Add ContainElements matcher (#370) [2f57380]
- Output missing and extra elements in ConsistOf failure message [a31eda7]
- Document method LargestMatching [7c5a280]
## 1.8.1 ## 1.8.1
### Fixes ### Fixes

View File

@ -24,7 +24,7 @@ import (
"github.com/onsi/gomega/types" "github.com/onsi/gomega/types"
) )
const GOMEGA_VERSION = "1.8.1" const GOMEGA_VERSION = "1.9.0"
const nilFailHandlerPanic = `You are trying to make an assertion, but Gomega's fail handler is nil. const nilFailHandlerPanic = `You are trying to make an assertion, but Gomega's fail handler is nil.
If you're using Ginkgo then you probably forgot to put your assertion in an It(). If you're using Ginkgo then you probably forgot to put your assertion in an It().

View File

@ -306,6 +306,20 @@ func ConsistOf(elements ...interface{}) types.GomegaMatcher {
} }
} }
//ContainElements succeeds if actual contains the passed in elements. The ordering of the elements does not matter.
//By default ContainElements() uses Equal() to match the elements, however custom matchers can be passed in instead. Here are some examples:
//
// Expect([]string{"Foo", "FooBar"}).Should(ContainElements("FooBar"))
// Expect([]string{"Foo", "FooBar"}).Should(ContainElements(ContainSubstring("Bar"), "Foo"))
//
//Actual must be an array, slice or map.
//For maps, ContainElements searches through the map's values.
func ContainElements(elements ...interface{}) types.GomegaMatcher {
return &matchers.ContainElementsMatcher{
Elements: elements,
}
}
//HaveKey succeeds if actual is a map with the passed in key. //HaveKey succeeds if actual is a map with the passed in key.
//By default HaveKey uses Equal() to perform the match, however a //By default HaveKey uses Equal() to perform the match, however a
//matcher can be passed in instead: //matcher can be passed in instead:

View File

@ -12,6 +12,8 @@ import (
type ConsistOfMatcher struct { type ConsistOfMatcher struct {
Elements []interface{} Elements []interface{}
missingElements []interface{}
extraElements []interface{}
} }
func (matcher *ConsistOfMatcher) Match(actual interface{}) (success bool, err error) { func (matcher *ConsistOfMatcher) Match(actual interface{}) (success bool, err error) {
@ -19,44 +21,63 @@ func (matcher *ConsistOfMatcher) Match(actual interface{}) (success bool, err er
return false, fmt.Errorf("ConsistOf matcher expects an array/slice/map. Got:\n%s", format.Object(actual, 1)) return false, fmt.Errorf("ConsistOf matcher expects an array/slice/map. Got:\n%s", format.Object(actual, 1))
} }
elements := matcher.Elements matchers := matchers(matcher.Elements)
if len(matcher.Elements) == 1 && isArrayOrSlice(matcher.Elements[0]) { values := valuesOf(actual)
elements = []interface{}{}
value := reflect.ValueOf(matcher.Elements[0])
for i := 0; i < value.Len(); i++ {
elements = append(elements, value.Index(i).Interface())
}
}
matchers := []interface{}{}
for _, element := range elements {
matcher, isMatcher := element.(omegaMatcher)
if !isMatcher {
matcher = &EqualMatcher{Expected: element}
}
matchers = append(matchers, matcher)
}
values := matcher.valuesOf(actual)
if len(values) != len(matchers) {
return false, nil
}
neighbours := func(v, m interface{}) (bool, error) {
match, err := m.(omegaMatcher).Match(v)
return match && err == nil, nil
}
bipartiteGraph, err := bipartitegraph.NewBipartiteGraph(values, matchers, neighbours) bipartiteGraph, err := bipartitegraph.NewBipartiteGraph(values, matchers, neighbours)
if err != nil { if err != nil {
return false, err return false, err
} }
return len(bipartiteGraph.LargestMatching()) == len(values), nil edges := bipartiteGraph.LargestMatching()
if len(edges) == len(values) && len(edges) == len(matchers) {
return true, nil
} }
func (matcher *ConsistOfMatcher) valuesOf(actual interface{}) []interface{} { var missingMatchers []interface{}
matcher.extraElements, missingMatchers = bipartiteGraph.FreeLeftRight(edges)
matcher.missingElements = equalMatchersToElements(missingMatchers)
return false, nil
}
func neighbours(value, matcher interface{}) (bool, error) {
match, err := matcher.(omegaMatcher).Match(value)
return match && err == nil, nil
}
func equalMatchersToElements(matchers []interface{}) (elements []interface{}) {
for _, matcher := range matchers {
equalMatcher, ok := matcher.(*EqualMatcher)
if ok {
matcher = equalMatcher.Expected
}
elements = append(elements, matcher)
}
return
}
func matchers(expectedElems []interface{}) (matchers []interface{}) {
elems := expectedElems
if len(expectedElems) == 1 && isArrayOrSlice(expectedElems[0]) {
elems = []interface{}{}
value := reflect.ValueOf(expectedElems[0])
for i := 0; i < value.Len(); i++ {
elems = append(elems, value.Index(i).Interface())
}
}
for _, e := range elems {
matcher, isMatcher := e.(omegaMatcher)
if !isMatcher {
matcher = &EqualMatcher{Expected: e}
}
matchers = append(matchers, matcher)
}
return
}
func valuesOf(actual interface{}) []interface{} {
value := reflect.ValueOf(actual) value := reflect.ValueOf(actual)
values := []interface{}{} values := []interface{}{}
if isMap(actual) { if isMap(actual) {
@ -74,7 +95,21 @@ func (matcher *ConsistOfMatcher) valuesOf(actual interface{}) []interface{} {
} }
func (matcher *ConsistOfMatcher) FailureMessage(actual interface{}) (message string) { func (matcher *ConsistOfMatcher) FailureMessage(actual interface{}) (message string) {
return format.Message(actual, "to consist of", matcher.Elements) message = format.Message(actual, "to consist of", matcher.Elements)
message = appendMissingElements(message, matcher.missingElements)
if len(matcher.extraElements) > 0 {
message = fmt.Sprintf("%s\nthe extra elements were\n%s", message,
format.Object(matcher.extraElements, 1))
}
return
}
func appendMissingElements(message string, missingElements []interface{}) string {
if len(missingElements) == 0 {
return message
}
return fmt.Sprintf("%s\nthe missing elements were\n%s", message,
format.Object(missingElements, 1))
} }
func (matcher *ConsistOfMatcher) NegatedFailureMessage(actual interface{}) (message string) { func (matcher *ConsistOfMatcher) NegatedFailureMessage(actual interface{}) (message string) {

View File

@ -0,0 +1,44 @@
package matchers
import (
"fmt"
"github.com/onsi/gomega/format"
"github.com/onsi/gomega/matchers/support/goraph/bipartitegraph"
)
type ContainElementsMatcher struct {
Elements []interface{}
missingElements []interface{}
}
func (matcher *ContainElementsMatcher) Match(actual interface{}) (success bool, err error) {
if !isArrayOrSlice(actual) && !isMap(actual) {
return false, fmt.Errorf("ContainElements matcher expects an array/slice/map. Got:\n%s", format.Object(actual, 1))
}
matchers := matchers(matcher.Elements)
bipartiteGraph, err := bipartitegraph.NewBipartiteGraph(valuesOf(actual), matchers, neighbours)
if err != nil {
return false, err
}
edges := bipartiteGraph.LargestMatching()
if len(edges) == len(matchers) {
return true, nil
}
_, missingMatchers := bipartiteGraph.FreeLeftRight(edges)
matcher.missingElements = equalMatchersToElements(missingMatchers)
return false, nil
}
func (matcher *ContainElementsMatcher) FailureMessage(actual interface{}) (message string) {
message = format.Message(actual, "to contain elements", matcher.Elements)
return appendMissingElements(message, matcher.missingElements)
}
func (matcher *ContainElementsMatcher) NegatedFailureMessage(actual interface{}) (message string) {
return format.Message(actual, "not to contain elements", matcher.Elements)
}

View File

@ -13,13 +13,13 @@ type BipartiteGraph struct {
func NewBipartiteGraph(leftValues, rightValues []interface{}, neighbours func(interface{}, interface{}) (bool, error)) (*BipartiteGraph, error) { func NewBipartiteGraph(leftValues, rightValues []interface{}, neighbours func(interface{}, interface{}) (bool, error)) (*BipartiteGraph, error) {
left := NodeOrderedSet{} left := NodeOrderedSet{}
for i := range leftValues { for i, v := range leftValues {
left = append(left, Node{Id: i}) left = append(left, Node{ID: i, Value: v})
} }
right := NodeOrderedSet{} right := NodeOrderedSet{}
for j := range rightValues { for j, v := range rightValues {
right = append(right, Node{Id: j + len(left)}) right = append(right, Node{ID: j + len(left), Value: v})
} }
edges := EdgeSet{} edges := EdgeSet{}
@ -31,10 +31,26 @@ func NewBipartiteGraph(leftValues, rightValues []interface{}, neighbours func(in
} }
if neighbours { if neighbours {
edges = append(edges, Edge{Node1: left[i], Node2: right[j]}) edges = append(edges, Edge{Node1: left[i].ID, Node2: right[j].ID})
} }
} }
} }
return &BipartiteGraph{left, right, edges}, nil return &BipartiteGraph{left, right, edges}, nil
} }
// FreeLeftRight returns left node values and right node values
// of the BipartiteGraph's nodes which are not part of the given edges.
func (bg *BipartiteGraph) FreeLeftRight(edges EdgeSet) (leftValues, rightValues []interface{}) {
for _, node := range bg.Left {
if edges.Free(node) {
leftValues = append(leftValues, node.Value)
}
}
for _, node := range bg.Right {
if edges.Free(node) {
rightValues = append(rightValues, node.Value)
}
}
return
}

View File

@ -1,9 +1,14 @@
package bipartitegraph package bipartitegraph
import . "github.com/onsi/gomega/matchers/support/goraph/node" import (
import . "github.com/onsi/gomega/matchers/support/goraph/edge" . "github.com/onsi/gomega/matchers/support/goraph/edge"
import "github.com/onsi/gomega/matchers/support/goraph/util" . "github.com/onsi/gomega/matchers/support/goraph/node"
"github.com/onsi/gomega/matchers/support/goraph/util"
)
// LargestMatching implements the HopcroftKarp algorithm taking as input a bipartite graph
// and outputting a maximum cardinality matching, i.e. a set of as many edges as possible
// with the property that no two edges share an endpoint.
func (bg *BipartiteGraph) LargestMatching() (matching EdgeSet) { func (bg *BipartiteGraph) LargestMatching() (matching EdgeSet) {
paths := bg.maximalDisjointSLAPCollection(matching) paths := bg.maximalDisjointSLAPCollection(matching)
@ -23,7 +28,7 @@ func (bg *BipartiteGraph) maximalDisjointSLAPCollection(matching EdgeSet) (resul
return return
} }
used := make(map[Node]bool) used := make(map[int]bool)
for _, u := range guideLayers[len(guideLayers)-1] { for _, u := range guideLayers[len(guideLayers)-1] {
slap, found := bg.findDisjointSLAP(u, matching, guideLayers, used) slap, found := bg.findDisjointSLAP(u, matching, guideLayers, used)
@ -43,7 +48,7 @@ func (bg *BipartiteGraph) findDisjointSLAP(
start Node, start Node,
matching EdgeSet, matching EdgeSet,
guideLayers []NodeOrderedSet, guideLayers []NodeOrderedSet,
used map[Node]bool, used map[int]bool,
) ([]Edge, bool) { ) ([]Edge, bool) {
return bg.findDisjointSLAPHelper(start, EdgeSet{}, len(guideLayers)-1, matching, guideLayers, used) return bg.findDisjointSLAPHelper(start, EdgeSet{}, len(guideLayers)-1, matching, guideLayers, used)
} }
@ -54,16 +59,16 @@ func (bg *BipartiteGraph) findDisjointSLAPHelper(
currentLevel int, currentLevel int,
matching EdgeSet, matching EdgeSet,
guideLayers []NodeOrderedSet, guideLayers []NodeOrderedSet,
used map[Node]bool, used map[int]bool,
) (EdgeSet, bool) { ) (EdgeSet, bool) {
used[currentNode] = true used[currentNode.ID] = true
if currentLevel == 0 { if currentLevel == 0 {
return currentSLAP, true return currentSLAP, true
} }
for _, nextNode := range guideLayers[currentLevel-1] { for _, nextNode := range guideLayers[currentLevel-1] {
if used[nextNode] { if used[nextNode.ID] {
continue continue
} }
@ -84,17 +89,17 @@ func (bg *BipartiteGraph) findDisjointSLAPHelper(
currentSLAP = currentSLAP[:len(currentSLAP)-1] currentSLAP = currentSLAP[:len(currentSLAP)-1]
} }
used[currentNode] = false used[currentNode.ID] = false
return nil, false return nil, false
} }
func (bg *BipartiteGraph) createSLAPGuideLayers(matching EdgeSet) (guideLayers []NodeOrderedSet) { func (bg *BipartiteGraph) createSLAPGuideLayers(matching EdgeSet) (guideLayers []NodeOrderedSet) {
used := make(map[Node]bool) used := make(map[int]bool)
currentLayer := NodeOrderedSet{} currentLayer := NodeOrderedSet{}
for _, node := range bg.Left { for _, node := range bg.Left {
if matching.Free(node) { if matching.Free(node) {
used[node] = true used[node.ID] = true
currentLayer = append(currentLayer, node) currentLayer = append(currentLayer, node)
} }
} }
@ -113,7 +118,7 @@ func (bg *BipartiteGraph) createSLAPGuideLayers(matching EdgeSet) (guideLayers [
if util.Odd(len(guideLayers)) { if util.Odd(len(guideLayers)) {
for _, leftNode := range lastLayer { for _, leftNode := range lastLayer {
for _, rightNode := range bg.Right { for _, rightNode := range bg.Right {
if used[rightNode] { if used[rightNode.ID] {
continue continue
} }
@ -123,7 +128,7 @@ func (bg *BipartiteGraph) createSLAPGuideLayers(matching EdgeSet) (guideLayers [
} }
currentLayer = append(currentLayer, rightNode) currentLayer = append(currentLayer, rightNode)
used[rightNode] = true used[rightNode.ID] = true
if matching.Free(rightNode) { if matching.Free(rightNode) {
done = true done = true
@ -133,7 +138,7 @@ func (bg *BipartiteGraph) createSLAPGuideLayers(matching EdgeSet) (guideLayers [
} else { } else {
for _, rightNode := range lastLayer { for _, rightNode := range lastLayer {
for _, leftNode := range bg.Left { for _, leftNode := range bg.Left {
if used[leftNode] { if used[leftNode.ID] {
continue continue
} }
@ -143,7 +148,7 @@ func (bg *BipartiteGraph) createSLAPGuideLayers(matching EdgeSet) (guideLayers [
} }
currentLayer = append(currentLayer, leftNode) currentLayer = append(currentLayer, leftNode)
used[leftNode] = true used[leftNode.ID] = true
} }
} }

View File

@ -3,15 +3,15 @@ package edge
import . "github.com/onsi/gomega/matchers/support/goraph/node" import . "github.com/onsi/gomega/matchers/support/goraph/node"
type Edge struct { type Edge struct {
Node1 Node Node1 int
Node2 Node Node2 int
} }
type EdgeSet []Edge type EdgeSet []Edge
func (ec EdgeSet) Free(node Node) bool { func (ec EdgeSet) Free(node Node) bool {
for _, e := range ec { for _, e := range ec {
if e.Node1 == node || e.Node2 == node { if e.Node1 == node.ID || e.Node2 == node.ID {
return false return false
} }
} }
@ -31,7 +31,7 @@ func (ec EdgeSet) Contains(edge Edge) bool {
func (ec EdgeSet) FindByNodes(node1, node2 Node) (Edge, bool) { func (ec EdgeSet) FindByNodes(node1, node2 Node) (Edge, bool) {
for _, e := range ec { for _, e := range ec {
if (e.Node1 == node1 && e.Node2 == node2) || (e.Node1 == node2 && e.Node2 == node1) { if (e.Node1 == node1.ID && e.Node2 == node2.ID) || (e.Node1 == node2.ID && e.Node2 == node1.ID) {
return e, true return e, true
} }
} }

View File

@ -1,7 +1,8 @@
package node package node
type Node struct { type Node struct {
Id int ID int
Value interface{}
} }
type NodeOrderedSet []Node type NodeOrderedSet []Node

2
vendor/modules.txt vendored
View File

@ -366,7 +366,7 @@ github.com/onsi/ginkgo/reporters/stenographer
github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable
github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty
github.com/onsi/ginkgo/types github.com/onsi/ginkgo/types
# github.com/onsi/gomega v1.8.1 # github.com/onsi/gomega v1.9.0
github.com/onsi/gomega github.com/onsi/gomega
github.com/onsi/gomega/format github.com/onsi/gomega/format
github.com/onsi/gomega/gbytes github.com/onsi/gomega/gbytes