k8s.io/kube-openapi@v0.0.0-20240228011516-70dd3763d340/pkg/internal/third_party/go-json-experiment/json/token_test.go (about) 1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package json 6 7 import ( 8 "math" 9 "reflect" 10 "testing" 11 ) 12 13 func TestTokenStringAllocations(t *testing.T) { 14 if testing.CoverMode() != "" { 15 t.Skip("coverage mode breaks the compiler optimization this depends on") 16 } 17 18 tok := rawToken(`"hello"`) 19 var m map[string]bool 20 got := int(testing.AllocsPerRun(10, func() { 21 // This function uses tok.String() is a non-escaping manner 22 // (i.e., looking it up in a Go map). It should not allocate. 23 if m[tok.String()] { 24 panic("never executed") 25 } 26 })) 27 if got > 0 { 28 t.Errorf("Token.String allocated %d times, want 0", got) 29 } 30 } 31 32 func TestTokenAccessors(t *testing.T) { 33 type token struct { 34 Bool bool 35 String string 36 Float float64 37 Int int64 38 Uint uint64 39 Kind Kind 40 } 41 42 tests := []struct { 43 in Token 44 want token 45 }{ 46 {Token{}, token{String: "<invalid json.Token>"}}, 47 {Null, token{String: "null", Kind: 'n'}}, 48 {False, token{Bool: false, String: "false", Kind: 'f'}}, 49 {True, token{Bool: true, String: "true", Kind: 't'}}, 50 {Bool(false), token{Bool: false, String: "false", Kind: 'f'}}, 51 {Bool(true), token{Bool: true, String: "true", Kind: 't'}}, 52 {ObjectStart, token{String: "{", Kind: '{'}}, 53 {ObjectEnd, token{String: "}", Kind: '}'}}, 54 {ArrayStart, token{String: "[", Kind: '['}}, 55 {ArrayEnd, token{String: "]", Kind: ']'}}, 56 {String(""), token{String: "", Kind: '"'}}, 57 {String("hello, world!"), token{String: "hello, world!", Kind: '"'}}, 58 {rawToken(`"hello, world!"`), token{String: "hello, world!", Kind: '"'}}, 59 {Float(0), token{String: "0", Float: 0, Int: 0, Uint: 0, Kind: '0'}}, 60 {Float(math.Copysign(0, -1)), token{String: "-0", Float: math.Copysign(0, -1), Int: 0, Uint: 0, Kind: '0'}}, 61 {Float(math.NaN()), token{String: "NaN", Float: math.NaN(), Int: 0, Uint: 0, Kind: '"'}}, 62 {Float(math.Inf(+1)), token{String: "Infinity", Float: math.Inf(+1), Kind: '"'}}, 63 {Float(math.Inf(-1)), token{String: "-Infinity", Float: math.Inf(-1), Kind: '"'}}, 64 {Int(minInt64), token{String: "-9223372036854775808", Float: minInt64, Int: minInt64, Uint: minUint64, Kind: '0'}}, 65 {Int(minInt64 + 1), token{String: "-9223372036854775807", Float: minInt64 + 1, Int: minInt64 + 1, Uint: minUint64, Kind: '0'}}, 66 {Int(-1), token{String: "-1", Float: -1, Int: -1, Uint: minUint64, Kind: '0'}}, 67 {Int(0), token{String: "0", Float: 0, Int: 0, Uint: 0, Kind: '0'}}, 68 {Int(+1), token{String: "1", Float: +1, Int: +1, Uint: +1, Kind: '0'}}, 69 {Int(maxInt64 - 1), token{String: "9223372036854775806", Float: maxInt64 - 1, Int: maxInt64 - 1, Uint: maxInt64 - 1, Kind: '0'}}, 70 {Int(maxInt64), token{String: "9223372036854775807", Float: maxInt64, Int: maxInt64, Uint: maxInt64, Kind: '0'}}, 71 {Uint(minUint64), token{String: "0", Kind: '0'}}, 72 {Uint(minUint64 + 1), token{String: "1", Float: minUint64 + 1, Int: minUint64 + 1, Uint: minUint64 + 1, Kind: '0'}}, 73 {Uint(maxUint64 - 1), token{String: "18446744073709551614", Float: maxUint64 - 1, Int: maxInt64, Uint: maxUint64 - 1, Kind: '0'}}, 74 {Uint(maxUint64), token{String: "18446744073709551615", Float: maxUint64, Int: maxInt64, Uint: maxUint64, Kind: '0'}}, 75 {rawToken(`-0`), token{String: "-0", Float: math.Copysign(0, -1), Int: 0, Uint: 0, Kind: '0'}}, 76 {rawToken(`1e1000`), token{String: "1e1000", Float: math.MaxFloat64, Int: maxInt64, Uint: maxUint64, Kind: '0'}}, 77 {rawToken(`-1e1000`), token{String: "-1e1000", Float: -math.MaxFloat64, Int: minInt64, Uint: minUint64, Kind: '0'}}, 78 {rawToken(`0.1`), token{String: "0.1", Float: 0.1, Int: 0, Uint: 0, Kind: '0'}}, 79 {rawToken(`0.5`), token{String: "0.5", Float: 0.5, Int: 0, Uint: 0, Kind: '0'}}, 80 {rawToken(`0.9`), token{String: "0.9", Float: 0.9, Int: 0, Uint: 0, Kind: '0'}}, 81 {rawToken(`1.1`), token{String: "1.1", Float: 1.1, Int: 1, Uint: 1, Kind: '0'}}, 82 {rawToken(`-0.1`), token{String: "-0.1", Float: -0.1, Int: 0, Uint: 0, Kind: '0'}}, 83 {rawToken(`-0.5`), token{String: "-0.5", Float: -0.5, Int: 0, Uint: 0, Kind: '0'}}, 84 {rawToken(`-0.9`), token{String: "-0.9", Float: -0.9, Int: 0, Uint: 0, Kind: '0'}}, 85 {rawToken(`-1.1`), token{String: "-1.1", Float: -1.1, Int: -1, Uint: 0, Kind: '0'}}, 86 {rawToken(`99999999999999999999`), token{String: "99999999999999999999", Float: 1e20 - 1, Int: maxInt64, Uint: maxUint64, Kind: '0'}}, 87 {rawToken(`-99999999999999999999`), token{String: "-99999999999999999999", Float: -1e20 - 1, Int: minInt64, Uint: minUint64, Kind: '0'}}, 88 } 89 90 for _, tt := range tests { 91 t.Run("", func(t *testing.T) { 92 got := token{ 93 Bool: func() bool { 94 defer func() { recover() }() 95 return tt.in.Bool() 96 }(), 97 String: tt.in.String(), 98 Float: func() float64 { 99 defer func() { recover() }() 100 return tt.in.Float() 101 }(), 102 Int: func() int64 { 103 defer func() { recover() }() 104 return tt.in.Int() 105 }(), 106 Uint: func() uint64 { 107 defer func() { recover() }() 108 return tt.in.Uint() 109 }(), 110 Kind: tt.in.Kind(), 111 } 112 113 if got.Bool != tt.want.Bool { 114 t.Errorf("Token(%s).Bool() = %v, want %v", tt.in, got.Bool, tt.want.Bool) 115 } 116 if got.String != tt.want.String { 117 t.Errorf("Token(%s).String() = %v, want %v", tt.in, got.String, tt.want.String) 118 } 119 if math.Float64bits(got.Float) != math.Float64bits(tt.want.Float) { 120 t.Errorf("Token(%s).Float() = %v, want %v", tt.in, got.Float, tt.want.Float) 121 } 122 if got.Int != tt.want.Int { 123 t.Errorf("Token(%s).Int() = %v, want %v", tt.in, got.Int, tt.want.Int) 124 } 125 if got.Uint != tt.want.Uint { 126 t.Errorf("Token(%s).Uint() = %v, want %v", tt.in, got.Uint, tt.want.Uint) 127 } 128 if got.Kind != tt.want.Kind { 129 t.Errorf("Token(%s).Kind() = %v, want %v", tt.in, got.Kind, tt.want.Kind) 130 } 131 }) 132 } 133 } 134 135 func TestTokenClone(t *testing.T) { 136 tests := []struct { 137 in Token 138 wantExactRaw bool 139 }{ 140 {Token{}, true}, 141 {Null, true}, 142 {False, true}, 143 {True, true}, 144 {ObjectStart, true}, 145 {ObjectEnd, true}, 146 {ArrayStart, true}, 147 {ArrayEnd, true}, 148 {String("hello, world!"), true}, 149 {rawToken(`"hello, world!"`), false}, 150 {Float(3.14159), true}, 151 {rawToken(`3.14159`), false}, 152 } 153 154 for _, tt := range tests { 155 t.Run("", func(t *testing.T) { 156 got := tt.in.Clone() 157 if !reflect.DeepEqual(got, tt.in) { 158 t.Errorf("Token(%s) == Token(%s).Clone() = false, want true", tt.in, tt.in) 159 } 160 gotExactRaw := got.raw == tt.in.raw 161 if gotExactRaw != tt.wantExactRaw { 162 t.Errorf("Token(%s).raw == Token(%s).Clone().raw = %v, want %v", tt.in, tt.in, gotExactRaw, tt.wantExactRaw) 163 } 164 }) 165 } 166 }