Support typed nils; test empty Unstructured is not mutated

This commit is contained in:
Mikhail Mazurskiy
2018-04-04 22:27:21 +10:00
parent d5fdac399c
commit 53e8fd04ec
3 changed files with 17 additions and 4 deletions

View File

@@ -2133,14 +2133,14 @@ URL: http://localhost
"name": "MyName", "name": "MyName",
"namespace": "MyNamespace", "namespace": "MyNamespace",
"creationTimestamp": "2017-04-01T00:00:00Z", "creationTimestamp": "2017-04-01T00:00:00Z",
"resourceVersion": int64(123), "resourceVersion": 123,
"uid": "00000000-0000-0000-0000-000000000001", "uid": "00000000-0000-0000-0000-000000000001",
"dummy3": "present", "dummy3": "present",
}, },
"items": []interface{}{ "items": []interface{}{
map[string]interface{}{ map[string]interface{}{
"itemBool": true, "itemBool": true,
"itemInt": int64(42), "itemInt": 42,
}, },
}, },
"url": "http://localhost", "url": "http://localhost",

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2017 The Kubernetes Authors. Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -24,7 +24,9 @@ import (
func TestNilUnstructuredContent(t *testing.T) { func TestNilUnstructuredContent(t *testing.T) {
var u Unstructured var u Unstructured
uCopy := u.DeepCopy()
content := u.UnstructuredContent() content := u.UnstructuredContent()
expContent := make(map[string]interface{}) expContent := make(map[string]interface{})
assert.EqualValues(t, expContent, content) assert.EqualValues(t, expContent, content)
assert.Equal(t, uCopy, &u)
} }

View File

@@ -446,20 +446,31 @@ func DeepCopyJSON(x map[string]interface{}) map[string]interface{} {
// DeepCopyJSONValue deep copies the passed value, assuming it is a valid JSON representation i.e. only contains // DeepCopyJSONValue deep copies the passed value, assuming it is a valid JSON representation i.e. only contains
// types produced by json.Unmarshal(). // types produced by json.Unmarshal().
func DeepCopyJSONValue(x interface{}) interface{} { func DeepCopyJSONValue(x interface{}) interface{} {
if x == nil {
return nil
}
switch x := x.(type) { switch x := x.(type) {
case map[string]interface{}: case map[string]interface{}:
if x == nil {
// Typed nil - an interface{} that contains a type map[string]interface{} with a value of nil
return x
}
clone := make(map[string]interface{}, len(x)) clone := make(map[string]interface{}, len(x))
for k, v := range x { for k, v := range x {
clone[k] = DeepCopyJSONValue(v) clone[k] = DeepCopyJSONValue(v)
} }
return clone return clone
case []interface{}: case []interface{}:
if x == nil {
// Typed nil - an interface{} that contains a type []interface{} with a value of nil
return x
}
clone := make([]interface{}, len(x)) clone := make([]interface{}, len(x))
for i, v := range x { for i, v := range x {
clone[i] = DeepCopyJSONValue(v) clone[i] = DeepCopyJSONValue(v)
} }
return clone return clone
case string, int64, bool, float64, nil, encodingjson.Number: case string, int64, bool, float64, encodingjson.Number:
return x return x
default: default:
panic(fmt.Errorf("cannot deep copy %T", x)) panic(fmt.Errorf("cannot deep copy %T", x))