github.com/openebs/api@v1.12.0/pkg/util/unstructured_test.go (about) 1 /* 2 Copyright 2020 The OpenEBS 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 util 18 19 import ( 20 "reflect" 21 "testing" 22 ) 23 24 func TestMergeMapOfObjects(t *testing.T) { 25 tests := map[string]struct { 26 destMap map[string]interface{} 27 srcMap map[string]interface{} 28 isMerge bool 29 expectedKeys []string 30 }{ 31 "merge map of objects - +ve test case - dest & src maps are exclusive": { 32 destMap: map[string]interface{}{ 33 "k1": "v1", 34 }, 35 srcMap: map[string]interface{}{ 36 "k2": "v2", 37 }, 38 isMerge: true, 39 expectedKeys: []string{"k1", "k2"}, 40 }, 41 "merge map of objects - +ve test case - dest & src maps are same": { 42 destMap: map[string]interface{}{ 43 "k1": "v1", 44 }, 45 srcMap: map[string]interface{}{ 46 "k1": "v2", 47 }, 48 isMerge: true, 49 expectedKeys: []string{"k1"}, 50 }, 51 "merge map of objects - +ve test case - some elements of dest & src maps are common": { 52 destMap: map[string]interface{}{ 53 "k1": "v1", 54 }, 55 srcMap: map[string]interface{}{ 56 "k1": "v1.1", 57 "k2": "v2", 58 }, 59 isMerge: true, 60 expectedKeys: []string{"k1", "k2"}, 61 }, 62 "merge map of objects - +ve test case - dest map is empty": { 63 destMap: map[string]interface{}{}, 64 srcMap: map[string]interface{}{ 65 "k2": "v2", 66 }, 67 isMerge: true, 68 expectedKeys: []string{"k2"}, 69 }, 70 "merge map of objects - +ve test case - dest map is nil": { 71 destMap: nil, 72 srcMap: map[string]interface{}{ 73 "k2": "v2", 74 }, 75 isMerge: false, 76 }, 77 "merge map of objects - +ve test case - src map is empty": { 78 destMap: map[string]interface{}{ 79 "k1": "v1", 80 }, 81 srcMap: nil, 82 isMerge: true, 83 expectedKeys: []string{"k1"}, 84 }, 85 "merge map of objects - +ve test case - src map is nil": { 86 destMap: map[string]interface{}{ 87 "k1": "v1", 88 }, 89 srcMap: nil, 90 isMerge: true, 91 expectedKeys: []string{"k1"}, 92 }, 93 } 94 95 for name, mock := range tests { 96 t.Run(name, func(t *testing.T) { 97 ok := MergeMapOfObjects(mock.destMap, mock.srcMap) 98 99 if mock.isMerge != ok { 100 t.Fatalf("failed to test merge map of objects: expected merge '%t': actual merge '%t'", mock.isMerge, ok) 101 } 102 103 if mock.isMerge && !ContainKeys(mock.destMap, mock.expectedKeys) { 104 t.Fatalf("failed to test merge map of objects: expected keys '%s': actual 'missing key(s)': dest after merge '%#v'", mock.expectedKeys, mock.destMap) 105 } 106 107 if mock.isMerge && len(mock.destMap) != len(mock.expectedKeys) { 108 t.Fatalf("failed to test merge map of objects: expected key count '%d': actual key count '%d'", len(mock.expectedKeys), len(mock.destMap)) 109 } 110 }) 111 } 112 } 113 114 func TestSetNestedField(t *testing.T) { 115 tests := map[string]struct { 116 obj map[string]interface{} 117 value interface{} 118 fields []string 119 }{ 120 "Negative test - set nested key value pair to empty original": { 121 // this is empty 122 obj: map[string]interface{}{}, 123 // value to be set in above obj 124 value: "hello there", 125 // above value will be set at path obj[k1][k1.1] 126 fields: []string{"k1", "k1.1"}, 127 }, 128 "Negative test - set nested key with complex value to empty original": { 129 // this is empty 130 obj: map[string]interface{}{}, 131 // value to be set in above obj 132 value: map[string]interface{}{ 133 "k1.1.1": map[string]interface{}{ 134 "k1.1.1.1": "hi there", 135 }, 136 }, 137 // above value will be set at path obj[k1][k1.1] 138 fields: []string{"k1", "k1.1"}, 139 }, 140 "Positive test - set a new value at new nested key": { 141 obj: map[string]interface{}{ 142 "k1": "v1", 143 "k2": map[string]string{ 144 "k2.1": "v2.1", 145 "k2.2": "v2.2", 146 }, 147 }, 148 // value to be set in above obj 149 value: "v2.3", 150 // above value will be set at path obj[k2][k2.3] 151 fields: []string{"k2", "k2.3"}, 152 }, 153 "Positive test - override an existing value of a nested key": { 154 obj: map[string]interface{}{ 155 "k1": "v1", 156 "k2": map[string]string{ 157 "k2.1": "v2.1", 158 "k2.2": "v2.2", 159 }, 160 }, 161 // value to be set in above obj 162 value: "v2.2'", 163 // above value will be set at path obj[k2][k2.2] 164 fields: []string{"k2", "k2.2"}, 165 }, 166 "Positive test - override an existing nested value of a parent key": { 167 obj: map[string]interface{}{ 168 "k1": "v1", 169 "k2": map[string]string{ 170 "k2.1": "v2.1", 171 "k2.2": "v2.2", 172 }, 173 }, 174 // value to be set in above obj 175 value: "hello", 176 // above value will be set against the obj[k2] 177 fields: []string{"k2"}, 178 }, 179 "Positive test - add a new parent key value pair": { 180 obj: map[string]interface{}{ 181 "k1": "v1", 182 "k2": map[string]string{ 183 "k2.1": "v2.1", 184 "k2.2": "v2.2", 185 }, 186 }, 187 // value to be set in above obj 188 value: "hello", 189 // above value will be set against the obj[k3] 190 fields: []string{"k3"}, 191 }, 192 "Negative test - no changes to original obj due to empty fields": { 193 obj: map[string]interface{}{ 194 "k1": "v1", 195 "k2": map[string]string{ 196 "k2.1": "v2.1", 197 "k2.2": "v2.2", 198 }, 199 }, 200 // resulting obj 201 value: map[string]interface{}{ 202 "k1": "v1", 203 "k2": map[string]string{ 204 "k2.1": "v2.1", 205 "k2.2": "v2.2", 206 }, 207 }, 208 // there will be no changes to obj since there are no fields 209 fields: []string{}, 210 }, 211 "Negative test - no changes to original obj due to nil object": { 212 obj: nil, 213 // resulting obj 214 value: nil, 215 // there will be no changes to obj even with provided fields 216 fields: []string{"k1", "k2"}, 217 }, 218 } 219 220 for name, mock := range tests { 221 t.Run(name, func(t *testing.T) { 222 SetNestedField(mock.obj, mock.value, mock.fields...) 223 224 if !reflect.DeepEqual(GetNestedField(mock.obj, mock.fields...), mock.value) { 225 t.Fatalf("failed to test set nested field: expected '%#v': actual '%#v'", mock.value, GetNestedField(mock.obj, mock.fields...)) 226 } 227 }) 228 } 229 }