123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- /*
- Copyright 2015 The Kubernetes Authors.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package json
- import (
- "fmt"
- "math"
- "reflect"
- "strconv"
- "strings"
- "testing"
- )
- func TestEvaluateTypes(t *testing.T) {
- testCases := []struct {
- In string
- Data interface{}
- Out string
- Err bool
- }{
- // Invalid syntaxes
- {
- In: `x`,
- Err: true,
- },
- {
- In: ``,
- Err: true,
- },
- // Null
- {
- In: `null`,
- Data: nil,
- Out: `null`,
- },
- // Booleans
- {
- In: `true`,
- Data: true,
- Out: `true`,
- },
- {
- In: `false`,
- Data: false,
- Out: `false`,
- },
- // Integers
- {
- In: `0`,
- Data: int64(0),
- Out: `0`,
- },
- {
- In: `-0`,
- Data: int64(-0),
- Out: `0`,
- },
- {
- In: `1`,
- Data: int64(1),
- Out: `1`,
- },
- {
- In: `2147483647`,
- Data: int64(math.MaxInt32),
- Out: `2147483647`,
- },
- {
- In: `-2147483648`,
- Data: int64(math.MinInt32),
- Out: `-2147483648`,
- },
- {
- In: `9223372036854775807`,
- Data: int64(math.MaxInt64),
- Out: `9223372036854775807`,
- },
- {
- In: `-9223372036854775808`,
- Data: int64(math.MinInt64),
- Out: `-9223372036854775808`,
- },
- // Int overflow
- {
- In: `9223372036854775808`, // MaxInt64 + 1
- Data: float64(9223372036854775808),
- Out: strconv.FormatFloat(9223372036854775808, 'g', -1, 64),
- },
- {
- In: `-9223372036854775809`, // MinInt64 - 1
- Data: float64(math.MinInt64),
- Out: strconv.FormatFloat(-9223372036854775809, 'g', -1, 64),
- },
- // Floats
- {
- In: `0.0`,
- Data: float64(0),
- Out: `0`,
- },
- {
- In: `-0.0`,
- Data: float64(-0.0),
- Out: `-0`,
- },
- {
- In: `0.5`,
- Data: float64(0.5),
- Out: `0.5`,
- },
- {
- In: `1e3`,
- Data: float64(1e3),
- Out: `1000`,
- },
- {
- In: `1.5`,
- Data: float64(1.5),
- Out: `1.5`,
- },
- {
- In: `-0.3`,
- Data: float64(-.3),
- Out: `-0.3`,
- },
- {
- // Largest representable float32
- In: `3.40282346638528859811704183484516925440e+38`,
- Data: float64(math.MaxFloat32),
- Out: strconv.FormatFloat(math.MaxFloat32, 'g', -1, 64),
- },
- {
- // Smallest float32 without losing precision
- In: `1.175494351e-38`,
- Data: float64(1.175494351e-38),
- Out: `1.175494351e-38`,
- },
- {
- // float32 closest to zero
- In: `1.401298464324817070923729583289916131280e-45`,
- Data: float64(math.SmallestNonzeroFloat32),
- Out: strconv.FormatFloat(math.SmallestNonzeroFloat32, 'g', -1, 64),
- },
- {
- // Largest representable float64
- In: `1.797693134862315708145274237317043567981e+308`,
- Data: float64(math.MaxFloat64),
- Out: strconv.FormatFloat(math.MaxFloat64, 'g', -1, 64),
- },
- {
- // Closest to zero without losing precision
- In: `2.2250738585072014e-308`,
- Data: float64(2.2250738585072014e-308),
- Out: `2.2250738585072014e-308`,
- },
- {
- // float64 closest to zero
- In: `4.940656458412465441765687928682213723651e-324`,
- Data: float64(math.SmallestNonzeroFloat64),
- Out: strconv.FormatFloat(math.SmallestNonzeroFloat64, 'g', -1, 64),
- },
- {
- // math.MaxFloat64 + 2 overflow
- In: `1.7976931348623159e+308`,
- Err: true,
- },
- // Strings
- {
- In: `""`,
- Data: string(""),
- Out: `""`,
- },
- {
- In: `"0"`,
- Data: string("0"),
- Out: `"0"`,
- },
- {
- In: `"A"`,
- Data: string("A"),
- Out: `"A"`,
- },
- {
- In: `"Iñtërnâtiônàlizætiøn"`,
- Data: string("Iñtërnâtiônàlizætiøn"),
- Out: `"Iñtërnâtiônàlizætiøn"`,
- },
- // Arrays
- {
- In: `[]`,
- Data: []interface{}{},
- Out: `[]`,
- },
- {
- In: `[` + strings.Join([]string{
- `null`,
- `true`,
- `false`,
- `0`,
- `9223372036854775807`,
- `0.0`,
- `0.5`,
- `1.0`,
- `1.797693134862315708145274237317043567981e+308`,
- `"0"`,
- `"A"`,
- `"Iñtërnâtiônàlizætiøn"`,
- `[null,true,1,1.0,1.5]`,
- `{"boolkey":true,"floatkey":1.0,"intkey":1,"nullkey":null}`,
- }, ",") + `]`,
- Data: []interface{}{
- nil,
- true,
- false,
- int64(0),
- int64(math.MaxInt64),
- float64(0.0),
- float64(0.5),
- float64(1.0),
- float64(math.MaxFloat64),
- string("0"),
- string("A"),
- string("Iñtërnâtiônàlizætiøn"),
- []interface{}{nil, true, int64(1), float64(1.0), float64(1.5)},
- map[string]interface{}{"nullkey": nil, "boolkey": true, "intkey": int64(1), "floatkey": float64(1.0)},
- },
- Out: `[` + strings.Join([]string{
- `null`,
- `true`,
- `false`,
- `0`,
- `9223372036854775807`,
- `0`,
- `0.5`,
- `1`,
- strconv.FormatFloat(math.MaxFloat64, 'g', -1, 64),
- `"0"`,
- `"A"`,
- `"Iñtërnâtiônàlizætiøn"`,
- `[null,true,1,1,1.5]`,
- `{"boolkey":true,"floatkey":1,"intkey":1,"nullkey":null}`, // gets alphabetized by Marshal
- }, ",") + `]`,
- },
- // Maps
- {
- In: `{}`,
- Data: map[string]interface{}{},
- Out: `{}`,
- },
- {
- In: `{"boolkey":true,"floatkey":1.0,"intkey":1,"nullkey":null}`,
- Data: map[string]interface{}{"nullkey": nil, "boolkey": true, "intkey": int64(1), "floatkey": float64(1.0)},
- Out: `{"boolkey":true,"floatkey":1,"intkey":1,"nullkey":null}`, // gets alphabetized by Marshal
- },
- }
- for _, tc := range testCases {
- inputJSON := fmt.Sprintf(`{"data":%s}`, tc.In)
- expectedJSON := fmt.Sprintf(`{"data":%s}`, tc.Out)
- m := map[string]interface{}{}
- err := Unmarshal([]byte(inputJSON), &m)
- if tc.Err && err != nil {
- // Expected error
- continue
- }
- if err != nil {
- t.Errorf("%s: error decoding: %v", tc.In, err)
- continue
- }
- if tc.Err {
- t.Errorf("%s: expected error, got none", tc.In)
- continue
- }
- data, ok := m["data"]
- if !ok {
- t.Errorf("%s: decoded object missing data key: %#v", tc.In, m)
- continue
- }
- if !reflect.DeepEqual(tc.Data, data) {
- t.Errorf("%s: expected\n\t%#v (%v), got\n\t%#v (%v)", tc.In, tc.Data, reflect.TypeOf(tc.Data), data, reflect.TypeOf(data))
- continue
- }
- outputJSON, err := Marshal(m)
- if err != nil {
- t.Errorf("%s: error encoding: %v", tc.In, err)
- continue
- }
- if expectedJSON != string(outputJSON) {
- t.Errorf("%s: expected\n\t%s, got\n\t%s", tc.In, expectedJSON, string(outputJSON))
- continue
- }
- }
- }
|