github.com/alex123012/deckhouse-controller-tools@v0.0.0-20230510090815-d594daf1af8c/pkg/crd/schema_test.go (about)

     1  /*
     2  Copyright 2019 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package crd
    18  
    19  import (
    20  	"go/ast"
    21  	"strings"
    22  	"testing"
    23  
    24  	"github.com/onsi/gomega"
    25  	"golang.org/x/tools/go/packages"
    26  	pkgstest "golang.org/x/tools/go/packages/packagestest"
    27  	apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
    28  	testloader "sigs.k8s.io/controller-tools/pkg/loader/testutils"
    29  	"sigs.k8s.io/controller-tools/pkg/markers"
    30  )
    31  
    32  func transform(t *testing.T, expr string) *apiext.JSONSchemaProps {
    33  	// this is *very* hacky but I haven’t found a simple way
    34  	// to get an ast.Expr with all the associated metadata required
    35  	// to run typeToSchema upon it:
    36  
    37  	moduleName := "sigs.k8s.io/controller-tools/pkg/crd"
    38  	modules := []pkgstest.Module{
    39  		{
    40  			Name: moduleName,
    41  			Files: map[string]interface{}{
    42  				"test.go": `
    43  				package crd 
    44  				type Test ` + expr,
    45  			},
    46  		},
    47  	}
    48  
    49  	pkgs, exported, err := testloader.LoadFakeRoots(pkgstest.Modules, modules, moduleName)
    50  	if exported != nil {
    51  		t.Cleanup(exported.Cleanup)
    52  	}
    53  
    54  	if err != nil {
    55  		t.Fatalf("unable to load fake package: %s", err)
    56  	}
    57  
    58  	if len(pkgs) != 1 {
    59  		t.Fatal("expected to parse only one package")
    60  	}
    61  
    62  	pkg := pkgs[0]
    63  	pkg.NeedTypesInfo()
    64  	failIfErrors(t, pkg.Errors)
    65  
    66  	schemaContext := newSchemaContext(pkg, nil, true, false).ForInfo(&markers.TypeInfo{})
    67  	// yick: grab the only type definition
    68  	definedType := pkg.Syntax[0].Decls[0].(*ast.GenDecl).Specs[0].(*ast.TypeSpec).Type
    69  	result := typeToSchema(schemaContext, definedType)
    70  	failIfErrors(t, pkg.Errors)
    71  	return result
    72  }
    73  
    74  func failIfErrors(t *testing.T, errs []packages.Error) {
    75  	if len(errs) > 0 {
    76  		var msgs []string
    77  		for _, e := range errs {
    78  			msgs = append(msgs, e.Msg)
    79  		}
    80  
    81  		t.Fatalf("error loading fake package: %s", strings.Join(msgs, "; "))
    82  	}
    83  }
    84  
    85  var arrayOfNumbersSchema *apiext.JSONSchemaProps = &apiext.JSONSchemaProps{
    86  	Type: "array",
    87  	Items: &apiext.JSONSchemaPropsOrArray{
    88  		Schema: &apiext.JSONSchemaProps{
    89  			Type: "number",
    90  		},
    91  	},
    92  }
    93  
    94  func Test_Schema_ArrayOfFloat32(t *testing.T) {
    95  	g := gomega.NewWithT(t)
    96  
    97  	output := transform(t, "[]float32")
    98  	g.Expect(output).To(gomega.Equal(arrayOfNumbersSchema))
    99  }
   100  
   101  func Test_Schema_MapOfStringToArrayOfFloat32(t *testing.T) {
   102  	g := gomega.NewWithT(t)
   103  
   104  	output := transform(t, "map[string][]float32")
   105  	g.Expect(output).To(gomega.Equal(&apiext.JSONSchemaProps{
   106  		Type: "object",
   107  		AdditionalProperties: &apiext.JSONSchemaPropsOrBool{
   108  			Allows: true,
   109  			Schema: arrayOfNumbersSchema,
   110  		},
   111  	}))
   112  }