diff --git a/.golangci.yml b/.golangci.yml index 98f5122..f1f7198 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -51,7 +51,12 @@ linters-settings: rules: - name: dot-imports arguments: - - allowedPackages: ["github.com/onsi/ginkgo/v2","github.com/onsi/gomega","github.com/onsi/gomega/gstruct"] + - allowedPackages: [ + "github.com/onsi/ginkgo/v2", + "github.com/onsi/gomega", + "github.com/onsi/gomega/gstruct", + "github.com/opendatahub-io/odh-platform/test/matchers" + ] importas: alias: - pkg: k8s.io/apimachinery/pkg/api/errors @@ -80,6 +85,11 @@ linters-settings: - generic # we want to return spi.Interfaces in routing.go and authconfig.go - spi + # for custom Gomega matchers + - types.GomegaMatcher + varnamelen: + ignore-names: + - g # g Gomega linters: enable-all: true disable: diff --git a/test/data/crds/test.component.crd.yaml b/test/data/crds/test.component.crd.yaml new file mode 100644 index 0000000..01e6d82 --- /dev/null +++ b/test/data/crds/test.component.crd.yaml @@ -0,0 +1,26 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: components.opendatahub.io +spec: + group: opendatahub.io + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + name: + type: string + scope: Namespaced + names: + plural: components + singular: component + kind: Component + shortNames: + - comp diff --git a/test/matchers/route.go b/test/matchers/route.go new file mode 100644 index 0000000..4f0dbe6 --- /dev/null +++ b/test/matchers/route.go @@ -0,0 +1,102 @@ +package matchers + +import ( + "fmt" + + "github.com/onsi/gomega" + "github.com/onsi/gomega/format" + "github.com/onsi/gomega/types" + openshiftroutev1 "github.com/openshift/api/route/v1" +) + +func HaveName(name string) types.GomegaMatcher { + return &routeNameMatcher{expectedName: name} +} + +type routeNameMatcher struct { + expectedName string +} + +func (r *routeNameMatcher) Match(actual any) (bool, error) { + if actual == nil { + return true, nil + } + + route, ok := actual.(*openshiftroutev1.Route) + if !ok { + return false, fmt.Errorf("expected Route. Got:\n%s", format.Object(actual, 1)) //nolint:goerr113 //reason helpful in assertions + } + + return gomega.Equal(r.expectedName).Match(route.Name) +} + +func (r *routeNameMatcher) FailureMessage(actual any) string { + return format.Message(actual, "to have name", r.expectedName) +} + +func (r *routeNameMatcher) NegatedFailureMessage(actual any) string { + return format.Message(actual, "to not have name", r.expectedName) +} + +func BeAttachedToService(svcName string) types.GomegaMatcher { + return &routeSvcMatcher{expectedSvcName: svcName} +} + +type routeSvcMatcher struct { + expectedSvcName string +} + +func (r *routeSvcMatcher) Match(actual any) (bool, error) { + if actual == nil { + return true, nil + } + + route, ok := actual.(*openshiftroutev1.Route) + if !ok { + return false, fmt.Errorf("expected Route. Got:\n%s", format.Object(actual, 1)) //nolint:goerr113 //reason helpful in assertions + } + + match, err := gomega.Equal("Service").Match(route.Spec.To.Kind) + if !match || err != nil { + return match, err + } + + return gomega.Equal(r.expectedSvcName).Match(route.Spec.To.Name) +} + +func (r *routeSvcMatcher) FailureMessage(actual any) string { + return format.Message(actual, "to be attached to service named", r.expectedSvcName) +} + +func (r *routeSvcMatcher) NegatedFailureMessage(actual any) string { + return format.Message(actual, "not to be attached to service named", r.expectedSvcName) +} + +func HaveHostPrefix(name string) types.GomegaMatcher { + return &routeHostPrefix{expectedHostPrefix: name} +} + +type routeHostPrefix struct { + expectedHostPrefix string +} + +func (matcher *routeHostPrefix) Match(actual any) (bool, error) { + if actual == nil { + return true, nil + } + + route, ok := actual.(*openshiftroutev1.Route) + if !ok { + return false, fmt.Errorf("expected Route. Got:\n%s", format.Object(actual, 1)) //nolint:goerr113 //reason helpful in assertions + } + + return gomega.HavePrefix(matcher.expectedHostPrefix).Match(route.Spec.Host) +} + +func (matcher *routeHostPrefix) FailureMessage(actual any) string { + return format.Message(actual, "to have host prefix", matcher.expectedHostPrefix) +} + +func (matcher *routeHostPrefix) NegatedFailureMessage(actual any) string { + return format.Message(actual, "to not have host prefix", matcher.expectedHostPrefix) +}