github.com/giantswarm/apiextensions/v2@v2.6.2/pkg/apis/release/v1alpha1/deep_copy_test.go (about) 1 package v1alpha1 2 3 import ( 4 "encoding/json" 5 "reflect" 6 "testing" 7 "time" 8 9 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 11 "github.com/google/go-cmp/cmp" 12 ) 13 14 func Test_DeepCopyDate_MarshalJSON(t *testing.T) { 15 testCases := []struct { 16 name string 17 inputDate string 18 expectedJSON string 19 errorMatcher func(err error) bool 20 }{ 21 { 22 name: "case 0: valid date", 23 inputDate: "2019-04-05T00:00:00Z", 24 expectedJSON: `{"testDate":"2019-04-05"}`, 25 errorMatcher: nil, 26 }, 27 { 28 name: "case 1: valid date, non-zeroed hour", 29 inputDate: "2019-04-05T12:05:17Z", 30 expectedJSON: `{"testDate":"2019-04-05"}`, 31 errorMatcher: nil, 32 }, 33 } 34 35 for _, tc := range testCases { 36 t.Run(tc.name, func(t *testing.T) { 37 date, err := time.Parse(time.RFC3339, tc.inputDate) 38 if !reflect.DeepEqual(nil, err) { 39 t.Fatalf("\n\n%s\n", cmp.Diff(nil, err)) 40 } 41 42 vPointer := struct { 43 TestDate *DeepCopyDate `json:"testDate"` 44 }{ 45 TestDate: &DeepCopyDate{ 46 Time: metav1.Time{Time: date}, 47 }, 48 } 49 50 vValue := struct { 51 TestDate DeepCopyDate `json:"testDate"` 52 }{ 53 TestDate: DeepCopyDate{ 54 Time: metav1.Time{Time: date}, 55 }, 56 } 57 58 bytesPointer, err := json.Marshal(vPointer) 59 60 switch { 61 case err == nil && tc.errorMatcher == nil: 62 // correct; carry on 63 case err != nil && tc.errorMatcher == nil: 64 t.Fatalf("error == %v, want nil", err) 65 case err == nil && tc.errorMatcher != nil: 66 t.Fatalf("error == nil, want non-nil") 67 case !tc.errorMatcher(err): 68 t.Fatalf("error == %v, want matching", err) 69 } 70 71 bytesValue, err := json.Marshal(vValue) 72 73 switch { 74 case err == nil && tc.errorMatcher == nil: 75 // correct; carry on 76 case err != nil && tc.errorMatcher == nil: 77 t.Fatalf("error == %v, want nil", err) 78 case err == nil && tc.errorMatcher != nil: 79 t.Fatalf("error == nil, want non-nil") 80 case !tc.errorMatcher(err): 81 t.Fatalf("error == %v, want matching", err) 82 } 83 84 if tc.errorMatcher != nil { 85 return 86 } 87 88 if !reflect.DeepEqual(string(bytesPointer), tc.expectedJSON) { 89 t.Fatalf("\n\n%s\n", cmp.Diff(string(bytesPointer), tc.expectedJSON)) 90 } 91 92 if !reflect.DeepEqual(string(bytesValue), tc.expectedJSON) { 93 t.Fatalf("\n\n%s\n", cmp.Diff(string(bytesValue), tc.expectedJSON)) 94 } 95 }) 96 } 97 } 98 99 func Test_DeepCopyDate_UnmarshalJSON(t *testing.T) { 100 testCases := []struct { 101 name string 102 inputJSON string 103 expectedNil bool 104 expectedDay int 105 expectedMonth time.Month 106 expectedYear int 107 errorMatcher func(err error) bool 108 }{ 109 { 110 name: "case 0: valid date", 111 inputJSON: `{"testDate":"2019-02-08"}`, 112 expectedNil: false, 113 expectedDay: 8, 114 expectedMonth: 2, 115 expectedYear: 2019, 116 errorMatcher: nil, 117 }, 118 { 119 name: "case 1: malformed date", 120 inputJSON: `{"testDate":"2019-02-08T12:04:00"}`, 121 errorMatcher: func(err error) bool { return err != nil }, 122 }, 123 { 124 name: "case 2: null", 125 inputJSON: `{"testDate":null}`, 126 expectedNil: true, 127 expectedDay: 1, 128 expectedMonth: 1, 129 expectedYear: 1, 130 errorMatcher: nil, 131 }, 132 { 133 name: "case 3: wrong type", 134 inputJSON: `{"testDate":5}`, 135 errorMatcher: func(err error) bool { return err != nil }, 136 }, 137 } 138 139 for _, tc := range testCases { 140 t.Run(tc.name, func(t *testing.T) { 141 type JSONObjectPointer struct { 142 TestDate *DeepCopyDate `json:"testDate"` 143 } 144 145 type JSONObjectValue struct { 146 TestDate DeepCopyDate `json:"testDate"` 147 } 148 149 var jsonObjectPointer = JSONObjectPointer{TestDate: &DeepCopyDate{}} 150 err := json.Unmarshal([]byte(tc.inputJSON), &jsonObjectPointer) 151 152 switch { 153 case err == nil && tc.errorMatcher == nil: 154 // correct; carry on 155 case err != nil && tc.errorMatcher == nil: 156 t.Fatalf("error == %v, want nil", err) 157 case err == nil && tc.errorMatcher != nil: 158 t.Fatalf("error == nil, want non-nil") 159 case !tc.errorMatcher(err): 160 t.Fatalf("error == %v, want matching", err) 161 } 162 163 var jsonObjectValue JSONObjectValue 164 err = json.Unmarshal([]byte(tc.inputJSON), &jsonObjectValue) 165 166 switch { 167 case err == nil && tc.errorMatcher == nil: 168 // correct; carry on 169 case err != nil && tc.errorMatcher == nil: 170 t.Fatalf("error == %v, want nil", err) 171 case err == nil && tc.errorMatcher != nil: 172 t.Fatalf("error == nil, want non-nil") 173 case !tc.errorMatcher(err): 174 t.Fatalf("error == %v, want matching", err) 175 } 176 177 if tc.errorMatcher != nil { 178 return 179 } 180 181 if tc.expectedNil { 182 // We need a nil of the same type. Otherwise won't work with cmp. 183 var nilDeepCopyDate *DeepCopyDate 184 if !reflect.DeepEqual(jsonObjectPointer.TestDate, nilDeepCopyDate) { 185 t.Errorf("\n\n%s\n", cmp.Diff(jsonObjectPointer.TestDate, nilDeepCopyDate)) 186 } 187 } else { 188 if !reflect.DeepEqual(jsonObjectPointer.TestDate.Day(), tc.expectedDay) { 189 t.Errorf("\n\n%s\n", cmp.Diff(jsonObjectPointer.TestDate.Day(), tc.expectedDay)) 190 } 191 if !reflect.DeepEqual(jsonObjectPointer.TestDate.Month(), tc.expectedMonth) { 192 t.Errorf("\n\n%s\n", cmp.Diff(jsonObjectPointer.TestDate.Month(), tc.expectedMonth)) 193 } 194 if !reflect.DeepEqual(jsonObjectPointer.TestDate.Year(), tc.expectedYear) { 195 t.Errorf("\n\n%s\n", cmp.Diff(jsonObjectPointer.TestDate.Year(), tc.expectedYear)) 196 } 197 } 198 199 if !reflect.DeepEqual(jsonObjectValue.TestDate.Day(), tc.expectedDay) { 200 t.Errorf("\n\n%s\n", cmp.Diff(jsonObjectValue.TestDate.Day(), tc.expectedDay)) 201 } 202 if !reflect.DeepEqual(jsonObjectValue.TestDate.Month(), tc.expectedMonth) { 203 t.Errorf("\n\n%s\n", cmp.Diff(jsonObjectValue.TestDate.Month(), tc.expectedMonth)) 204 } 205 if !reflect.DeepEqual(jsonObjectValue.TestDate.Year(), tc.expectedYear) { 206 t.Errorf("\n\n%s\n", cmp.Diff(jsonObjectValue.TestDate.Year(), tc.expectedYear)) 207 } 208 }) 209 } 210 }