knative.dev/pkg@v0.0.0-20260602142205-ac97e43f6622/apis/duck/unstructured_test.go (about) 1 /* 2 Copyright 2018 The Knative 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 duck 18 19 import ( 20 "encoding/json" 21 "errors" 22 "testing" 23 24 "github.com/google/go-cmp/cmp" 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 27 . "knative.dev/pkg/testing" 28 ) 29 30 func TestFromUnstructuredFooable(t *testing.T) { 31 tcs := []struct { 32 name string 33 in json.Marshaler 34 want FooStatus 35 wantError error 36 }{{ 37 name: "Works with valid status", 38 in: &unstructured.Unstructured{ 39 Object: map[string]interface{}{ 40 "apiVersion": "test", 41 "kind": "test_kind", 42 "name": "test_name", 43 "status": map[string]interface{}{ 44 "extra": "fields", 45 "fooable": map[string]interface{}{ 46 "field1": "foo", 47 "field2": "bar", 48 }, 49 }, 50 }, 51 }, 52 want: FooStatus{&Fooable{ 53 Field1: "foo", 54 Field2: "bar", 55 }}, 56 wantError: nil, 57 }, { 58 name: "does not work with missing fooable status", 59 in: &unstructured.Unstructured{ 60 Object: map[string]interface{}{ 61 "apiVersion": "test", 62 "kind": "test_kind", 63 "name": "test_name", 64 "status": map[string]interface{}{ 65 "extra": "fields", 66 }, 67 }, 68 }, 69 want: FooStatus{}, 70 wantError: nil, 71 }, { 72 name: "empty unstructured", 73 in: &unstructured.Unstructured{}, 74 want: FooStatus{}, 75 wantError: nil, 76 }} 77 78 for _, tc := range tcs { 79 t.Run(tc.name, func(t *testing.T) { 80 raw, err := json.Marshal(tc.in) 81 if err != nil { 82 t.Fatal("failed to marshal:", err) 83 } 84 85 t.Log("Marshalled:", string(raw)) 86 87 got := Foo{} 88 if err := FromUnstructured(tc.in, &got); !errors.Is(err, tc.wantError) { 89 t.Fatal("FromUnstructured() =", err) 90 } 91 92 if !cmp.Equal(tc.want, got.Status) { 93 t.Error("ToUnstructured (-want, +got) =", cmp.Diff(tc.want, got.Status)) 94 } 95 }) 96 } 97 } 98 99 func TestToUnstructured(t *testing.T) { 100 tests := []struct { 101 name string 102 in OneOfOurs 103 want *unstructured.Unstructured 104 wantError error 105 }{{ 106 name: "missing TypeMeta", 107 in: &Resource{ 108 ObjectMeta: metav1.ObjectMeta{ 109 Name: "blah", 110 }, 111 }, 112 want: &unstructured.Unstructured{ 113 Object: map[string]interface{}{ 114 "apiVersion": "pkg.knative.dev/v2", 115 "kind": "Resource", 116 "metadata": map[string]interface{}{ 117 "name": "blah", 118 }, 119 "spec": map[string]interface{}{}, 120 }, 121 }, 122 }, { 123 name: "with TypeMeta", 124 in: &Resource{ 125 TypeMeta: metav1.TypeMeta{ 126 APIVersion: "apps/v1", 127 Kind: "Deployment", 128 }, 129 ObjectMeta: metav1.ObjectMeta{ 130 Name: "blah", 131 }, 132 }, 133 want: &unstructured.Unstructured{ 134 Object: map[string]interface{}{ 135 "apiVersion": "apps/v1", 136 "kind": "Deployment", 137 "metadata": map[string]interface{}{ 138 "name": "blah", 139 }, 140 "spec": map[string]interface{}{}, 141 }, 142 }, 143 }} 144 145 for _, tc := range tests { 146 t.Run(tc.name, func(t *testing.T) { 147 got, err := ToUnstructured(tc.in) 148 if !errors.Is(err, tc.wantError) { 149 t.Fatal("ToUnstructured() =", err) 150 } 151 152 if !cmp.Equal(tc.want, got) { 153 t.Error("ToUnstructured (-want, +got) =", cmp.Diff(tc.want, got)) 154 } 155 }) 156 } 157 }