From b6135c096146079a67dbbd221fa51b63dda7f4a7 Mon Sep 17 00:00:00 2001 From: App Platform Runtime Working Group CI Bot Date: Sun, 1 Dec 2024 03:08:14 +0000 Subject: [PATCH] Update go.mod dependencies -------- index 77512eee..ee63e013 100644 @@ -15,15 +15,15 @@ replace github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2 exclude code.cloudfoundry.org/executor v0.1442.0 - code.cloudfoundry.org/cf-networking-helpers v0.27.0 - code.cloudfoundry.org/debugserver v0.25.0 - code.cloudfoundry.org/diego-logging-client v0.30.0 + code.cloudfoundry.org/cf-networking-helpers v0.28.0 + code.cloudfoundry.org/debugserver v0.26.0 + code.cloudfoundry.org/diego-logging-client v0.31.0 code.cloudfoundry.org/executor v0.0.0-20230406153242-208a08c51850 - code.cloudfoundry.org/filelock v0.19.0 - code.cloudfoundry.org/garden v0.0.0-20241120020832-f199cabc97c3 + code.cloudfoundry.org/filelock v0.20.0 + code.cloudfoundry.org/garden v0.0.0-20241127021034-06ec4d3844e0 code.cloudfoundry.org/go-loggregator/v9 v9.2.1 - code.cloudfoundry.org/lager/v3 v3.15.0 - code.cloudfoundry.org/policy_client v0.29.0 + code.cloudfoundry.org/lager/v3 v3.16.0 + code.cloudfoundry.org/policy_client v0.30.0 code.cloudfoundry.org/runtimeschema v0.0.0-20240514235758-31be7684c5bf github.com/cloudfoundry/dropsonde v1.1.0 github.com/containernetworking/cni v1.2.3 github.com/jmoiron/sqlx v1.4.0 github.com/lib/pq v1.10.9 github.com/onsi/ginkgo/v2 v2.22.0 - github.com/onsi/gomega v1.35.1 + github.com/onsi/gomega v1.36.0 github.com/pivotal-cf-experimental/gomegamatchers v0.0.0-20180326192815-e36bfcc98c3a github.com/pkg/errors v0.9.1 github.com/rubenv/sql-migrate v1.7.0 --- src/code.cloudfoundry.org/go.mod | 20 +- src/code.cloudfoundry.org/go.sum | 40 +-- .../github.com/onsi/gomega/CHANGELOG.md | 9 + .../github.com/onsi/gomega/gomega_dsl.go | 2 +- .../onsi/gomega/matchers/be_empty_matcher.go | 16 +- .../onsi/gomega/matchers/consist_of.go | 32 ++- .../matchers/contain_element_matcher.go | 239 +++++++++++++----- .../matchers/contain_elements_matcher.go | 5 +- .../onsi/gomega/matchers/have_each_matcher.go | 40 ++- .../gomega/matchers/have_exact_elements.go | 53 +++- .../onsi/gomega/matchers/have_key_matcher.go | 19 +- .../matchers/have_key_with_value_matcher.go | 26 +- .../onsi/gomega/matchers/have_len_matcher.go | 2 +- .../internal/miter/type_support_iter.go | 128 ++++++++++ .../internal/miter/type_support_noiter.go | 44 ++++ .../onsi/gomega/matchers/type_support.go | 13 + src/code.cloudfoundry.org/vendor/modules.txt | 21 +- 17 files changed, 588 insertions(+), 121 deletions(-) create mode 100644 src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/internal/miter/type_support_iter.go create mode 100644 src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/internal/miter/type_support_noiter.go diff --git a/src/code.cloudfoundry.org/go.mod b/src/code.cloudfoundry.org/go.mod index 77512eee..ee63e013 100644 --- a/src/code.cloudfoundry.org/go.mod +++ b/src/code.cloudfoundry.org/go.mod @@ -15,15 +15,15 @@ replace github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2 exclude code.cloudfoundry.org/executor v0.1442.0 require ( - code.cloudfoundry.org/cf-networking-helpers v0.27.0 - code.cloudfoundry.org/debugserver v0.25.0 - code.cloudfoundry.org/diego-logging-client v0.30.0 + code.cloudfoundry.org/cf-networking-helpers v0.28.0 + code.cloudfoundry.org/debugserver v0.26.0 + code.cloudfoundry.org/diego-logging-client v0.31.0 code.cloudfoundry.org/executor v0.0.0-20230406153242-208a08c51850 - code.cloudfoundry.org/filelock v0.19.0 - code.cloudfoundry.org/garden v0.0.0-20241120020832-f199cabc97c3 + code.cloudfoundry.org/filelock v0.20.0 + code.cloudfoundry.org/garden v0.0.0-20241127021034-06ec4d3844e0 code.cloudfoundry.org/go-loggregator/v9 v9.2.1 - code.cloudfoundry.org/lager/v3 v3.15.0 - code.cloudfoundry.org/policy_client v0.29.0 + code.cloudfoundry.org/lager/v3 v3.16.0 + code.cloudfoundry.org/policy_client v0.30.0 code.cloudfoundry.org/runtimeschema v0.0.0-20240514235758-31be7684c5bf github.com/cloudfoundry/dropsonde v1.1.0 github.com/containernetworking/cni v1.2.3 @@ -37,7 +37,7 @@ require ( github.com/jmoiron/sqlx v1.4.0 github.com/lib/pq v1.10.9 github.com/onsi/ginkgo/v2 v2.22.0 - github.com/onsi/gomega v1.35.1 + github.com/onsi/gomega v1.36.0 github.com/pivotal-cf-experimental/gomegamatchers v0.0.0-20180326192815-e36bfcc98c3a github.com/pkg/errors v0.9.1 github.com/rubenv/sql-migrate v1.7.0 @@ -52,7 +52,7 @@ require ( require ( code.cloudfoundry.org/bbs v0.0.0-20241029001107-2bebce403fed // indirect code.cloudfoundry.org/clock v1.1.0 // indirect - code.cloudfoundry.org/go-diodes v0.0.0-20241104194350-6f18271962f1 // indirect + code.cloudfoundry.org/go-diodes v0.0.0-20241125060457-612558937770 // indirect code.cloudfoundry.org/locket v0.0.0-20230406154009-5e8522d975d2 // indirect code.cloudfoundry.org/routing-info v0.0.0-20241025163841-3f7521aac814 // indirect code.cloudfoundry.org/tlsconfig v0.10.0 // indirect @@ -66,7 +66,7 @@ require ( github.com/go-test/deep v1.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/google/go-cmp v0.6.0 // indirect - github.com/google/pprof v0.0.0-20241122213907-cbe949e5a41b // indirect + github.com/google/pprof v0.0.0-20241128161848-dc51965c6481 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/jackc/pgx/v5 v5.5.5 // indirect github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect diff --git a/src/code.cloudfoundry.org/go.sum b/src/code.cloudfoundry.org/go.sum index b9bf27eb..9d5abdc7 100644 --- a/src/code.cloudfoundry.org/go.sum +++ b/src/code.cloudfoundry.org/go.sum @@ -594,30 +594,30 @@ cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= code.cloudfoundry.org/bbs v0.0.0-20241029001107-2bebce403fed h1:lcK8khEvQegfbSrJ3YYGNxq3oVK9GYvG9Sh1dLXQIwc= code.cloudfoundry.org/bbs v0.0.0-20241029001107-2bebce403fed/go.mod h1:XKlGVVXFi5EcHHMPzw3xgONK9PeEZuUbIC43XNwxD10= -code.cloudfoundry.org/cf-networking-helpers v0.27.0 h1:dXmYFg3tuRXIv20jQaHKVO2OKQ0K01N3BOJ44Td3Dng= -code.cloudfoundry.org/cf-networking-helpers v0.27.0/go.mod h1:k6aIUBQeon9LY6q+bW4Sgh38TAGmC6JkBib/AOiPcag= +code.cloudfoundry.org/cf-networking-helpers v0.28.0 h1:JJ1cgL8i18hj3cchGcjza0WMQepNB12t0i2TaVNOthw= +code.cloudfoundry.org/cf-networking-helpers v0.28.0/go.mod h1:NWkDDjbfznZYXJf74yrzchOvJdtiNUjgj4NeIdl88II= code.cloudfoundry.org/clock v1.1.0 h1:XLzC6W3Ah/Y7ht1rmZ6+QfPdt1iGWEAAtIZXgiaj57c= code.cloudfoundry.org/clock v1.1.0/go.mod h1:yA3fxddT9RINQL2XHS7PS+OXxKCGhfrZmlNUCIM6AKo= -code.cloudfoundry.org/debugserver v0.25.0 h1:D13+4IIT95Fbdfsk1Q6sviBJmJFhQJfKmTNpzFdmjU4= -code.cloudfoundry.org/debugserver v0.25.0/go.mod h1:S2mo8GHzgUE7YWUNsyKdiaMWi8P2MCDikVOZ5MRFbb0= -code.cloudfoundry.org/diego-logging-client v0.30.0 h1:2/YZ532UmZZpqDLKVYWxfzoPgk72p2lSoMTthC64mpw= -code.cloudfoundry.org/diego-logging-client v0.30.0/go.mod h1:+54+qQnqp9m7Rxa36RLEVfIV5jTvdVneJgZbQBIs7s4= +code.cloudfoundry.org/debugserver v0.26.0 h1:YzRUfAzAZ1dLRNWF4W62AeN8Rb050rQy2wQK+vA3Hw4= +code.cloudfoundry.org/debugserver v0.26.0/go.mod h1:idaPvlIj+FLyunxSN7zDb1CDJcdmr+8yz7cJf217aDc= +code.cloudfoundry.org/diego-logging-client v0.31.0 h1:oZKkHizm6zatB9sIKp7E3w2foUjWCykMjVOyinFCn6s= +code.cloudfoundry.org/diego-logging-client v0.31.0/go.mod h1:1H47e4sQm+p48ucOAUq3mtQ/k4VQSqyv95qA3ajuI6g= code.cloudfoundry.org/executor v0.0.0-20230406153242-208a08c51850 h1:DmHNflNF95mAK5VFERMEt5xF1Kx3KZcM216V+VUB0vI= code.cloudfoundry.org/executor v0.0.0-20230406153242-208a08c51850/go.mod h1:oemBimQzPedAfYleiBj968jpfEkSw8F5OsP+zYkVMRk= -code.cloudfoundry.org/filelock v0.19.0 h1:gYlbTHXNQp+6bvQhsJC/g1gKtGY28cIWXta0iN/uPT8= -code.cloudfoundry.org/filelock v0.19.0/go.mod h1:0ZFQxqbYyBa2vXWwFhd21LeMqhAAMIftw5KH+Jdinkk= -code.cloudfoundry.org/garden v0.0.0-20241120020832-f199cabc97c3 h1:j49uvc9JzG2bSRoytHXnV60CyDoZWtlemhH4X7w904I= -code.cloudfoundry.org/garden v0.0.0-20241120020832-f199cabc97c3/go.mod h1:iN698KtiTGzqGX6X5za6o7RD13fVKPDc0SNDBiGvWQ0= -code.cloudfoundry.org/go-diodes v0.0.0-20241104194350-6f18271962f1 h1:hq2DOWkD1TUDjXX87XCL2gJAkQlrTBg5hrdeY9oI85k= -code.cloudfoundry.org/go-diodes v0.0.0-20241104194350-6f18271962f1/go.mod h1:iKVp/Irul4GfauGPnBmTtaGY1RZm6nF5GW9ktab5CnU= +code.cloudfoundry.org/filelock v0.20.0 h1:6+NtVNmWXSXWFE17YqE3BLtuc7yysFay23SlI0e66lw= +code.cloudfoundry.org/filelock v0.20.0/go.mod h1:ZVuSVFUYnvDkYwIMNhfKTUaJ9AnvdoCnUL4x3X0OG3M= +code.cloudfoundry.org/garden v0.0.0-20241127021034-06ec4d3844e0 h1:UQSuRrdfSyeP/6M0xa9QHMQZoK+QqIyXbzy99Os1yxg= +code.cloudfoundry.org/garden v0.0.0-20241127021034-06ec4d3844e0/go.mod h1:6ZsljwYvAZgG4JhbLehxW0zDmp8/qpA0QNeO/W1FpDE= +code.cloudfoundry.org/go-diodes v0.0.0-20241125060457-612558937770 h1:mIdbJ1bQpJ/EboT42Hz2g2e79yDns1nKYoNB01T+BO0= +code.cloudfoundry.org/go-diodes v0.0.0-20241125060457-612558937770/go.mod h1:LUuklsZ+vM4POrCPtgmPssFlsId1zYprvC0jWmhQghw= code.cloudfoundry.org/go-loggregator/v9 v9.2.1 h1:S6Lgg5UJbhh2bt2TGQxs6R00CF8PrUA3GFPYDxy56Fk= code.cloudfoundry.org/go-loggregator/v9 v9.2.1/go.mod h1:FTFFruqGeOhVCDFvyLgl8EV8YW63NNwRzLhxJcporu8= -code.cloudfoundry.org/lager/v3 v3.15.0 h1:n31lbeh9krwuQLCRUWNEVZBk/BFEtyhQBwDZxFauPw4= -code.cloudfoundry.org/lager/v3 v3.15.0/go.mod h1:x5XGPsP6QF0HMW/FpRilBHu4gy+cWRur8/fiZEyj6z8= +code.cloudfoundry.org/lager/v3 v3.16.0 h1:v7LnlPN+6tiLmE4qHLP4FHRwywRoG3cNE43vIS35O2E= +code.cloudfoundry.org/lager/v3 v3.16.0/go.mod h1:BBAP7NdUAZLLhJhcbjFWX4w4uNpDWgSMMAPc6lX/wT0= code.cloudfoundry.org/locket v0.0.0-20230406154009-5e8522d975d2 h1:tUpafuylA0aTl6sdQnf20OsO/ipCvdNSZlWOB1cHhz8= code.cloudfoundry.org/locket v0.0.0-20230406154009-5e8522d975d2/go.mod h1:AwHLRkdXtttLXNB8RHgLfErJ2kKafH62AR2OClhy6xI= -code.cloudfoundry.org/policy_client v0.29.0 h1:eWlsINtMN9DaFLq/hCbU8ktUW1vUzqmjVSDyHgq+7Vo= -code.cloudfoundry.org/policy_client v0.29.0/go.mod h1:Ccw9xWyLPHz3HQy1kmD0cDWa37pHP28uCTMnTX9oLWs= +code.cloudfoundry.org/policy_client v0.30.0 h1:yAy2MeNg+fgkLUH6NAPjpiN79mtjKoe1srZ9vF/yQqo= +code.cloudfoundry.org/policy_client v0.30.0/go.mod h1:1X6LU0XQR8mJHNIfzw0xsMl/iPKYgsHjFL82Y3c9N1Y= code.cloudfoundry.org/routing-info v0.0.0-20241025163841-3f7521aac814 h1:m8m8wsEpS2+Iat7FzYp8XmAui2glgvCt0tpmRhHH8/U= code.cloudfoundry.org/routing-info v0.0.0-20241025163841-3f7521aac814/go.mod h1:ykLgqzJGV5PTkvxtfyOy8hcQy7wxPaoV5ZPyk74aqp8= code.cloudfoundry.org/runtimeschema v0.0.0-20180622181441-7dcd19348be6 h1:J08p1/LBnhv5BDDf0WLpHRyMJFCws3vd3fLCFL/iVnQ= @@ -821,8 +821,8 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20241122213907-cbe949e5a41b h1:SXO0REt4iu865upYCk8aKBBJQ4BqoE0ReP23ClMu60s= -github.com/google/pprof v0.0.0-20241122213907-cbe949e5a41b/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20241128161848-dc51965c6481 h1:yudKIrXagAOl99WQzrP1gbz5HLB9UjhcOFnPzdd6Qec= +github.com/google/pprof v0.0.0-20241128161848-dc51965c6481/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= @@ -945,8 +945,8 @@ github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfad github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw= github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ= github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= -github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= -github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/onsi/gomega v1.36.0 h1:Pb12RlruUtj4XUuPUqeEWc6j5DkVVVA49Uf6YLfC95Y= +github.com/onsi/gomega v1.36.0/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg= github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c= github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= diff --git a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/CHANGELOG.md b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/CHANGELOG.md index 9f6090b8..b797577f 100644 --- a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/CHANGELOG.md +++ b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/CHANGELOG.md @@ -1,3 +1,12 @@ +## 1.36.0 + +### Features +- new: make collection-related matchers Go 1.23 iterator aware [4c964c6] + +### Maintenance +- Replace min/max helpers with built-in min/max [ece6872] +- Fix some typos in docs [8e924d7] + ## 1.35.1 ### Fixes diff --git a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/gomega_dsl.go b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/gomega_dsl.go index 1038d7dd..eb74f6f6 100644 --- a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/gomega_dsl.go +++ b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/gomega_dsl.go @@ -22,7 +22,7 @@ import ( "github.com/onsi/gomega/types" ) -const GOMEGA_VERSION = "1.35.1" +const GOMEGA_VERSION = "1.36.0" const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler. If you're using Ginkgo then you probably forgot to put your assertion in an It(). diff --git a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/be_empty_matcher.go b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/be_empty_matcher.go index 527c1a1c..bd7f0b96 100644 --- a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/be_empty_matcher.go +++ b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/be_empty_matcher.go @@ -4,17 +4,31 @@ package matchers import ( "fmt" + "reflect" "github.com/onsi/gomega/format" + "github.com/onsi/gomega/matchers/internal/miter" ) type BeEmptyMatcher struct { } func (matcher *BeEmptyMatcher) Match(actual interface{}) (success bool, err error) { + // short-circuit the iterator case, as we only need to see the first + // element, if any. + if miter.IsIter(actual) { + var length int + if miter.IsSeq2(actual) { + miter.IterateKV(actual, func(k, v reflect.Value) bool { length++; return false }) + } else { + miter.IterateV(actual, func(v reflect.Value) bool { length++; return false }) + } + return length == 0, nil + } + length, ok := lengthOf(actual) if !ok { - return false, fmt.Errorf("BeEmpty matcher expects a string/array/map/channel/slice. Got:\n%s", format.Object(actual, 1)) + return false, fmt.Errorf("BeEmpty matcher expects a string/array/map/channel/slice/iterator. Got:\n%s", format.Object(actual, 1)) } return length == 0, nil diff --git a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/consist_of.go b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/consist_of.go index f69037a4..a1118818 100644 --- a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/consist_of.go +++ b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/consist_of.go @@ -7,6 +7,7 @@ import ( "reflect" "github.com/onsi/gomega/format" + "github.com/onsi/gomega/matchers/internal/miter" "github.com/onsi/gomega/matchers/support/goraph/bipartitegraph" ) @@ -17,8 +18,8 @@ type ConsistOfMatcher struct { } func (matcher *ConsistOfMatcher) Match(actual interface{}) (success bool, err error) { - if !isArrayOrSlice(actual) && !isMap(actual) { - return false, fmt.Errorf("ConsistOf matcher expects an array/slice/map. Got:\n%s", format.Object(actual, 1)) + if !isArrayOrSlice(actual) && !isMap(actual) && !miter.IsIter(actual) { + return false, fmt.Errorf("ConsistOf matcher expects an array/slice/map/iter.Seq/iter.Seq2. Got:\n%s", format.Object(actual, 1)) } matchers := matchers(matcher.Elements) @@ -60,10 +61,21 @@ func equalMatchersToElements(matchers []interface{}) (elements []interface{}) { } func flatten(elems []interface{}) []interface{} { - if len(elems) != 1 || !isArrayOrSlice(elems[0]) { + if len(elems) != 1 || + !(isArrayOrSlice(elems[0]) || + (miter.IsIter(elems[0]) && !miter.IsSeq2(elems[0]))) { return elems } + if miter.IsIter(elems[0]) { + flattened := []any{} + miter.IterateV(elems[0], func(v reflect.Value) bool { + flattened = append(flattened, v.Interface()) + return true + }) + return flattened + } + value := reflect.ValueOf(elems[0]) flattened := make([]interface{}, value.Len()) for i := 0; i < value.Len(); i++ { @@ -116,7 +128,19 @@ func presentable(elems []interface{}) interface{} { func valuesOf(actual interface{}) []interface{} { value := reflect.ValueOf(actual) values := []interface{}{} - if isMap(actual) { + if miter.IsIter(actual) { + if miter.IsSeq2(actual) { + miter.IterateKV(actual, func(k, v reflect.Value) bool { + values = append(values, v.Interface()) + return true + }) + } else { + miter.IterateV(actual, func(v reflect.Value) bool { + values = append(values, v.Interface()) + return true + }) + } + } else if isMap(actual) { keys := value.MapKeys() for i := 0; i < value.Len(); i++ { values = append(values, value.MapIndex(keys[i]).Interface()) diff --git a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go index 3d45c9eb..830239c7 100644 --- a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go +++ b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go @@ -8,6 +8,7 @@ import ( "reflect" "github.com/onsi/gomega/format" + "github.com/onsi/gomega/matchers/internal/miter" ) type ContainElementMatcher struct { @@ -16,16 +17,18 @@ type ContainElementMatcher struct { } func (matcher *ContainElementMatcher) Match(actual interface{}) (success bool, err error) { - if !isArrayOrSlice(actual) && !isMap(actual) { - return false, fmt.Errorf("ContainElement matcher expects an array/slice/map. Got:\n%s", format.Object(actual, 1)) + if !isArrayOrSlice(actual) && !isMap(actual) && !miter.IsIter(actual) { + return false, fmt.Errorf("ContainElement matcher expects an array/slice/map/iterator. Got:\n%s", format.Object(actual, 1)) } var actualT reflect.Type var result reflect.Value - switch l := len(matcher.Result); { - case l > 1: + switch numResultArgs := len(matcher.Result); { + case numResultArgs > 1: return false, errors.New("ContainElement matcher expects at most a single optional pointer to store its findings at") - case l == 1: + case numResultArgs == 1: + // Check the optional result arg to point to a single value/array/slice/map + // of a type compatible with the actual value. if reflect.ValueOf(matcher.Result[0]).Kind() != reflect.Ptr { return false, fmt.Errorf("ContainElement matcher expects a non-nil pointer to store its findings at. Got\n%s", format.Object(matcher.Result[0], 1)) @@ -34,93 +37,209 @@ func (matcher *ContainElementMatcher) Match(actual interface{}) (success bool, e resultReference := matcher.Result[0] result = reflect.ValueOf(resultReference).Elem() // what ResultReference points to, to stash away our findings switch result.Kind() { - case reflect.Array: + case reflect.Array: // result arrays are not supported, as they cannot be dynamically sized. + if miter.IsIter(actual) { + _, actualvT := miter.IterKVTypes(actual) + return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", + reflect.SliceOf(actualvT), result.Type().String()) + } return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", reflect.SliceOf(actualT.Elem()).String(), result.Type().String()) - case reflect.Slice: - if !isArrayOrSlice(actual) { + + case reflect.Slice: // result slice + // can we assign elements in actual to elements in what the result + // arg points to? + // - ✔ actual is an array or slice + // - ✔ actual is an iter.Seq producing "v" elements + // - ✔ actual is an iter.Seq2 producing "v" elements, ignoring + // the "k" elements. + switch { + case isArrayOrSlice(actual): + if !actualT.Elem().AssignableTo(result.Type().Elem()) { + return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", + actualT.String(), result.Type().String()) + } + + case miter.IsIter(actual): + _, actualvT := miter.IterKVTypes(actual) + if !actualvT.AssignableTo(result.Type().Elem()) { + return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", + actualvT.String(), result.Type().String()) + } + + default: // incompatible result reference return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", reflect.MapOf(actualT.Key(), actualT.Elem()).String(), result.Type().String()) } - if !actualT.Elem().AssignableTo(result.Type().Elem()) { - return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", - actualT.String(), result.Type().String()) - } - case reflect.Map: - if !isMap(actual) { - return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", - actualT.String(), result.Type().String()) - } - if !actualT.AssignableTo(result.Type()) { + + case reflect.Map: // result map + // can we assign elements in actual to elements in what the result + // arg points to? + // - ✔ actual is a map + // - ✔ actual is an iter.Seq2 (iter.Seq doesn't fit though) + switch { + case isMap(actual): + if !actualT.AssignableTo(result.Type()) { + return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", + actualT.String(), result.Type().String()) + } + + case miter.IsIter(actual): + actualkT, actualvT := miter.IterKVTypes(actual) + if actualkT == nil { + return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", + reflect.SliceOf(actualvT).String(), result.Type().String()) + } + if !reflect.MapOf(actualkT, actualvT).AssignableTo(result.Type()) { + return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", + reflect.MapOf(actualkT, actualvT), result.Type().String()) + } + + default: // incompatible result reference return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", actualT.String(), result.Type().String()) } + default: - if !actualT.Elem().AssignableTo(result.Type()) { - return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", - actualT.Elem().String(), result.Type().String()) + // can we assign a (single) element in actual to what the result arg + // points to? + switch { + case miter.IsIter(actual): + _, actualvT := miter.IterKVTypes(actual) + if !actualvT.AssignableTo(result.Type()) { + return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", + actualvT.String(), result.Type().String()) + } + default: + if !actualT.Elem().AssignableTo(result.Type()) { + return false, fmt.Errorf("ContainElement cannot return findings. Need *%s, got *%s", + actualT.Elem().String(), result.Type().String()) + } } } } + // If the supplied matcher isn't an Omega matcher, default to the Equal + // matcher. elemMatcher, elementIsMatcher := matcher.Element.(omegaMatcher) if !elementIsMatcher { elemMatcher = &EqualMatcher{Expected: matcher.Element} } value := reflect.ValueOf(actual) - var valueAt func(int) interface{} - var getFindings func() reflect.Value - var foundAt func(int) + var getFindings func() reflect.Value // abstracts how the findings are collected and stored + var lastError error - if isMap(actual) { - keys := value.MapKeys() - valueAt = func(i int) interface{} { - return value.MapIndex(keys[i]).Interface() + if !miter.IsIter(actual) { + var valueAt func(int) interface{} + var foundAt func(int) + // We're dealing with an array/slice/map, so in all cases we can iterate + // over the elements in actual using indices (that can be considered + // keys in case of maps). + if isMap(actual) { + keys := value.MapKeys() + valueAt = func(i int) interface{} { + return value.MapIndex(keys[i]).Interface() + } + if result.Kind() != reflect.Invalid { + fm := reflect.MakeMap(actualT) + getFindings = func() reflect.Value { return fm } + foundAt = func(i int) { + fm.SetMapIndex(keys[i], value.MapIndex(keys[i])) + } + } + } else { + valueAt = func(i int) interface{} { + return value.Index(i).Interface() + } + if result.Kind() != reflect.Invalid { + var fsl reflect.Value + if result.Kind() == reflect.Slice { + fsl = reflect.MakeSlice(result.Type(), 0, 0) + } else { + fsl = reflect.MakeSlice(reflect.SliceOf(result.Type()), 0, 0) + } + getFindings = func() reflect.Value { return fsl } + foundAt = func(i int) { + fsl = reflect.Append(fsl, value.Index(i)) + } + } } - if result.Kind() != reflect.Invalid { - fm := reflect.MakeMap(actualT) - getFindings = func() reflect.Value { - return fm + + for i := 0; i < value.Len(); i++ { + elem := valueAt(i) + success, err := elemMatcher.Match(elem) + if err != nil { + lastError = err + continue } - foundAt = func(i int) { - fm.SetMapIndex(keys[i], value.MapIndex(keys[i])) + if success { + if result.Kind() == reflect.Invalid { + return true, nil + } + foundAt(i) } } } else { - valueAt = func(i int) interface{} { - return value.Index(i).Interface() - } + // We're dealing with an iterator as a first-class construct, so things + // are slightly different: there is no index defined as in case of + // arrays/slices/maps, just "ooooorder" + var found func(k, v reflect.Value) if result.Kind() != reflect.Invalid { - var f reflect.Value - if result.Kind() == reflect.Slice { - f = reflect.MakeSlice(result.Type(), 0, 0) + if result.Kind() == reflect.Map { + fm := reflect.MakeMap(result.Type()) + getFindings = func() reflect.Value { return fm } + found = func(k, v reflect.Value) { fm.SetMapIndex(k, v) } } else { - f = reflect.MakeSlice(reflect.SliceOf(result.Type()), 0, 0) - } - getFindings = func() reflect.Value { - return f - } - foundAt = func(i int) { - f = reflect.Append(f, value.Index(i)) + var fsl reflect.Value + if result.Kind() == reflect.Slice { + fsl = reflect.MakeSlice(result.Type(), 0, 0) + } else { + fsl = reflect.MakeSlice(reflect.SliceOf(result.Type()), 0, 0) + } + getFindings = func() reflect.Value { return fsl } + found = func(_, v reflect.Value) { fsl = reflect.Append(fsl, v) } } } - } - var lastError error - for i := 0; i < value.Len(); i++ { - elem := valueAt(i) - success, err := elemMatcher.Match(elem) - if err != nil { - lastError = err - continue + success := false + actualkT, _ := miter.IterKVTypes(actual) + if actualkT == nil { + miter.IterateV(actual, func(v reflect.Value) bool { + var err error + success, err = elemMatcher.Match(v.Interface()) + if err != nil { + lastError = err + return true // iterate on... + } + if success { + if result.Kind() == reflect.Invalid { + return false // a match and no result needed, so we're done + } + found(reflect.Value{}, v) + } + return true // iterate on... + }) + } else { + miter.IterateKV(actual, func(k, v reflect.Value) bool { + var err error + success, err = elemMatcher.Match(v.Interface()) + if err != nil { + lastError = err + return true // iterate on... + } + if success { + if result.Kind() == reflect.Invalid { + return false // a match and no result needed, so we're done + } + found(k, v) + } + return true // iterate on... + }) } - if success { - if result.Kind() == reflect.Invalid { - return true, nil - } - foundAt(i) + if success && result.Kind() == reflect.Invalid { + return true, nil } } diff --git a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go index 946cd8be..d9fcb8b8 100644 --- a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go +++ b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/contain_elements_matcher.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/onsi/gomega/format" + "github.com/onsi/gomega/matchers/internal/miter" "github.com/onsi/gomega/matchers/support/goraph/bipartitegraph" ) @@ -13,8 +14,8 @@ type ContainElementsMatcher struct { } 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)) + if !isArrayOrSlice(actual) && !isMap(actual) && !miter.IsIter(actual) { + return false, fmt.Errorf("ContainElements matcher expects an array/slice/map/iter.Seq/iter.Seq2. Got:\n%s", format.Object(actual, 1)) } matchers := matchers(matcher.Elements) diff --git a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_each_matcher.go b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_each_matcher.go index 025b6e1a..4111f2b8 100644 --- a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_each_matcher.go +++ b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_each_matcher.go @@ -5,6 +5,7 @@ import ( "reflect" "github.com/onsi/gomega/format" + "github.com/onsi/gomega/matchers/internal/miter" ) type HaveEachMatcher struct { @@ -12,8 +13,8 @@ type HaveEachMatcher struct { } func (matcher *HaveEachMatcher) Match(actual interface{}) (success bool, err error) { - if !isArrayOrSlice(actual) && !isMap(actual) { - return false, fmt.Errorf("HaveEach matcher expects an array/slice/map. Got:\n%s", + if !isArrayOrSlice(actual) && !isMap(actual) && !miter.IsIter(actual) { + return false, fmt.Errorf("HaveEach matcher expects an array/slice/map/iter.Seq/iter.Seq2. Got:\n%s", format.Object(actual, 1)) } @@ -22,6 +23,38 @@ func (matcher *HaveEachMatcher) Match(actual interface{}) (success bool, err err elemMatcher = &EqualMatcher{Expected: matcher.Element} } + if miter.IsIter(actual) { + // rejecting the non-elements case works different for iterators as we + // don't want to fetch all elements into a slice first. + count := 0 + var success bool + var err error + if miter.IsSeq2(actual) { + miter.IterateKV(actual, func(k, v reflect.Value) bool { + count++ + success, err = elemMatcher.Match(v.Interface()) + if err != nil { + return false + } + return success + }) + } else { + miter.IterateV(actual, func(v reflect.Value) bool { + count++ + success, err = elemMatcher.Match(v.Interface()) + if err != nil { + return false + } + return success + }) + } + if count == 0 { + return false, fmt.Errorf("HaveEach matcher expects a non-empty iter.Seq/iter.Seq2. Got:\n%s", + format.Object(actual, 1)) + } + return success, err + } + value := reflect.ValueOf(actual) if value.Len() == 0 { return false, fmt.Errorf("HaveEach matcher expects a non-empty array/slice/map. Got:\n%s", @@ -40,7 +73,8 @@ func (matcher *HaveEachMatcher) Match(actual interface{}) (success bool, err err } } - // if there are no elements, then HaveEach will match. + // if we never failed then we succeed; the empty/nil cases have already been + // rejected above. for i := 0; i < value.Len(); i++ { success, err := elemMatcher.Match(valueAt(i)) if err != nil { diff --git a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_exact_elements.go b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_exact_elements.go index 5a236d7d..23799f1c 100644 --- a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_exact_elements.go +++ b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_exact_elements.go @@ -2,8 +2,10 @@ package matchers import ( "fmt" + "reflect" "github.com/onsi/gomega/format" + "github.com/onsi/gomega/matchers/internal/miter" ) type mismatchFailure struct { @@ -21,17 +23,58 @@ type HaveExactElementsMatcher struct { func (matcher *HaveExactElementsMatcher) Match(actual interface{}) (success bool, err error) { matcher.resetState() - if isMap(actual) { - return false, fmt.Errorf("error") + if isMap(actual) || miter.IsSeq2(actual) { + return false, fmt.Errorf("HaveExactElements matcher doesn't work on map or iter.Seq2. Got:\n%s", format.Object(actual, 1)) } matchers := matchers(matcher.Elements) - values := valuesOf(actual) - lenMatchers := len(matchers) - lenValues := len(values) + success = true + if miter.IsIter(actual) { + // In the worst case, we need to see everything before we can give our + // verdict. The only exception is fast fail. + i := 0 + miter.IterateV(actual, func(v reflect.Value) bool { + if i >= lenMatchers { + // the iterator produces more values than we got matchers: this + // is not good. + matcher.extraIndex = i + success = false + return false + } + + elemMatcher := matchers[i].(omegaMatcher) + match, err := elemMatcher.Match(v.Interface()) + if err != nil { + matcher.mismatchFailures = append(matcher.mismatchFailures, mismatchFailure{ + index: i, + failure: err.Error(), + }) + success = false + } else if !match { + matcher.mismatchFailures = append(matcher.mismatchFailures, mismatchFailure{ + index: i, + failure: elemMatcher.FailureMessage(v.Interface()), + }) + success = false + } + i++ + return true + }) + if i < len(matchers) { + // the iterator produced less values than we got matchers: this is + // no good, no no no. + matcher.missingIndex = i + success = false + } + return success, nil + } + + values := valuesOf(actual) + lenValues := len(values) + for i := 0; i < lenMatchers || i < lenValues; i++ { if i >= lenMatchers { matcher.extraIndex = i diff --git a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go index 00cffec7..b62ee93c 100644 --- a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go +++ b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go @@ -7,6 +7,7 @@ import ( "reflect" "github.com/onsi/gomega/format" + "github.com/onsi/gomega/matchers/internal/miter" ) type HaveKeyMatcher struct { @@ -14,8 +15,8 @@ type HaveKeyMatcher struct { } func (matcher *HaveKeyMatcher) Match(actual interface{}) (success bool, err error) { - if !isMap(actual) { - return false, fmt.Errorf("HaveKey matcher expects a map. Got:%s", format.Object(actual, 1)) + if !isMap(actual) && !miter.IsSeq2(actual) { + return false, fmt.Errorf("HaveKey matcher expects a map/iter.Seq2. Got:%s", format.Object(actual, 1)) } keyMatcher, keyIsMatcher := matcher.Key.(omegaMatcher) @@ -23,6 +24,20 @@ func (matcher *HaveKeyMatcher) Match(actual interface{}) (success bool, err erro keyMatcher = &EqualMatcher{Expected: matcher.Key} } + if miter.IsSeq2(actual) { + var success bool + var err error + miter.IterateKV(actual, func(k, v reflect.Value) bool { + success, err = keyMatcher.Match(k.Interface()) + if err != nil { + err = fmt.Errorf("HaveKey's key matcher failed with:\n%s%s", format.Indent, err.Error()) + return false + } + return !success + }) + return success, err + } + keys := reflect.ValueOf(actual).MapKeys() for i := 0; i < len(keys); i++ { success, err := keyMatcher.Match(keys[i].Interface()) diff --git a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go index 4c591680..3d608f63 100644 --- a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go +++ b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go @@ -7,6 +7,7 @@ import ( "reflect" "github.com/onsi/gomega/format" + "github.com/onsi/gomega/matchers/internal/miter" ) type HaveKeyWithValueMatcher struct { @@ -15,8 +16,8 @@ type HaveKeyWithValueMatcher struct { } func (matcher *HaveKeyWithValueMatcher) Match(actual interface{}) (success bool, err error) { - if !isMap(actual) { - return false, fmt.Errorf("HaveKeyWithValue matcher expects a map. Got:%s", format.Object(actual, 1)) + if !isMap(actual) && !miter.IsSeq2(actual) { + return false, fmt.Errorf("HaveKeyWithValue matcher expects a map/iter.Seq2. Got:%s", format.Object(actual, 1)) } keyMatcher, keyIsMatcher := matcher.Key.(omegaMatcher) @@ -29,6 +30,27 @@ func (matcher *HaveKeyWithValueMatcher) Match(actual interface{}) (success bool, valueMatcher = &EqualMatcher{Expected: matcher.Value} } + if miter.IsSeq2(actual) { + var success bool + var err error + miter.IterateKV(actual, func(k, v reflect.Value) bool { + success, err = keyMatcher.Match(k.Interface()) + if err != nil { + err = fmt.Errorf("HaveKey's key matcher failed with:\n%s%s", format.Indent, err.Error()) + return false + } + if success { + success, err = valueMatcher.Match(v.Interface()) + if err != nil { + err = fmt.Errorf("HaveKeyWithValue's value matcher failed with:\n%s%s", format.Indent, err.Error()) + return false + } + } + return !success + }) + return success, err + } + keys := reflect.ValueOf(actual).MapKeys() for i := 0; i < len(keys); i++ { success, err := keyMatcher.Match(keys[i].Interface()) diff --git a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_len_matcher.go b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_len_matcher.go index ee427618..ca25713f 100644 --- a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_len_matcher.go +++ b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/have_len_matcher.go @@ -13,7 +13,7 @@ type HaveLenMatcher struct { func (matcher *HaveLenMatcher) Match(actual interface{}) (success bool, err error) { length, ok := lengthOf(actual) if !ok { - return false, fmt.Errorf("HaveLen matcher expects a string/array/map/channel/slice. Got:\n%s", format.Object(actual, 1)) + return false, fmt.Errorf("HaveLen matcher expects a string/array/map/channel/slice/iterator. Got:\n%s", format.Object(actual, 1)) } return length == matcher.Count, nil diff --git a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/internal/miter/type_support_iter.go b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/internal/miter/type_support_iter.go new file mode 100644 index 00000000..d8837a4d --- /dev/null +++ b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/internal/miter/type_support_iter.go @@ -0,0 +1,128 @@ +//go:build go1.23 + +package miter + +import ( + "reflect" +) + +// HasIterators always returns false for Go versions before 1.23. +func HasIterators() bool { return true } + +// IsIter returns true if the specified value is a function type that can be +// range-d over, otherwise false. +// +// We don't use reflect's CanSeq and CanSeq2 directly, as these would return +// true also for other value types that are range-able, such as integers, +// slices, et cetera. Here, we aim only at range-able (iterator) functions. +func IsIter(it any) bool { + if it == nil { // on purpose we only test for untyped nil. + return false + } + // reject all non-iterator-func values, even if they're range-able. + t := reflect.TypeOf(it) + if t.Kind() != reflect.Func { + return false + } + return t.CanSeq() || t.CanSeq2() +} + +// IterKVTypes returns the reflection types of an iterator's yield function's K +// and optional V arguments, otherwise nil K and V reflection types. +func IterKVTypes(it any) (k, v reflect.Type) { + if it == nil { + return + } + // reject all non-iterator-func values, even if they're range-able. + t := reflect.TypeOf(it) + if t.Kind() != reflect.Func { + return + } + // get the reflection types for V, and where applicable, K. + switch { + case t.CanSeq(): + v = t. /*iterator fn*/ In(0). /*yield fn*/ In(0) + case t.CanSeq2(): + yieldfn := t. /*iterator fn*/ In(0) + k = yieldfn.In(0) + v = yieldfn.In(1) + } + return +} + +// IsSeq2 returns true if the passed iterator function is compatible with +// iter.Seq2, otherwise false. +// +// IsSeq2 hides the Go 1.23+ specific reflect.Type.CanSeq2 behind a facade which +// is empty for Go versions before 1.23. +func IsSeq2(it any) bool { + if it == nil { + return false + } + t := reflect.TypeOf(it) + return t.Kind() == reflect.Func && t.CanSeq2() +} + +// isNilly returns true if v is either an untyped nil, or is a nil function (not +// necessarily an iterator function). +func isNilly(v any) bool { + if v == nil { + return true + } + rv := reflect.ValueOf(v) + return rv.Kind() == reflect.Func && rv.IsNil() +} + +// IterateV loops over the elements produced by an iterator function, passing +// the elements to the specified yield function individually and stopping only +// when either the iterator function runs out of elements or the yield function +// tell us to stop it. +// +// IterateV works very much like reflect.Value.Seq but hides the Go 1.23+ +// specific parts behind a facade which is empty for Go versions before 1.23, in +// order to simplify code maintenance for matchers when using older Go versions. +func IterateV(it any, yield func(v reflect.Value) bool) { + if isNilly(it) { + return + } + // reject all non-iterator-func values, even if they're range-able. + t := reflect.TypeOf(it) + if t.Kind() != reflect.Func || !t.CanSeq() { + return + } + // Call the specified iterator function, handing it our adaptor to call the + // specified generic reflection yield function. + reflectedYield := reflect.MakeFunc( + t. /*iterator fn*/ In(0), + func(args []reflect.Value) []reflect.Value { + return []reflect.Value{reflect.ValueOf(yield(args[0]))} + }) + reflect.ValueOf(it).Call([]reflect.Value{reflectedYield}) +} + +// IterateKV loops over the key-value elements produced by an iterator function, +// passing the elements to the specified yield function individually and +// stopping only when either the iterator function runs out of elements or the +// yield function tell us to stop it. +// +// IterateKV works very much like reflect.Value.Seq2 but hides the Go 1.23+ +// specific parts behind a facade which is empty for Go versions before 1.23, in +// order to simplify code maintenance for matchers when using older Go versions. +func IterateKV(it any, yield func(k, v reflect.Value) bool) { + if isNilly(it) { + return + } + // reject all non-iterator-func values, even if they're range-able. + t := reflect.TypeOf(it) + if t.Kind() != reflect.Func || !t.CanSeq2() { + return + } + // Call the specified iterator function, handing it our adaptor to call the + // specified generic reflection yield function. + reflectedYield := reflect.MakeFunc( + t. /*iterator fn*/ In(0), + func(args []reflect.Value) []reflect.Value { + return []reflect.Value{reflect.ValueOf(yield(args[0], args[1]))} + }) + reflect.ValueOf(it).Call([]reflect.Value{reflectedYield}) +} diff --git a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/internal/miter/type_support_noiter.go b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/internal/miter/type_support_noiter.go new file mode 100644 index 00000000..4b8fcc55 --- /dev/null +++ b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/internal/miter/type_support_noiter.go @@ -0,0 +1,44 @@ +//go:build !go1.23 + +/* +Gomega matchers + +This package implements the Gomega matchers and does not typically need to be imported. +See the docs for Gomega for documentation on the matchers + +http://onsi.github.io/gomega/ +*/ + +package miter + +import "reflect" + +// HasIterators always returns false for Go versions before 1.23. +func HasIterators() bool { return false } + +// IsIter always returns false for Go versions before 1.23 as there is no +// iterator (function) pattern defined yet; see also: +// https://tip.golang.org/blog/range-functions. +func IsIter(i any) bool { return false } + +// IsSeq2 always returns false for Go versions before 1.23 as there is no +// iterator (function) pattern defined yet; see also: +// https://tip.golang.org/blog/range-functions. +func IsSeq2(it any) bool { return false } + +// IterKVTypes always returns nil reflection types for Go versions before 1.23 +// as there is no iterator (function) pattern defined yet; see also: +// https://tip.golang.org/blog/range-functions. +func IterKVTypes(i any) (k, v reflect.Type) { + return +} + +// IterateV never loops over what has been passed to it as an iterator for Go +// versions before 1.23 as there is no iterator (function) pattern defined yet; +// see also: https://tip.golang.org/blog/range-functions. +func IterateV(it any, yield func(v reflect.Value) bool) {} + +// IterateKV never loops over what has been passed to it as an iterator for Go +// versions before 1.23 as there is no iterator (function) pattern defined yet; +// see also: https://tip.golang.org/blog/range-functions. +func IterateKV(it any, yield func(k, v reflect.Value) bool) {} diff --git a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/type_support.go b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/type_support.go index dced2419..b9440ac7 100644 --- a/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/type_support.go +++ b/src/code.cloudfoundry.org/vendor/github.com/onsi/gomega/matchers/type_support.go @@ -15,6 +15,8 @@ import ( "encoding/json" "fmt" "reflect" + + "github.com/onsi/gomega/matchers/internal/miter" ) type omegaMatcher interface { @@ -152,6 +154,17 @@ func lengthOf(a interface{}) (int, bool) { switch reflect.TypeOf(a).Kind() { case reflect.Map, reflect.Array, reflect.String, reflect.Chan, reflect.Slice: return reflect.ValueOf(a).Len(), true + case reflect.Func: + if !miter.IsIter(a) { + return 0, false + } + var l int + if miter.IsSeq2(a) { + miter.IterateKV(a, func(k, v reflect.Value) bool { l++; return true }) + } else { + miter.IterateV(a, func(v reflect.Value) bool { l++; return true }) + } + return l, true default: return 0, false } diff --git a/src/code.cloudfoundry.org/vendor/modules.txt b/src/code.cloudfoundry.org/vendor/modules.txt index a99a1b9e..0bc1644e 100644 --- a/src/code.cloudfoundry.org/vendor/modules.txt +++ b/src/code.cloudfoundry.org/vendor/modules.txt @@ -3,7 +3,7 @@ code.cloudfoundry.org/bbs/encryption code.cloudfoundry.org/bbs/format code.cloudfoundry.org/bbs/models -# code.cloudfoundry.org/cf-networking-helpers v0.27.0 +# code.cloudfoundry.org/cf-networking-helpers v0.28.0 ## explicit; go 1.22.0 code.cloudfoundry.org/cf-networking-helpers/db code.cloudfoundry.org/cf-networking-helpers/db/monitor @@ -21,27 +21,27 @@ code.cloudfoundry.org/cf-networking-helpers/testsupport/metrics code.cloudfoundry.org/cf-networking-helpers/testsupport/ports # code.cloudfoundry.org/clock v1.1.0 ## explicit; go 1.20 -# code.cloudfoundry.org/debugserver v0.25.0 +# code.cloudfoundry.org/debugserver v0.26.0 ## explicit; go 1.22.0 code.cloudfoundry.org/debugserver -# code.cloudfoundry.org/diego-logging-client v0.30.0 +# code.cloudfoundry.org/diego-logging-client v0.31.0 ## explicit; go 1.22.7 code.cloudfoundry.org/diego-logging-client code.cloudfoundry.org/diego-logging-client/testhelpers # code.cloudfoundry.org/executor v0.0.0-20230406153242-208a08c51850 ## explicit code.cloudfoundry.org/executor -# code.cloudfoundry.org/filelock v0.19.0 +# code.cloudfoundry.org/filelock v0.20.0 ## explicit; go 1.22.0 code.cloudfoundry.org/filelock -# code.cloudfoundry.org/garden v0.0.0-20241120020832-f199cabc97c3 +# code.cloudfoundry.org/garden v0.0.0-20241127021034-06ec4d3844e0 ## explicit; go 1.22.0 code.cloudfoundry.org/garden code.cloudfoundry.org/garden/client code.cloudfoundry.org/garden/client/connection code.cloudfoundry.org/garden/routes code.cloudfoundry.org/garden/transport -# code.cloudfoundry.org/go-diodes v0.0.0-20241104194350-6f18271962f1 +# code.cloudfoundry.org/go-diodes v0.0.0-20241125060457-612558937770 ## explicit; go 1.22.0 code.cloudfoundry.org/go-diodes # code.cloudfoundry.org/go-loggregator/v9 v9.2.1 @@ -49,7 +49,7 @@ code.cloudfoundry.org/go-diodes code.cloudfoundry.org/go-loggregator/v9 code.cloudfoundry.org/go-loggregator/v9/rpc/loggregator_v2 code.cloudfoundry.org/go-loggregator/v9/runtimeemitter -# code.cloudfoundry.org/lager/v3 v3.15.0 +# code.cloudfoundry.org/lager/v3 v3.16.0 ## explicit; go 1.22.0 code.cloudfoundry.org/lager/v3 code.cloudfoundry.org/lager/v3/internal/truncate @@ -58,7 +58,7 @@ code.cloudfoundry.org/lager/v3/lagerflags code.cloudfoundry.org/lager/v3/lagertest # code.cloudfoundry.org/locket v0.0.0-20230406154009-5e8522d975d2 ## explicit -# code.cloudfoundry.org/policy_client v0.29.0 +# code.cloudfoundry.org/policy_client v0.30.0 ## explicit; go 1.22.0 code.cloudfoundry.org/policy_client # code.cloudfoundry.org/routing-info v0.0.0-20241025163841-3f7521aac814 @@ -157,7 +157,7 @@ github.com/google/go-cmp/cmp/internal/diff github.com/google/go-cmp/cmp/internal/flags github.com/google/go-cmp/cmp/internal/function github.com/google/go-cmp/cmp/internal/value -# github.com/google/pprof v0.0.0-20241122213907-cbe949e5a41b +# github.com/google/pprof v0.0.0-20241128161848-dc51965c6481 ## explicit; go 1.22 github.com/google/pprof/profile # github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 @@ -215,7 +215,7 @@ github.com/onsi/ginkgo/v2/internal/parallel_support github.com/onsi/ginkgo/v2/internal/testingtproxy github.com/onsi/ginkgo/v2/reporters github.com/onsi/ginkgo/v2/types -# github.com/onsi/gomega v1.35.1 +# github.com/onsi/gomega v1.36.0 ## explicit; go 1.22 github.com/onsi/gomega github.com/onsi/gomega/format @@ -225,6 +225,7 @@ github.com/onsi/gomega/ghttp github.com/onsi/gomega/internal github.com/onsi/gomega/internal/gutil github.com/onsi/gomega/matchers +github.com/onsi/gomega/matchers/internal/miter github.com/onsi/gomega/matchers/support/goraph/bipartitegraph github.com/onsi/gomega/matchers/support/goraph/edge github.com/onsi/gomega/matchers/support/goraph/node