github.com/crossplane/upjet@v1.3.0/pkg/types/reference_test.go (about)

     1  // SPDX-FileCopyrightText: 2023 The Crossplane Authors <https://crossplane.io>
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  
     5  package types
     6  
     7  import (
     8  	"go/token"
     9  	"go/types"
    10  	"testing"
    11  
    12  	"github.com/google/go-cmp/cmp"
    13  	twtypes "github.com/muvaf/typewriter/pkg/types"
    14  
    15  	"github.com/crossplane/upjet/pkg/config"
    16  	"github.com/crossplane/upjet/pkg/types/name"
    17  )
    18  
    19  func TestBuilder_generateReferenceFields(t *testing.T) {
    20  	tp := types.NewPackage("github.com/crossplane/upjet/pkg/types", "tjtypes")
    21  
    22  	type args struct {
    23  		t *types.TypeName
    24  		f *Field
    25  	}
    26  	type want struct {
    27  		outFields   []*types.Var
    28  		outTags     []string
    29  		outComments twtypes.Comments
    30  	}
    31  	cases := map[string]struct {
    32  		args
    33  		want
    34  	}{
    35  		"OnlyRefType": {
    36  			args: args{
    37  				t: types.NewTypeName(token.NoPos, tp, "Params", types.Universe.Lookup("string").Type()),
    38  				f: &Field{
    39  					Name: name.NewFromCamel("TestField"),
    40  					Reference: &config.Reference{
    41  						Type: "testObject",
    42  					},
    43  					FieldType: types.Universe.Lookup("string").Type(),
    44  				},
    45  			}, want: want{
    46  				outFields: []*types.Var{
    47  					types.NewField(token.NoPos, tp, "TestFieldRef", types.NewPointer(typeReferenceField), false),
    48  					types.NewField(token.NoPos, tp, "TestFieldSelector", types.NewPointer(typeSelectorField), false),
    49  				},
    50  				outTags: []string{
    51  					`json:"testFieldRef,omitempty" tf:"-"`,
    52  					`json:"testFieldSelector,omitempty" tf:"-"`,
    53  				},
    54  				outComments: twtypes.Comments{
    55  					"github.com/crossplane/upjet/pkg/types.Params:TestFieldRef":      "// Reference to a testObject to populate testField.\n// +kubebuilder:validation:Optional\n",
    56  					"github.com/crossplane/upjet/pkg/types.Params:TestFieldSelector": "// Selector for a testObject to populate testField.\n// +kubebuilder:validation:Optional\n",
    57  				},
    58  			},
    59  		},
    60  		"OnlyRefTypeSlice": {
    61  			args: args{
    62  				t: types.NewTypeName(token.NoPos, tp, "Params", types.Universe.Lookup("string").Type()),
    63  				f: &Field{
    64  					Name: name.NewFromCamel("TestField"),
    65  					Reference: &config.Reference{
    66  						Type: "testObject",
    67  					},
    68  					FieldType: types.NewSlice(types.Universe.Lookup("string").Type()),
    69  				},
    70  			}, want: want{
    71  				outFields: []*types.Var{
    72  					types.NewField(token.NoPos, tp, "TestFieldRefs", types.NewSlice(typeReferenceField), false),
    73  					types.NewField(token.NoPos, tp, "TestFieldSelector", types.NewPointer(typeSelectorField), false),
    74  				},
    75  				outTags: []string{
    76  					`json:"testFieldRefs,omitempty" tf:"-"`,
    77  					`json:"testFieldSelector,omitempty" tf:"-"`,
    78  				},
    79  				outComments: twtypes.Comments{
    80  					"github.com/crossplane/upjet/pkg/types.Params:TestFieldRefs":     "// References to testObject to populate testField.\n// +kubebuilder:validation:Optional\n",
    81  					"github.com/crossplane/upjet/pkg/types.Params:TestFieldSelector": "// Selector for a list of testObject to populate testField.\n// +kubebuilder:validation:Optional\n",
    82  				},
    83  			},
    84  		},
    85  		"WithCustomFieldName": {
    86  			args: args{
    87  				t: types.NewTypeName(token.NoPos, tp, "Params", types.Universe.Lookup("string").Type()),
    88  				f: &Field{
    89  					Name: name.NewFromCamel("TestField"),
    90  					Reference: &config.Reference{
    91  						Type:         "TestObject",
    92  						RefFieldName: "CustomRef",
    93  					},
    94  					FieldType: types.Universe.Lookup("string").Type(),
    95  				},
    96  			}, want: want{
    97  				outFields: []*types.Var{
    98  					types.NewField(token.NoPos, tp, "CustomRef", types.NewPointer(typeReferenceField), false),
    99  					types.NewField(token.NoPos, tp, "TestFieldSelector", types.NewPointer(typeSelectorField), false),
   100  				},
   101  				outTags: []string{
   102  					`json:"customRef,omitempty" tf:"-"`,
   103  					`json:"testFieldSelector,omitempty" tf:"-"`,
   104  				},
   105  				outComments: twtypes.Comments{
   106  					"github.com/crossplane/upjet/pkg/types.Params:CustomRef":         "// Reference to a TestObject to populate testField.\n// +kubebuilder:validation:Optional\n",
   107  					"github.com/crossplane/upjet/pkg/types.Params:TestFieldSelector": "// Selector for a TestObject to populate testField.\n// +kubebuilder:validation:Optional\n",
   108  				},
   109  			},
   110  		},
   111  		"WithCustomSelectorName": {
   112  			args: args{
   113  				t: types.NewTypeName(token.NoPos, tp, "Params", types.Universe.Lookup("string").Type()),
   114  				f: &Field{
   115  					Name: name.NewFromCamel("TestField"),
   116  					Reference: &config.Reference{
   117  						Type:              "TestObject",
   118  						SelectorFieldName: "CustomSelector",
   119  					},
   120  					FieldType: types.Universe.Lookup("string").Type(),
   121  				},
   122  			}, want: want{
   123  				outFields: []*types.Var{
   124  					types.NewField(token.NoPos, tp, "TestFieldRef", types.NewPointer(typeReferenceField), false),
   125  					types.NewField(token.NoPos, tp, "CustomSelector", types.NewPointer(typeSelectorField), false),
   126  				},
   127  				outTags: []string{
   128  					`json:"testFieldRef,omitempty" tf:"-"`,
   129  					`json:"customSelector,omitempty" tf:"-"`,
   130  				},
   131  				outComments: twtypes.Comments{
   132  					"github.com/crossplane/upjet/pkg/types.Params:TestFieldRef":   "// Reference to a TestObject to populate testField.\n// +kubebuilder:validation:Optional\n",
   133  					"github.com/crossplane/upjet/pkg/types.Params:CustomSelector": "// Selector for a TestObject to populate testField.\n// +kubebuilder:validation:Optional\n",
   134  				},
   135  			},
   136  		},
   137  		"ReferenceToAnotherPackage": {
   138  			args: args{
   139  				t: types.NewTypeName(token.NoPos, tp, "Params", types.Universe.Lookup("string").Type()),
   140  				f: &Field{
   141  					Name: name.NewFromCamel("TestField"),
   142  					Reference: &config.Reference{
   143  						Type: "github.com/upbound/official-providers/provider-aws/apis/somepackage/v1beta1.TestObject",
   144  					},
   145  					FieldType: types.Universe.Lookup("string").Type(),
   146  				},
   147  			}, want: want{
   148  				outFields: []*types.Var{
   149  					types.NewField(token.NoPos, tp, "TestFieldRef", types.NewPointer(typeReferenceField), false),
   150  					types.NewField(token.NoPos, tp, "TestFieldSelector", types.NewPointer(typeSelectorField), false),
   151  				},
   152  				outTags: []string{
   153  					`json:"testFieldRef,omitempty" tf:"-"`,
   154  					`json:"testFieldSelector,omitempty" tf:"-"`,
   155  				},
   156  				outComments: twtypes.Comments{
   157  					"github.com/crossplane/upjet/pkg/types.Params:TestFieldRef":      "// Reference to a TestObject in somepackage to populate testField.\n// +kubebuilder:validation:Optional\n",
   158  					"github.com/crossplane/upjet/pkg/types.Params:TestFieldSelector": "// Selector for a TestObject in somepackage to populate testField.\n// +kubebuilder:validation:Optional\n",
   159  				},
   160  			},
   161  		},
   162  	}
   163  	for name, tc := range cases {
   164  		t.Run(name, func(t *testing.T) {
   165  			g := &Builder{
   166  				comments: twtypes.Comments{},
   167  			}
   168  			gotFields, gotTags := g.generateReferenceFields(tc.args.t, tc.args.f)
   169  			if diff := cmp.Diff(tc.want.outFields, gotFields, cmp.Comparer(func(a, b *types.Var) bool {
   170  				return a.String() == b.String()
   171  			})); diff != "" {
   172  				t.Errorf("generateReferenceFields(): fields: +got, -want: %s", diff)
   173  			}
   174  			if diff := cmp.Diff(tc.want.outTags, gotTags); diff != "" {
   175  				t.Errorf("generateReferenceFields(): tags: +got, -want: %s", diff)
   176  			}
   177  			if diff := cmp.Diff(tc.want.outComments, g.comments); diff != "" {
   178  				t.Errorf("generateReferenceFields(): comments: +got, -want: %s", diff)
   179  			}
   180  		})
   181  	}
   182  }