From e413d478888a57627614c4891d25ffac324ce69b Mon Sep 17 00:00:00 2001 From: Shalin Patel Date: Fri, 5 Apr 2024 13:52:26 -0700 Subject: [PATCH] test: move all Nutanix patch handler unit tests to their own packages (#32) * test: move controlplane endpoint unit tests * test: move PC endpoint unit tests * test: nove machinedetails unit tests --- .../generate_patches.go => inject_test.go} | 52 ++++++++---- ...atches.go => inject_control_plane_test.go} | 82 +++++++------------ .../machinedetails/inject_suite_test.go | 16 ++++ .../machinedetails/inject_worker_test.go | 59 +++++++++++++ .../mutation/metapatch_handler_test.go | 47 ----------- .../generate_patches.go => inject_test.go} | 58 ++++++++----- 6 files changed, 175 insertions(+), 139 deletions(-) rename pkg/handlers/nutanix/mutation/controlplaneendpoint/{tests/generate_patches.go => inject_test.go} (56%) rename pkg/handlers/nutanix/mutation/machinedetails/{tests/generate_patches.go => inject_control_plane_test.go} (72%) create mode 100644 pkg/handlers/nutanix/mutation/machinedetails/inject_suite_test.go create mode 100644 pkg/handlers/nutanix/mutation/machinedetails/inject_worker_test.go rename pkg/handlers/nutanix/mutation/prismcentralendpoint/{tests/generate_patches.go => inject_test.go} (80%) diff --git a/pkg/handlers/nutanix/mutation/controlplaneendpoint/tests/generate_patches.go b/pkg/handlers/nutanix/mutation/controlplaneendpoint/inject_test.go similarity index 56% rename from pkg/handlers/nutanix/mutation/controlplaneendpoint/tests/generate_patches.go rename to pkg/handlers/nutanix/mutation/controlplaneendpoint/inject_test.go index 8a93eb8f5..6ae946e79 100644 --- a/pkg/handlers/nutanix/mutation/controlplaneendpoint/tests/generate_patches.go +++ b/pkg/handlers/nutanix/mutation/controlplaneendpoint/inject_test.go @@ -1,11 +1,12 @@ // Copyright 2023 D2iQ, Inc. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package tests +package controlplaneendpoint import ( "testing" + . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" @@ -13,32 +14,35 @@ import ( "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" + nutanixclusterconfig "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/clusterconfig" ) -func TestGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() - - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ +func TestControlPlaneEndpointPatch(t *testing.T) { + gomega.RegisterFailHandler(Fail) + RunSpecs(t, "Nutanix ControlPlane endpoint suite") +} + +var _ = Describe("Generate Nutanix ControlPlane endpoint patches", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewPatch()).(mutation.GeneratePatches) + } + + testDefs := []capitest.PatchTestDef{ + { Name: "unset variable", }, - capitest.PatchTestDef{ + { Name: "ControlPlaneEndpoint set to valid host and port", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, clusterv1.APIEndpoint{ Host: "10.20.100.10", Port: 6443, }, - variablePath..., + nutanixclusterconfig.NutanixVariableName, + VariableName, ), }, RequestItem: request.NewNutanixClusterTemplateRequestItem(""), @@ -55,5 +59,17 @@ func TestGeneratePatches( }, }, }, - ) -} + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/nutanix/mutation/machinedetails/tests/generate_patches.go b/pkg/handlers/nutanix/mutation/machinedetails/inject_control_plane_test.go similarity index 72% rename from pkg/handlers/nutanix/mutation/machinedetails/tests/generate_patches.go rename to pkg/handlers/nutanix/mutation/machinedetails/inject_control_plane_test.go index 9e38b6214..3d05ef071 100644 --- a/pkg/handlers/nutanix/mutation/machinedetails/tests/generate_patches.go +++ b/pkg/handlers/nutanix/mutation/machinedetails/inject_control_plane_test.go @@ -1,13 +1,11 @@ // Copyright 2023 D2iQ, Inc. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package tests +package machinedetails import ( - "testing" - + . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/api/resource" "k8s.io/utils/ptr" runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" @@ -17,6 +15,8 @@ import ( "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" + nutanixclusterconfig "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/clusterconfig" ) var ( @@ -96,66 +96,40 @@ var ( } ) -func TestControlPlaneGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() +var _ = Describe("Generate Nutanix Machine Details patches for ControlPlane", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewControlPlanePatch()).(mutation.GeneratePatches) + } - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ + testDefs := []capitest.PatchTestDef{ + { Name: "unset variable", }, - capitest.PatchTestDef{ + { Name: "all fields set for control-plane", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, variableWithAllFieldsSet, - variablePath..., + clusterconfig.MetaControlPlaneConfigName, + nutanixclusterconfig.NutanixVariableName, + VariableName, ), }, RequestItem: request.NewCPNutanixMachineTemplateRequestItem(""), ExpectedPatchMatchers: matchersForAllFieldsSet, }, - ) -} - -func TestWorkerGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() + } - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ - Name: "unset variable", - }, - capitest.PatchTestDef{ - Name: "all fields set for workers", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - variableName, - variableWithAllFieldsSet, - variablePath..., - ), - capitest.VariableWithValue( - "builtin", - apiextensionsv1.JSON{ - Raw: []byte(`{"machineDeployment": {"class": "a-worker"}}`), - }, - ), - }, - RequestItem: request.NewWorkerNutanixMachineTemplateRequestItem(""), - ExpectedPatchMatchers: matchersForAllFieldsSet, - }, - ) -} + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/nutanix/mutation/machinedetails/inject_suite_test.go b/pkg/handlers/nutanix/mutation/machinedetails/inject_suite_test.go new file mode 100644 index 000000000..0bc40008e --- /dev/null +++ b/pkg/handlers/nutanix/mutation/machinedetails/inject_suite_test.go @@ -0,0 +1,16 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package machinedetails + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestMachineDetailsPatch(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Nutanix Machine Details patches for ControlPlane and Workers suite") +} diff --git a/pkg/handlers/nutanix/mutation/machinedetails/inject_worker_test.go b/pkg/handlers/nutanix/mutation/machinedetails/inject_worker_test.go new file mode 100644 index 000000000..9481bf960 --- /dev/null +++ b/pkg/handlers/nutanix/mutation/machinedetails/inject_worker_test.go @@ -0,0 +1,59 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package machinedetails + +import ( + . "github.com/onsi/ginkgo/v2" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" + + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/workerconfig" + nutanixclusterconfig "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/clusterconfig" +) + +var _ = Describe("Generate Nutanix Machine Details patches for Worker", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewWorkerPatch()).(mutation.GeneratePatches) + } + + testDefs := []capitest.PatchTestDef{ + { + Name: "unset variable", + }, + { + Name: "all fields set for workers", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + workerconfig.MetaVariableName, + variableWithAllFieldsSet, + nutanixclusterconfig.NutanixVariableName, + VariableName, + ), + capitest.VariableWithValue( + "builtin", + apiextensionsv1.JSON{ + Raw: []byte(`{"machineDeployment": {"class": "a-worker"}}`), + }, + ), + }, + RequestItem: request.NewWorkerNutanixMachineTemplateRequestItem(""), + ExpectedPatchMatchers: matchersForAllFieldsSet, + }, + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/nutanix/mutation/metapatch_handler_test.go b/pkg/handlers/nutanix/mutation/metapatch_handler_test.go index 0ef280fa5..822b4dae5 100644 --- a/pkg/handlers/nutanix/mutation/metapatch_handler_test.go +++ b/pkg/handlers/nutanix/mutation/metapatch_handler_test.go @@ -21,14 +21,6 @@ import ( kubernetesimagerepositorytests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/kubernetesimagerepository/tests" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/mirrors" globalimageregistrymirrortests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/mirrors/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/workerconfig" - nutanixclusterconfig "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/clusterconfig" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/mutation/controlplaneendpoint" - controlplaneendpointtests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/mutation/controlplaneendpoint/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/mutation/machinedetails" - machinedetailstests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/mutation/machinedetails/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/mutation/prismcentralendpoint" - prismcentralendpointtests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/mutation/prismcentralendpoint/tests" ) func metaPatchGeneratorFunc(mgr manager.Manager) func() mutation.GeneratePatches { @@ -37,50 +29,11 @@ func metaPatchGeneratorFunc(mgr manager.Manager) func() mutation.GeneratePatches } } -func workerPatchGeneratorFunc() func() mutation.GeneratePatches { - return func() mutation.GeneratePatches { - return MetaWorkerPatchHandler().(mutation.GeneratePatches) - } -} - func TestGeneratePatches(t *testing.T) { t.Parallel() mgr := testEnv.Manager - controlplaneendpointtests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - nutanixclusterconfig.NutanixVariableName, - controlplaneendpoint.VariableName, - ) - - prismcentralendpointtests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - nutanixclusterconfig.NutanixVariableName, - prismcentralendpoint.VariableName, - ) - - machinedetailstests.TestControlPlaneGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - clusterconfig.MetaControlPlaneConfigName, - nutanixclusterconfig.NutanixVariableName, - machinedetails.VariableName, - ) - - machinedetailstests.TestWorkerGeneratePatches( - t, - workerPatchGeneratorFunc(), - workerconfig.MetaVariableName, - nutanixclusterconfig.NutanixVariableName, - machinedetails.VariableName, - ) - auditpolicytests.TestGeneratePatches( t, metaPatchGeneratorFunc(mgr), diff --git a/pkg/handlers/nutanix/mutation/prismcentralendpoint/tests/generate_patches.go b/pkg/handlers/nutanix/mutation/prismcentralendpoint/inject_test.go similarity index 80% rename from pkg/handlers/nutanix/mutation/prismcentralendpoint/tests/generate_patches.go rename to pkg/handlers/nutanix/mutation/prismcentralendpoint/inject_test.go index 0b9003fc1..83d9f431e 100644 --- a/pkg/handlers/nutanix/mutation/prismcentralendpoint/tests/generate_patches.go +++ b/pkg/handlers/nutanix/mutation/prismcentralendpoint/inject_test.go @@ -1,11 +1,12 @@ // Copyright 2023 D2iQ, Inc. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package tests +package prismcentralendpoint import ( "testing" + . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" "k8s.io/utils/ptr" @@ -15,30 +16,33 @@ import ( "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" + nutanixclusterconfig "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/clusterconfig" ) // //nolint:lll // just a long string const testCertBundle = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVjekNDQTF1Z0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRUUZBRC4uQWtHQTFVRUJoTUNSMEl4CkV6QVJCZ05WQkFnVENsTnZiV1V0VTNSaGRHVXhGREFTQmdOVkJBb1RDMC4uMEVnVEhSa01UY3dOUVlEClZRUUxFeTVEYkdGemN5QXhJRkIxWW14cFl5QlFjbWx0WVhKNUlFTmxjbi4uWFJwYjI0Z1FYVjBhRzl5CmFYUjVNUlF3RWdZRFZRUURFd3RDWlhOMElFTkJJRXgwWkRBZUZ3MHdNRC4uVFV3TVRaYUZ3MHdNVEF5Ck1EUXhPVFV3TVRaYU1JR0hNUXN3Q1FZRFZRUUdFd0pIUWpFVE1CRUdBMS4uMjl0WlMxVGRHRjBaVEVVCk1CSUdBMVVFQ2hNTFFtVnpkQ0JEUVNCTWRHUXhOekExQmdOVkJBc1RMay4uREVnVUhWaWJHbGpJRkJ5CmFXMWhjbmtnUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvYjNKcGRIa3hGRC4uQU1UQzBKbGMzUWdRMEVnClRIUmtNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZy4uVHoybXI3U1ppQU1mUXl1CnZCak05T2lKalJhelhCWjFCalA1Q0UvV20vUnI1MDBQUksrTGg5eDVlSi4uL0FOQkUwc1RLMFpzREdNCmFrMm0xZzdvcnVJM2RZM1ZIcUl4RlR6MFRhMWQrTkFqd25MZTRuT2I3Ly4uazA1U2hoQnJKR0JLS3hiCjhuMTA0by81cDhIQXNaUGR6YkZNSXlOakp6Qk0ybzV5NUExM3dpTGl0RS4uZnlZa1F6YXhDdzBBd3psCmtWSGlJeUN1YUY0d2o1NzFwU3prdjZzdis0SURNYlQvWHBDbzhMNndUYS4uc2grZXRMRDZGdFRqWWJiCnJ2WjhSUU0xdGxLZG9NSGcycXhyYUFWKytITkJZbU5XczBkdUVkalViSi4uWEk5VHRuUzRvMUNrajdQCk9mbGppUUlEQVFBQm80SG5NSUhrTUIwR0ExVWREZ1FXQkJROHVyTUNSTC4uNUFrSXA5TkpISnc1VENCCnRBWURWUjBqQklHc01JR3BnQlE4dXJNQ1JMWVlNSFVLVTVBa0lwOU5KSC4uYVNCaWpDQmh6RUxNQWtHCkExVUVCaE1DUjBJeEV6QVJCZ05WQkFnVENsTnZiV1V0VTNSaGRHVXhGRC4uQW9UQzBKbGMzUWdRMEVnClRIUmtNVGN3TlFZRFZRUUxFeTVEYkdGemN5QXhJRkIxWW14cFl5QlFjbS4uRU5sY25ScFptbGpZWFJwCmIyNGdRWFYwYUc5eWFYUjVNUlF3RWdZRFZRUURFd3RDWlhOMElFTkJJRS4uREFNQmdOVkhSTUVCVEFECkFRSC9NQTBHQ1NxR1NJYjNEUUVCQkFVQUE0SUJBUUMxdVlCY3NTbmN3QS4uRENzUWVyNzcyQzJ1Y3BYCnhRVUUvQzBwV1dtNmdEa3dkNUQwRFNNREpScVYvd2VvWjR3QzZCNzNmNS4uYkxoR1lIYVhKZVNENktyClhjb093TGRTYUdtSllzbExLWkIzWklERXAwd1lUR2hndGViNkpGaVR0bi4uc2YyeGRyWWZQQ2lJQjdnCkJNQVY3R3pkYzRWc3BTNmxqckFoYmlpYXdkQmlRbFFtc0JlRno5SmtGNC4uYjNsOEJvR04rcU1hNTZZCkl0OHVuYTJnWTRsMk8vL29uODhyNUlXSmxtMUwwb0E4ZTRmUjJ5ckJIWC4uYWRzR2VGS2t5TnJ3R2kvCjd2UU1mWGRHc1JyWE5HUkduWCt2V0RaMy96V0kwam9EdENrTm5xRXBWbi4uSG9YCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=" -func TestGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ +func TestPrismCentralEndpointPatch(t *testing.T) { + gomega.RegisterFailHandler(Fail) + RunSpecs(t, "Nutanix Prism Central Endpoint mutator suite") +} + +var _ = Describe("Generate Nutanix Prism Central Endpoint patches", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewPatch()).(mutation.GeneratePatches) + } + + testDefs := []capitest.PatchTestDef{ + { Name: "unset variable", }, - capitest.PatchTestDef{ + { Name: "all required fields set", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.NutanixPrismCentralEndpointSpec{ Host: "prism-central.nutanix.com", Port: 9441, @@ -47,7 +51,8 @@ func TestGeneratePatches( Name: "credentials", }, }, - variablePath..., + nutanixclusterconfig.NutanixVariableName, + VariableName, ), }, RequestItem: request.NewNutanixClusterTemplateRequestItem(""), @@ -68,11 +73,11 @@ func TestGeneratePatches( }, }, }, - capitest.PatchTestDef{ + { Name: "additional trust bundle is set", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.NutanixPrismCentralEndpointSpec{ Host: "prism-central.nutanix.com", Port: 9441, @@ -82,7 +87,8 @@ func TestGeneratePatches( }, AdditionalTrustBundle: ptr.To(testCertBundle), }, - variablePath..., + nutanixclusterconfig.NutanixVariableName, + VariableName, ), }, RequestItem: request.NewNutanixClusterTemplateRequestItem(""), @@ -104,5 +110,17 @@ func TestGeneratePatches( }, }, }, - ) -} + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +})