sigs.k8s.io/prow@v0.0.0-20240503223140-c5e374dc7eb1/pkg/genyaml/populate_struct_test.go (about)

     1  /*
     2  Copyright 2020 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 genyaml
    18  
    19  import (
    20  	"testing"
    21  )
    22  
    23  func TestPopulateStructHandlesPointerFields(t *testing.T) {
    24  	s := struct {
    25  		Field *struct {
    26  			NestedField *int
    27  		}
    28  	}{}
    29  
    30  	PopulateStruct(&s)
    31  	if s.Field == nil {
    32  		t.Fatalf("Pointer field in struct didn't get set, struct: %+v", s)
    33  	}
    34  	if s.Field.NestedField == nil {
    35  		t.Fatalf("Nested pointer field in struct didn't get set, struct: %+v", s)
    36  	}
    37  }
    38  
    39  func TestPopulateStructHandlesSlicesOfLiterals(t *testing.T) {
    40  	s := struct {
    41  		Field []struct {
    42  			NestedField *int
    43  		}
    44  	}{}
    45  
    46  	PopulateStruct(&s)
    47  	if n := len(s.Field); n != 1 {
    48  		t.Fatalf("Slice didn't get populated, struct: %+v", s)
    49  	}
    50  
    51  	if s.Field[0].NestedField == nil {
    52  		t.Fatalf("Slice element field didn't get populated, struct: %+v", s)
    53  	}
    54  }
    55  
    56  func TestPopulateStructHandlesSliceOfPointers(t *testing.T) {
    57  	s := struct {
    58  		Field []*struct {
    59  			NestedField *int
    60  		}
    61  	}{}
    62  
    63  	PopulateStruct(&s)
    64  	if n := len(s.Field); n != 1 {
    65  		t.Fatalf("Slice didn't get populated, struct: %+v", s)
    66  	}
    67  	if s.Field[0] == nil {
    68  		t.Fatalf("Slice element didn't get populated, struct: %+v", s)
    69  	}
    70  
    71  	if s.Field[0].NestedField == nil {
    72  		t.Fatalf("Slice element field didn't get populated, struct: %+v", s)
    73  	}
    74  }
    75  
    76  func TestPopulateStructHandlesMaps(t *testing.T) {
    77  	s := struct {
    78  		Field map[string]struct {
    79  			NestedField *int
    80  		}
    81  	}{}
    82  
    83  	PopulateStruct(&s)
    84  	if n := len(s.Field); n != 1 {
    85  		t.Fatalf("Map didn't get populated, struct: %+v", s)
    86  	}
    87  
    88  	for _, v := range s.Field {
    89  		if v.NestedField == nil {
    90  			t.Fatalf("Pointer field in map element didn't get populated, struct: %+v", s)
    91  		}
    92  	}
    93  }
    94  
    95  func TestPopulateStructHandlesMapsWithPointerValues(t *testing.T) {
    96  	s := struct {
    97  		Field map[string]*struct {
    98  			NestedField *int
    99  		}
   100  	}{}
   101  
   102  	PopulateStruct(&s)
   103  	if n := len(s.Field); n != 1 {
   104  		t.Fatalf("Map didn't get populated, struct: %+v", s)
   105  	}
   106  
   107  	for _, v := range s.Field {
   108  		if v == nil {
   109  			t.Fatalf("Map value is a nilpointer, struct: %+v", s)
   110  		}
   111  		if v.NestedField == nil {
   112  			t.Fatalf("Pointer field in map element didn't get populated, struct: %+v", s)
   113  		}
   114  	}
   115  }
   116  
   117  func TestPopulateStructHandlesMapsWithPointerKeys(t *testing.T) {
   118  	s := struct {
   119  		Field map[*string]struct {
   120  			NestedField *int
   121  		}
   122  	}{}
   123  
   124  	PopulateStruct(&s)
   125  	if n := len(s.Field); n != 1 {
   126  		t.Fatalf("Map didn't get populated, struct: %+v", s)
   127  	}
   128  
   129  	for k, v := range s.Field {
   130  		if k == nil {
   131  			t.Fatalf("Map key is a nilpointer, struct: %+v", s)
   132  		}
   133  		if v.NestedField == nil {
   134  			t.Fatalf("Pointer field in map element didn't get populated, struct: %+v", s)
   135  		}
   136  	}
   137  }
   138  
   139  // this is needed because genyaml uses a custom json unmarshaler that omits empty structs
   140  // even if they are not pointers. If we don't do this, structs that only have string fields
   141  // end up being omitted.
   142  // TODO: Is there a necessity for genyaml to have this custom unmarshaler?
   143  func TestPopulateStructSetsStrings(t *testing.T) {
   144  	s := struct {
   145  		String string
   146  		Field  struct {
   147  			String string
   148  		}
   149  	}{}
   150  
   151  	PopulateStruct(&s)
   152  	if s.String == "" {
   153  		t.Errorf("String field didn't get set, struct: %+v", s)
   154  	}
   155  	if s.Field.String == "" {
   156  		t.Errorf("Nested string field didn't get set, struct: %+v", s)
   157  	}
   158  }
   159  
   160  func TestPopulateStructBool(t *testing.T) {
   161  	s := struct {
   162  		Bool   bool   `json:"bool,omitempty"`
   163  		String string `json:"string,omitempty"`
   164  	}{}
   165  
   166  	PopulateStruct(&s)
   167  	if !s.Bool {
   168  		t.Fatalf("Bool field didn't get set, struct: %+v", s)
   169  	}
   170  }
   171  
   172  func TestPopulateStructHandlesUnexportedFields(_ *testing.T) {
   173  	s := struct {
   174  		unexported *struct {
   175  			justAsUnexported *int
   176  		}
   177  	}{}
   178  
   179  	PopulateStruct(&s)
   180  	// This test indicates success by not panicking, so nothing further to check
   181  }