Skip to content

Commit b8e57a1

Browse files
authored
Merge pull request kubernetes#127822 from benluddy/json-serializer-roundtrip-float64-no-fraction
Test concrete type changes in unstructured float64 JSON roundtrips.
2 parents c95dd85 + 707ee63 commit b8e57a1

File tree

1 file changed

+47
-0
lines changed
  • staging/src/k8s.io/apimachinery/pkg/runtime/serializer/json

1 file changed

+47
-0
lines changed

staging/src/k8s.io/apimachinery/pkg/runtime/serializer/json/json_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,3 +1042,50 @@ func TestEncode(t *testing.T) {
10421042
})
10431043
}
10441044
}
1045+
1046+
// TestRoundtripUnstructuredFloat64 demonstrates that encoding a fractionless float64 value to JSON
1047+
// then decoding into interface{} can produce a value with concrete type int64. This is a
1048+
// consequence of two specific behaviors. First, there is nothing in the JSON encoding of a
1049+
// fractionless float64 value to distinguish it from the JSON encoding of an integer value. Second,
1050+
// if, when unmarshaling into interface{}, the decoder encounters a JSON number with no decimal
1051+
// point in the input, it produces a value with concrete type int64 as long as the number can be
1052+
// precisely represented by an int64.
1053+
func TestRoundtripUnstructuredFractionlessFloat64(t *testing.T) {
1054+
s := json.NewSerializerWithOptions(json.DefaultMetaFactory, runtime.NewScheme(), runtime.NewScheme(), json.SerializerOptions{})
1055+
1056+
initial := &unstructured.Unstructured{Object: map[string]interface{}{
1057+
"apiVersion": "v1",
1058+
"kind": "Test",
1059+
"with-fraction": float64(1.5),
1060+
"without-fraction": float64(1),
1061+
"without-fraction-big-positive": float64(9223372036854776000),
1062+
"without-fraction-big-negative": float64(-9223372036854776000),
1063+
}}
1064+
1065+
var buf bytes.Buffer
1066+
if err := s.Encode(initial, &buf); err != nil {
1067+
t.Fatal(err)
1068+
}
1069+
1070+
final := &unstructured.Unstructured{}
1071+
got, _, err := s.Decode(buf.Bytes(), nil, final)
1072+
if err != nil {
1073+
t.Fatal(err)
1074+
}
1075+
if got != final {
1076+
t.Fatalf("expected Decode to return target Unstructured object but got: %v", got)
1077+
}
1078+
1079+
expected := &unstructured.Unstructured{Object: map[string]interface{}{
1080+
"apiVersion": "v1",
1081+
"kind": "Test",
1082+
"with-fraction": float64(1.5),
1083+
"without-fraction": int64(1), // note the change in concrete type
1084+
"without-fraction-big-positive": float64(9223372036854776000),
1085+
"without-fraction-big-negative": float64(-9223372036854776000),
1086+
}}
1087+
1088+
if diff := cmp.Diff(expected, final); diff != "" {
1089+
t.Fatalf("unexpected diff:\n%s", diff)
1090+
}
1091+
}

0 commit comments

Comments
 (0)